Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 323909e

Browse files
committed
Add Firebase Auth MFA info to user record
1 parent 6145491 commit 323909e

File tree

6 files changed

+280
-1
lines changed

6 files changed

+280
-1
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 2022 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.firebase.auth;
18+
19+
import com.google.firebase.auth.internal.GetAccountInfoResponse;
20+
import com.google.firebase.internal.Nullable;
21+
22+
/**
23+
* Interface representing the common properties of a user-enrolled second factor.
24+
*/
25+
public abstract class MultiFactorInfo {
26+
27+
/**
28+
* The ID of the enrolled second factor. This ID is unique to the user.
29+
*/
30+
private final String uid;
31+
32+
/**
33+
* The optional display name of the enrolled second factor.
34+
*/
35+
private final String displayName;
36+
37+
/**
38+
* The type identifier of the second factor. For SMS second factors, this is `phone`.
39+
*/
40+
private final String factorId;
41+
42+
/**
43+
* The optional date the second factor was enrolled, formatted as a UTC string.
44+
*/
45+
private final String enrollmentTime;
46+
47+
MultiFactorInfo(GetAccountInfoResponse.MultiFactorInfo response) {
48+
this.uid = response.getMfaEnrollmentId();
49+
this.displayName = response.getDisplayName();
50+
this.factorId = response.getFactorId();
51+
this.enrollmentTime = response.getEnrollmentTime();
52+
}
53+
54+
public String getUid() {
55+
return uid;
56+
}
57+
58+
@Nullable
59+
public String getDisplayName() {
60+
return displayName;
61+
}
62+
63+
public String getFactorId() {
64+
return factorId;
65+
}
66+
67+
@Nullable
68+
public String getEnrollmentTime() {
69+
return enrollmentTime;
70+
}
71+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright 2022 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.firebase.auth;
18+
19+
/**
20+
* The multi-factor related user settings.
21+
*/
22+
public class MultiFactorSettings {
23+
24+
private final PhoneMultiFactorInfo[] enrolledFactors;
25+
26+
public MultiFactorSettings(PhoneMultiFactorInfo[] enrolledFactors) {
27+
this.enrolledFactors = enrolledFactors;
28+
}
29+
30+
public PhoneMultiFactorInfo[] getEnrolledFactors() {
31+
return enrolledFactors;
32+
}
33+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright 2022 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.firebase.auth;
18+
19+
import com.google.firebase.auth.internal.GetAccountInfoResponse;
20+
21+
/**
22+
* Interface representing the common properties of a user-enrolled second factor.
23+
*/
24+
public class PhoneMultiFactorInfo extends MultiFactorInfo {
25+
26+
/**
27+
* The phone number associated with a phone second factor.
28+
*/
29+
private final String phoneNumber;
30+
31+
private final String unobfuscatedPhoneNumber;
32+
33+
public PhoneMultiFactorInfo(GetAccountInfoResponse.MultiFactorInfo response) {
34+
super(response);
35+
36+
this.phoneNumber = response.getPhoneInfo();
37+
this.unobfuscatedPhoneNumber = response.getUnobfuscatedPhoneInfo();
38+
}
39+
40+
public String getPhoneNumber() {
41+
return phoneNumber;
42+
}
43+
44+
public String getUnobfuscatedPhoneNumber() {
45+
return unobfuscatedPhoneNumber;
46+
}
47+
}

‎src/main/java/com/google/firebase/auth/UserRecord.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ public class UserRecord implements UserInfo {
6161
private final long tokensValidAfterTimestamp;
6262
private final UserMetadata userMetadata;
6363
private final Map<String, Object> customClaims;
64+
private final MultiFactorSettings multiFactor;
6465

6566
UserRecord(User response, JsonFactory jsonFactory) {
6667
checkNotNull(response, "response must not be null");
@@ -82,6 +83,18 @@ public class UserRecord implements UserInfo {
8283
this.providers[i] = new ProviderUserInfo(response.getProviders()[i]);
8384
}
8485
}
86+
87+
if (response.getMfaInfo() == null || response.getMfaInfo().length == 0) {
88+
this.multiFactor = new MultiFactorSettings(new PhoneMultiFactorInfo[0]);
89+
} else {
90+
int mfaInfoLength = response.getMfaInfo().length;
91+
PhoneMultiFactorInfo[] multiFactorInfos = new PhoneMultiFactorInfo[mfaInfoLength];
92+
for (int i = 0; i < multiFactorInfos.length; i++) {
93+
multiFactorInfos[i] = new PhoneMultiFactorInfo(response.getMfaInfo()[i]);
94+
}
95+
this.multiFactor = new MultiFactorSettings(multiFactorInfos);
96+
}
97+
8598
this.tokensValidAfterTimestamp = response.getValidSince() * 1000;
8699

87100
String lastRefreshAtRfc3339 = response.getLastRefreshAt();
@@ -240,6 +253,13 @@ public Map<String,Object> getCustomClaims() {
240253
return customClaims;
241254
}
242255

256+
/**
257+
* The multi-factor related properties for the current user, if available.
258+
*/
259+
public MultiFactorSettings getMultiFactor() {
260+
return multiFactor;
261+
}
262+
243263
/**
244264
* Returns a new {@link UpdateRequest}, which can be used to update the attributes
245265
* of this user.

‎src/main/java/com/google/firebase/auth/internal/GetAccountInfoResponse.java

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.google.firebase.auth.internal;
1818

1919
import com.google.api.client.util.Key;
20+
2021
import java.util.List;
2122

2223
/**
@@ -85,6 +86,9 @@ public static class User {
8586
@Key("customAttributes")
8687
private String customClaims;
8788

89+
@Key("mfaInfo")
90+
private MultiFactorInfo[] mfaInfo;
91+
8892
public String getUid() {
8993
return uid;
9094
}
@@ -140,6 +144,10 @@ public long getValidSince() {
140144
public String getCustomClaims() {
141145
return customClaims;
142146
}
147+
148+
public MultiFactorInfo[] getMfaInfo() {
149+
return mfaInfo;
150+
}
143151
}
144152

145153
/**
@@ -189,4 +197,71 @@ public String getProviderId() {
189197
return providerId;
190198
}
191199
}
200+
201+
/**
202+
* JSON data binding for multi factor info data.
203+
*/
204+
public static final class MultiFactorInfo {
205+
/**
206+
* The ID of the enrolled second factor. This ID is unique to the user.
207+
*/
208+
@Key("mfaEnrollmentId")
209+
private String mfaEnrollmentId;
210+
211+
/**
212+
* The optional display name of the enrolled second factor.
213+
*/
214+
@Key("displayName")
215+
private String displayName;
216+
217+
/**
218+
* The type identifier of the second factor. For SMS second factors, this is `phone`.
219+
*/
220+
@Key("factorId")
221+
private String factorId;
222+
223+
/**
224+
* The optional date the second factor was enrolled, formatted as a UTC string.
225+
*/
226+
@Key("enrollmentTime")
227+
private String enrollmentTime;
228+
229+
/**
230+
* Normally this will show the phone number associated with this enrollment.
231+
* In some situations, such as after a first factor sign in,
232+
* it will only show the obfuscated version of the associated phone number.
233+
*/
234+
@Key("phoneInfo")
235+
private String phoneInfo;
236+
237+
/**
238+
* Unobfuscated phoneInfo.
239+
*/
240+
@Key("unobfuscatedPhoneInfo")
241+
private String unobfuscatedPhoneInfo;
242+
243+
public String getMfaEnrollmentId() {
244+
return mfaEnrollmentId;
245+
}
246+
247+
public String getDisplayName() {
248+
return displayName;
249+
}
250+
251+
public String getFactorId() {
252+
return factorId;
253+
}
254+
255+
public String getEnrollmentTime() {
256+
return enrollmentTime;
257+
}
258+
259+
public String getPhoneInfo() {
260+
return phoneInfo;
261+
}
262+
263+
public String getUnobfuscatedPhoneInfo() {
264+
return unobfuscatedPhoneInfo;
265+
}
266+
}
192267
}

‎src/test/java/com/google/firebase/auth/UserRecordTest.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import static org.junit.Assert.assertEquals;
44
import static org.junit.Assert.assertFalse;
5+
import static org.junit.Assert.assertNotNull;
56
import static org.junit.Assert.assertNull;
67
import static org.junit.Assert.fail;
78

@@ -17,6 +18,7 @@
1718
import java.io.IOException;
1819
import java.io.InputStream;
1920
import java.nio.charset.Charset;
21+
2022
import org.junit.Test;
2123

2224
public class UserRecordTest {
@@ -92,7 +94,7 @@ public void testAllProviderInfo() throws IOException {
9294
.put("photoUrl", "http://photo.url")
9395
.put("providerId", "providerId")
9496
.build()
95-
)
97+
)
9698
);
9799
String json = JSON_FACTORY.toString(resp);
98100
UserRecord userRecord = parseUser(json);
@@ -108,6 +110,37 @@ public void testAllProviderInfo() throws IOException {
108110
}
109111
}
110112

