Skip to content

Commit 3f140e0

Browse files
committed
Adding TotpInfo to userRecord
1 parent 61c6c04 commit 3f140e0

File tree

5 files changed

+158
-69
lines changed

5 files changed

+158
-69
lines changed

auth/user_mgt.go

Lines changed: 51 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ const (
4242
createUserMethod = "createUser"
4343
updateUserMethod = "updateUser"
4444
phoneMultiFactorID = "phone"
45+
totpMultiFactorID = "totp"
4546
)
4647

4748
// 'REDACTED', encoded as a base64 string.
@@ -62,20 +63,29 @@ type UserInfo struct {
6263

6364
// multiFactorInfoResponse describes the `mfaInfo` of the user record API response
6465
type multiFactorInfoResponse struct {
65-
MFAEnrollmentID string `json:"mfaEnrollmentId,omitempty"`
66-
DisplayName string `json:"displayName,omitempty"`
67-
PhoneInfo string `json:"phoneInfo,omitempty"`
68-
EnrolledAt string `json:"enrolledAt,omitempty"`
66+
MFAEnrollmentID string `json:"mfaEnrollmentId,omitempty"`
67+
DisplayName string `json:"displayName,omitempty"`
68+
PhoneInfo string `json:"phoneInfo,omitempty"`
69+
TOTPInfo *TOTPInfo `json:"totpInfo,omitempty"`
70+
EnrolledAt string `json:"enrolledAt,omitempty"`
71+
}
72+
73+
// TOTPInfo describes a user enrolled second totp factor.
74+
type TOTPInfo struct{}
75+
76+
// PhoneMultiFactorInfo describes a user enrolled second phone factor.
77+
type PhoneMultiFactorInfo struct {
78+
PhoneNumber string
6979
}
7080

7181
// MultiFactorInfo describes a user enrolled second phone factor.
72-
// TODO : convert PhoneNumber to PhoneMultiFactorInfo struct
7382
type MultiFactorInfo struct {
74-
UID string
75-
DisplayName string
76-
EnrollmentTimestamp int64
77-
FactorID string
78-
PhoneNumber string
83+
UID string
84+
DisplayName string
85+
EnrollmentTimestamp int64
86+
FactorID string
87+
PhoneMultiFactorInfo *PhoneMultiFactorInfo
88+
TOTPMultiFactorInfo *TOTPInfo
7989
}
8090

8191
// MultiFactorSettings describes the multi-factor related user settings.
@@ -170,12 +180,18 @@ func convertMultiFactorInfoToServerFormat(mfaInfo MultiFactorInfo) (multiFactorI
170180
if mfaInfo.EnrollmentTimestamp != 0 {
171181
authFactorInfo.EnrolledAt = time.Unix(mfaInfo.EnrollmentTimestamp, 0).Format("2006-01-02T15:04:05Z07:00Z")
172182
}
173-
if mfaInfo.FactorID == phoneMultiFactorID {
174-
authFactorInfo.PhoneInfo = mfaInfo.PhoneNumber
175-
authFactorInfo.DisplayName = mfaInfo.DisplayName
176-
authFactorInfo.MFAEnrollmentID = mfaInfo.UID
183+
authFactorInfo.DisplayName = mfaInfo.DisplayName
184+
authFactorInfo.MFAEnrollmentID = mfaInfo.UID
185+
186+
switch mfaInfo.FactorID {
187+
case phoneMultiFactorID:
188+
authFactorInfo.PhoneInfo = mfaInfo.PhoneMultiFactorInfo.PhoneNumber
189+
return authFactorInfo, nil
190+
case totpMultiFactorID:
191+
authFactorInfo.TOTPInfo = (*TOTPInfo)(mfaInfo.TOTPMultiFactorInfo)
177192
return authFactorInfo, nil
178193
}
194+
179195
out, _ := json.Marshal(mfaInfo)
180196
return multiFactorInfoResponse{}, fmt.Errorf("Unsupported second factor %s provided", string(out))
181197
}
@@ -675,8 +691,8 @@ func validateAndFormatMfaSettings(mfaSettings MultiFactorSettings, methodType st
675691
return nil, fmt.Errorf("the second factor \"displayName\" for \"%s\" must be a valid non-empty string", multiFactorInfo.DisplayName)
676692
}
677693
if multiFactorInfo.FactorID == phoneMultiFactorID {
678-
if err := validatePhone(multiFactorInfo.PhoneNumber); err != nil {
679-
return nil, fmt.Errorf("the second factor \"phoneNumber\" for \"%s\" must be a non-empty E.164 standard compliant identifier string", multiFactorInfo.PhoneNumber)
694+
if err := validatePhone(multiFactorInfo.PhoneMultiFactorInfo.PhoneNumber); err != nil {
695+
return nil, fmt.Errorf("the second factor \"phoneNumber\" for \"%s\" must be a non-empty E.164 standard compliant identifier string", multiFactorInfo.PhoneMultiFactorInfo.PhoneNumber)
680696
}
681697
}
682698
obj, err := convertMultiFactorInfoToServerFormat(*multiFactorInfo)
@@ -1075,17 +1091,27 @@ func (r *userQueryResponse) makeExportedUserRecord() (*ExportedUserRecord, error
10751091
enrollmentTimestamp = t.Unix() * 1000
10761092
}
10771093

1078-
if factor.PhoneInfo == "" {
1094+
if factor.PhoneInfo != "" {
1095+
enrolledFactors = append(enrolledFactors, &MultiFactorInfo{
1096+
UID: factor.MFAEnrollmentID,
1097+
DisplayName: factor.DisplayName,
1098+
EnrollmentTimestamp: enrollmentTimestamp,
1099+
FactorID: phoneMultiFactorID,
1100+
PhoneMultiFactorInfo: &PhoneMultiFactorInfo{
1101+
PhoneNumber: factor.PhoneInfo,
1102+
},
1103+
})
1104+
} else if factor.TOTPInfo != nil {
1105+
enrolledFactors = append(enrolledFactors, &MultiFactorInfo{
1106+
UID: factor.MFAEnrollmentID,
1107+
DisplayName: factor.DisplayName,
1108+
EnrollmentTimestamp: enrollmentTimestamp,
1109+
FactorID: totpMultiFactorID,
1110+
TOTPMultiFactorInfo: &TOTPInfo{},
1111+
})
1112+
} else {
10791113
return nil, fmt.Errorf("unsupported multi-factor auth response: %#v", factor)
10801114
}
1081-
1082-
enrolledFactors = append(enrolledFactors, &MultiFactorInfo{
1083-
UID: factor.MFAEnrollmentID,
1084-
DisplayName: factor.DisplayName,
1085-
EnrollmentTimestamp: enrollmentTimestamp,
1086-
FactorID: phoneMultiFactorID,
1087-
PhoneNumber: factor.PhoneInfo,
1088-
})
10891115
}
10901116

10911117
return &ExportedUserRecord{

auth/user_mgt_test.go

Lines changed: 65 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,20 @@ var testUser = &UserRecord{
6969
MultiFactor: &MultiFactorSettings{
7070
EnrolledFactors: []*MultiFactorInfo{
7171
{
72-
UID: "0aaded3f-5e73-461d-aef9-37b48e3769be",
72+
UID: "enrolledFactor1",
7373
FactorID: "phone",
7474
EnrollmentTimestamp: 1614776780000,
75-
PhoneNumber: "+1234567890",
76-
DisplayName: "My MFA Phone",
75+
PhoneMultiFactorInfo: &PhoneMultiFactorInfo{
76+
PhoneNumber: "+1234567890",
77+
},
78+
DisplayName: "My MFA Phone",
79+
},
80+
{
81+
UID: "enrolledFactor2",
82+
FactorID: "totp",
83+
EnrollmentTimestamp: 1614776780000,
84+
TOTPMultiFactorInfo: &TOTPInfo{},
85+
DisplayName: "My MFA TOTP",
7786
},
7887
},
7988
},
@@ -646,8 +655,10 @@ func TestInvalidCreateUser(t *testing.T) {
646655
(&UserToCreate{}).MFASettings(MultiFactorSettings{
647656
EnrolledFactors: []*MultiFactorInfo{
648657
{
649-
UID: "EnrollmentID",
650-
PhoneNumber: "+11234567890",
658+
UID: "EnrollmentID",
659+
PhoneMultiFactorInfo: &PhoneMultiFactorInfo{
660+
PhoneNumber: "+11234567890",
661+
},
651662
DisplayName: "Spouse's phone number",
652663
FactorID: "phone",
653664
},
@@ -658,7 +669,9 @@ func TestInvalidCreateUser(t *testing.T) {
658669
(&UserToCreate{}).MFASettings(MultiFactorSettings{
659670
EnrolledFactors: []*MultiFactorInfo{
660671
{
661-
PhoneNumber: "invalid",
672+
PhoneMultiFactorInfo: &PhoneMultiFactorInfo{
673+
PhoneNumber: "invalid",
674+
},
662675
DisplayName: "Spouse's phone number",
663676
FactorID: "phone",
664677
},
@@ -669,7 +682,9 @@ func TestInvalidCreateUser(t *testing.T) {
669682
(&UserToCreate{}).MFASettings(MultiFactorSettings{
670683
EnrolledFactors: []*MultiFactorInfo{
671684
{
672-
PhoneNumber: "+11234567890",
685+
PhoneMultiFactorInfo: &PhoneMultiFactorInfo{
686+
PhoneNumber: "+11234567890",
687+
},
673688
DisplayName: "Spouse's phone number",
674689
FactorID: "phone",
675690
EnrollmentTimestamp: time.Now().UTC().Unix(),
@@ -681,7 +696,9 @@ func TestInvalidCreateUser(t *testing.T) {
681696
(&UserToCreate{}).MFASettings(MultiFactorSettings{
682697
EnrolledFactors: []*MultiFactorInfo{
683698
{
684-
PhoneNumber: "+11234567890",
699+
PhoneMultiFactorInfo: &PhoneMultiFactorInfo{
700+
PhoneNumber: "+11234567890",
701+
},
685702
DisplayName: "Spouse's phone number",
686703
FactorID: "",
687704
},
@@ -692,8 +709,10 @@ func TestInvalidCreateUser(t *testing.T) {
692709
(&UserToCreate{}).MFASettings(MultiFactorSettings{
693710
EnrolledFactors: []*MultiFactorInfo{
694711
{
695-
PhoneNumber: "+11234567890",
696-
FactorID: "phone",
712+
PhoneMultiFactorInfo: &PhoneMultiFactorInfo{
713+
PhoneNumber: "+11234567890",
714+
},
715+
FactorID: "phone",
697716
},
698717
},
699718
}),
@@ -773,7 +792,9 @@ var createUserCases = []struct {
773792
(&UserToCreate{}).MFASettings(MultiFactorSettings{
774793
EnrolledFactors: []*MultiFactorInfo{
775794
{
776-
PhoneNumber: "+11234567890",
795+
PhoneMultiFactorInfo: &PhoneMultiFactorInfo{
796+
PhoneNumber: "+11234567890",
797+
},
777798
DisplayName: "Spouse's phone number",
778799
FactorID: "phone",
779800
},
@@ -790,12 +811,16 @@ var createUserCases = []struct {
790811
(&UserToCreate{}).MFASettings(MultiFactorSettings{
791812
EnrolledFactors: []*MultiFactorInfo{
792813
{
793-
PhoneNumber: "+11234567890",
814+
PhoneMultiFactorInfo: &PhoneMultiFactorInfo{
815+
PhoneNumber: "+11234567890",
816+
},
794817
DisplayName: "number1",
795818
FactorID: "phone",
796819
},
797820
{
798-
PhoneNumber: "+11234567890",
821+
PhoneMultiFactorInfo: &PhoneMultiFactorInfo{
822+
PhoneNumber: "+11234567890",
823+
},
799824
DisplayName: "number2",
800825
FactorID: "phone",
801826
},
@@ -875,9 +900,11 @@ func TestInvalidUpdateUser(t *testing.T) {
875900
(&UserToUpdate{}).MFASettings(MultiFactorSettings{
876901
EnrolledFactors: []*MultiFactorInfo{
877902
{
878-
UID: "enrolledSecondFactor1",
879-
PhoneNumber: "+11234567890",
880-
FactorID: "phone",
903+
UID: "enrolledSecondFactor1",
904+
PhoneMultiFactorInfo: &PhoneMultiFactorInfo{
905+
PhoneNumber: "+11234567890",
906+
},
907+
FactorID: "phone",
881908
},
882909
},
883910
}),
@@ -886,8 +913,10 @@ func TestInvalidUpdateUser(t *testing.T) {
886913
(&UserToUpdate{}).MFASettings(MultiFactorSettings{
887914
EnrolledFactors: []*MultiFactorInfo{
888915
{
889-
UID: "enrolledSecondFactor1",
890-
PhoneNumber: "invalid",
916+
UID: "enrolledSecondFactor1",
917+
PhoneMultiFactorInfo: &PhoneMultiFactorInfo{
918+
PhoneNumber: "invalid",
919+
},
891920
DisplayName: "Spouse's phone number",
892921
FactorID: "phone",
893922
},
@@ -898,7 +927,9 @@ func TestInvalidUpdateUser(t *testing.T) {
898927
(&UserToUpdate{}).MFASettings(MultiFactorSettings{
899928
EnrolledFactors: []*MultiFactorInfo{
900929
{
901-
PhoneNumber: "+11234567890",
930+
PhoneMultiFactorInfo: &PhoneMultiFactorInfo{
931+
PhoneNumber: "+11234567890",
932+
},
902933
FactorID: "phone",
903934
DisplayName: "Spouse's phone number",
904935
},
@@ -1049,14 +1080,18 @@ var updateUserCases = []struct {
10491080
(&UserToUpdate{}).MFASettings(MultiFactorSettings{
10501081
EnrolledFactors: []*MultiFactorInfo{
10511082
{
1052-
UID: "enrolledSecondFactor1",
1053-
PhoneNumber: "+11234567890",
1083+
UID: "enrolledSecondFactor1",
1084+
PhoneMultiFactorInfo: &PhoneMultiFactorInfo{
1085+
PhoneNumber: "+11234567890",
1086+
},
10541087
DisplayName: "Spouse's phone number",
10551088
FactorID: "phone",
10561089
EnrollmentTimestamp: time.Now().Unix(),
10571090
}, {
1058-
UID: "enrolledSecondFactor2",
1059-
PhoneNumber: "+11234567890",
1091+
UID: "enrolledSecondFactor2",
1092+
PhoneMultiFactorInfo: &PhoneMultiFactorInfo{
1093+
PhoneNumber: "+11234567890",
1094+
},
10601095
DisplayName: "Spouse's phone number",
10611096
FactorID: "phone",
10621097
},
@@ -1886,10 +1921,16 @@ func TestMakeExportedUser(t *testing.T) {
18861921
MFAInfo: []*multiFactorInfoResponse{
18871922
{
18881923
PhoneInfo: "+1234567890",
1889-
MFAEnrollmentID: "0aaded3f-5e73-461d-aef9-37b48e3769be",
1924+
MFAEnrollmentID: "enrolledFactor1",
18901925
DisplayName: "My MFA Phone",
18911926
EnrolledAt: "2021-03-03T13:06:20.542896Z",
18921927
},
1928+
{
1929+
TOTPInfo: &TOTPInfo{},
1930+
MFAEnrollmentID: "enrolledFactor2",
1931+
DisplayName: "My MFA TOTP",
1932+
EnrolledAt: "2021-03-03T13:06:20.542896Z",
1933+
},
18931934
},
18941935
}
18951936

integration/auth/user_mgt_test.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,9 @@ func TestCreateUserMFA(t *testing.T) {
434434
tc.MFASettings(auth.MultiFactorSettings{
435435
EnrolledFactors: []*auth.MultiFactorInfo{
436436
{
437-
PhoneNumber: "+11234567890",
437+
PhoneMultiFactorInfo: &auth.PhoneMultiFactorInfo{
438+
PhoneNumber: "+11234567890",
439+
},
438440
DisplayName: "Spouse's phone number",
439441
FactorID: "phone",
440442
},
@@ -447,10 +449,12 @@ func TestCreateUserMFA(t *testing.T) {
447449
defer deleteUser(user.UID)
448450
var factor []*auth.MultiFactorInfo = []*auth.MultiFactorInfo{
449451
{
450-
UID: user.MultiFactor.EnrolledFactors[0].UID,
451-
DisplayName: "Spouse's phone number",
452-
FactorID: "phone",
453-
PhoneNumber: "+11234567890",
452+
UID: user.MultiFactor.EnrolledFactors[0].UID,
453+
DisplayName: "Spouse's phone number",
454+
FactorID: "phone",
455+
PhoneMultiFactorInfo: &auth.PhoneMultiFactorInfo{
456+
PhoneNumber: "+11234567890",
457+
},
454458
EnrollmentTimestamp: user.MultiFactor.EnrolledFactors[0].EnrollmentTimestamp,
455459
},
456460
}

testdata/get_user.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,17 @@
3535
"mfaInfo": [
3636
{
3737
"phoneInfo": "+1234567890",
38-
"mfaEnrollmentId": "0aaded3f-5e73-461d-aef9-37b48e3769be",
38+
"mfaEnrollmentId": "enrolledFactor1",
3939
"displayName": "My MFA Phone",
4040
"enrolledAt": "2021-03-03T13:06:20.542896Z"
41+
},
42+
{
43+
"totpInfo": {},
44+
"mfaEnrollmentId": "enrolledFactor2",
45+
"displayName": "My MFA TOTP",
46+
"enrolledAt": "2021-03-03T13:06:20.542896Z"
4147
}
4248
]
4349
}
4450
]
45-
}
51+
}

0 commit comments

Comments
 (0)