113+
@Test
114+
public void testPhoneMultiFactors() throws IOException {
115+
ImmutableMap<String, Object> resp = ImmutableMap.<String, Object>of(
116+
"localId", "user",
117+
"mfaInfo", ImmutableList.of(
118+
ImmutableMap.builder()
119+
.put("mfaEnrollmentId", "53HG4HG45HG8G04GJ40J4G3J")
120+
.put("displayName", "Display Name")
121+
.put("factorId", "phone")
122+
.put("enrollmentTime", "2017年9月22日 01:49:58 GMT")
123+
.put("phoneInfo", "+16505551234")
124+
.build()
125+
)
126+
);
127+
String json = JSON_FACTORY.toString(resp);
128+
UserRecord userRecord = parseUser(json);
129+
assertEquals("user", userRecord.getUid());
130+
131+
assertNotNull(userRecord.getMultiFactor());
132+
PhoneMultiFactorInfo[] enrolledFactors = userRecord.getMultiFactor().getEnrolledFactors();
133+
assertEquals(1, enrolledFactors.length);
134+
for (PhoneMultiFactorInfo multiFactorInfo : enrolledFactors) {
135+
assertEquals("53HG4HG45HG8G04GJ40J4G3J", multiFactorInfo.getUid());
136+
assertEquals("Display Name", multiFactorInfo.getDisplayName());
137+
assertEquals("phone", multiFactorInfo.getFactorId());
138+
assertEquals("2017年9月22日 01:49:58 GMT", multiFactorInfo.getEnrollmentTime());
139+
assertEquals("+16505551234", multiFactorInfo.getPhoneNumber());
140+
assertNull(multiFactorInfo.getUnobfuscatedPhoneNumber());
141+
}
142+
}
143+
111144
@Test
112145
public void testUserMetadata() throws IOException {
113146
ImmutableMap<String, Object> resp = ImmutableMap.<String, Object>of(

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /