Skip to content

Commit 0a98a74

Browse files
authored
[ID-687] Handle Create Admin account API issue (#688)
* Update CHANGELOG.md * Fix is in progress * Do not pass parameter which is not used * Check if the account exists for this app * Determine operation * App sign up is in progress * App sign up is in progress * Return account * Once we have tenants accounts this means that phone is also valid * In progress * API is done --------- Co-authored-by: Petyo Stoyanov <[email protected]>
1 parent 12c25cf commit 0a98a74

File tree

5 files changed

+123
-28
lines changed

5 files changed

+123
-28
lines changed

.secrets.baseline

+3-3
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@
136136
"filename": "core/auth/apis.go",
137137
"hashed_secret": "394e3412459f79523e12e1fa95a4cf141ccff122",
138138
"is_verified": false,
139-
"line_number": 2103
139+
"line_number": 2133
140140
}
141141
],
142142
"core/auth/auth.go": [
@@ -166,7 +166,7 @@
166166
"filename": "core/auth/auth.go",
167167
"hashed_secret": "94a7f0195bbbd2260c4e4d02b6348fbcd90b2b30",
168168
"is_verified": false,
169-
"line_number": 2539
169+
"line_number": 2593
170170
}
171171
],
172172
"core/auth/auth_type_email.go": [
@@ -364,5 +364,5 @@
364364
}
365365
]
366366
},
367-
"generated_at": "2023-11-29T10:56:59Z"
367+
"generated_at": "2023-12-08T06:55:08Z"
368368
}

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99
### Fixed
10+
- Handle Create Admin account API issue [#687](https://github.com/rokwire/core-building-block/issues/687)
1011
- Fix storeSystemData [#685](https://github.com/rokwire/core-building-block/issues/685)
1112

1213
## [1.35.0] - 2023-12-01

core/auth/apis.go

+54-24
Original file line numberDiff line numberDiff line change
@@ -578,42 +578,69 @@ func (a *Auth) CreateAdminAccount(authenticationType string, appID string, orgID
578578
}
579579

580580
// create account
581-
var accountAuthType *model.AccountAuthType
582581
var newAccount *model.Account
583582
var params map[string]interface{}
583+
584584
transaction := func(context storage.TransactionContext) error {
585-
//1. check if the user exists
586-
account, err := a.storage.FindAccount(context, appOrg.ID, authType.ID, identifier)
585+
//find the account for the org and the user identity
586+
foundedAccount, err := a.storage.FindAccountByOrgAndIdentifier(nil, appOrg.Organization.ID, authType.ID, identifier, appOrg.ID)
587587
if err != nil {
588588
return errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err)
589589
}
590-
if account != nil {
591-
return errors.ErrorData(logutils.StatusFound, model.TypeAccount, &logutils.FieldArgs{"app_org_id": appOrg.ID, "auth_type": authType.Code, "identifier": identifier})
590+
591+
//check if the account exists for this app
592+
if foundedAccount != nil && foundedAccount.HasApp(appID) {
593+
return errors.Newf("there is already account for %s in %s application", identifier, appID)
592594
}
593595

594-
//2. account does not exist, so apply sign up
595-
profile.DateCreated = time.Now().UTC()
596-
if authType.IsExternal {
597-
externalUser := model.ExternalSystemUser{Identifier: identifier}
598-
accountAuthType, err = a.applySignUpAdminExternal(context, *authType, *appOrg, externalUser, profile, privacy, username, permissions, roleIDs, groupIDs, scopes, creatorPermissions, clientVersion, l)
599-
if err != nil {
600-
return errors.WrapErrorAction(logutils.ActionRegister, "admin user", &logutils.FieldArgs{"auth_type": authType.Code, "identifier": identifier}, err)
601-
}
602-
} else {
603-
authImpl, err := a.getAuthTypeImpl(*authType)
596+
//determine operation - "org-sign-up" or "app-sign-up"
597+
operation, err := a.determineOperation(foundedAccount, appOrg.ID, l)
598+
if err != nil {
599+
return errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err)
600+
}
601+
602+
//apply operation
603+
switch operation {
604+
case "app-sign-up":
605+
// account exists in the organization but not for the application
606+
607+
udatedAccount, err := a.appSignUp(context, *foundedAccount, *appOrg, permissions, roleIDs, groupIDs, clientVersion, creatorPermissions, l)
604608
if err != nil {
605-
return errors.WrapErrorAction(logutils.ActionLoadCache, typeExternalAuthType, nil, err)
609+
return errors.WrapErrorAction("app sign up", "", nil, err)
606610
}
607611

608-
profile.Email = identifier
609-
params, accountAuthType, err = a.applySignUpAdmin(context, authImpl, account, *authType, *appOrg, identifier, "", profile, privacy, username, permissions, roleIDs, groupIDs, scopes, creatorPermissions, clientVersion, l)
610-
if err != nil {
611-
return errors.WrapErrorAction(logutils.ActionRegister, "admin user", &logutils.FieldArgs{"auth_type": authType.Code, "identifier": identifier}, err)
612+
newAccount = udatedAccount
613+
return nil
614+
case "org-sign-up":
615+
// account does not exist in the organization
616+
617+
var accountAuthType *model.AccountAuthType
618+
619+
profile.DateCreated = time.Now().UTC()
620+
if authType.IsExternal {
621+
externalUser := model.ExternalSystemUser{Identifier: identifier}
622+
accountAuthType, err = a.applySignUpAdminExternal(context, *authType, *appOrg, externalUser, profile, privacy, username, permissions, roleIDs, groupIDs, scopes, creatorPermissions, clientVersion, l)
623+
if err != nil {
624+
return errors.WrapErrorAction(logutils.ActionRegister, "admin user", &logutils.FieldArgs{"auth_type": authType.Code, "identifier": identifier}, err)
625+
}
626+
} else {
627+
authImpl, err := a.getAuthTypeImpl(*authType)
628+
if err != nil {
629+
return errors.WrapErrorAction(logutils.ActionLoadCache, typeExternalAuthType, nil, err)
630+
}
631+
632+
profile.Email = identifier
633+
params, accountAuthType, err = a.applySignUpAdmin(context, authImpl, *authType, *appOrg, identifier, "", profile, privacy, username, permissions, roleIDs, groupIDs, scopes, creatorPermissions, clientVersion, l)
634+
if err != nil {
635+
return errors.WrapErrorAction(logutils.ActionRegister, "admin user", &logutils.FieldArgs{"auth_type": authType.Code, "identifier": identifier}, err)
636+
}
612637
}
638+
639+
newAccount = &accountAuthType.Account
640+
return nil
613641
}
614642

615-
newAccount = &accountAuthType.Account
616-
return nil
643+
return errors.Newf("not supported operation - create account via admin API")
617644
}
618645

619646
err = a.storage.PerformTransaction(transaction)
@@ -630,7 +657,10 @@ func (a *Auth) UpdateAdminAccount(authenticationType string, appID string, orgID
630657
//TODO: when elevating existing accounts to application level admin, need to enforce any authentication policies set up for the app org
631658
// when demoting from application level admin to standard user, may want to inform user of applicable authentication policy changes
632659

633-
if authenticationType != AuthTypeOidc && authenticationType != AuthTypeEmail && !strings.HasSuffix(authenticationType, "_oidc") {
660+
if authenticationType != AuthTypeOidc &&
661+
authenticationType != AuthTypeEmail &&
662+
!strings.HasSuffix(authenticationType, "_oidc") &&
663+
authenticationType != AuthTypeTwilioPhone { //Once we have tenants accounts this means that phone is also valid
634664
return nil, nil, errors.ErrorData(logutils.StatusInvalid, "auth type", nil)
635665
}
636666

@@ -1779,7 +1809,7 @@ func (a *Auth) InitializeSystemAccount(context storage.TransactionContext, authT
17791809
privacy := model.Privacy{Public: false}
17801810
permissions := []string{allSystemPermission}
17811811

1782-
_, accountAuthType, err := a.applySignUpAdmin(context, authImpl, nil, authType, appOrg, email, password, profile, privacy, "", permissions, nil, nil, nil, permissions, &clientVersion, l)
1812+
_, accountAuthType, err := a.applySignUpAdmin(context, authImpl, authType, appOrg, email, password, profile, privacy, "", permissions, nil, nil, nil, permissions, &clientVersion, l)
17831813
if err != nil {
17841814
return "", errors.WrapErrorAction(logutils.ActionRegister, "initial system user", &logutils.FieldArgs{"email": email}, err)
17851815
}

core/auth/auth.go

+55-1
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,7 @@ func (a *Auth) applyOrgSignUp(authImpl authType, account *model.Account, authTyp
809809
return message, accountAuthType, nil
810810
}
811811

812-
func (a *Auth) applySignUpAdmin(context storage.TransactionContext, authImpl authType, account *model.Account, authType model.AuthType, appOrg model.ApplicationOrganization, identifier string, password string,
812+
func (a *Auth) applySignUpAdmin(context storage.TransactionContext, authImpl authType, authType model.AuthType, appOrg model.ApplicationOrganization, identifier string, password string,
813813
regProfile model.Profile, privacy model.Privacy, username string, permissions []string, roles []string, groups []string, scopes []string, creatorPermissions []string, clientVersion *string, l *logs.Log) (map[string]interface{}, *model.AccountAuthType, error) {
814814

815815
if username != "" {
@@ -1441,6 +1441,60 @@ func (a *Auth) getProfileBBData(authType model.AuthType, identifier string, l *l
14411441
return profile, preferences, nil
14421442
}
14431443

1444+
// sign up an account to a specific application in the organization
1445+
//
1446+
// Input:
1447+
// account (Account): The account
1448+
// appOrg (ApplicationOrganization): The application organization where this account will be attached
1449+
// permissionNames ([]string): set of permissions to assign
1450+
// roleIDs ([]string): set of roles to assign
1451+
// groupIDs ([]string): set of groups to assign
1452+
// clientVersion (*string): client version
1453+
// creatorPermissions ([]string): creator permissions
1454+
// Returns:
1455+
// Updated account (Account): The updated account object
1456+
func (a *Auth) appSignUp(context storage.TransactionContext, account model.Account, appOrg model.ApplicationOrganization,
1457+
permissionNames []string, roleIDs []string, groupIDs []string, clientVersion *string,
1458+
creatorPermissions []string,
1459+
l *logs.Log) (*model.Account, error) {
1460+
1461+
//check permissions, roles and groups
1462+
permissions, err := a.CheckPermissions(context, []model.ApplicationOrganization{appOrg}, permissionNames, creatorPermissions, false)
1463+
if err != nil {
1464+
return nil, errors.WrapErrorAction(logutils.ActionValidate, model.TypePermission, nil, err)
1465+
}
1466+
1467+
roles, err := a.CheckRoles(context, &appOrg, roleIDs, creatorPermissions, false)
1468+
if err != nil {
1469+
return nil, errors.WrapErrorAction(logutils.ActionValidate, model.TypeAppOrgRole, nil, err)
1470+
}
1471+
1472+
groups, err := a.CheckGroups(context, &appOrg, groupIDs, creatorPermissions, false)
1473+
if err != nil {
1474+
return nil, errors.WrapErrorAction(logutils.ActionGet, model.TypeAppOrgGroup, nil, err)
1475+
}
1476+
1477+
//create new app membership
1478+
rolesItems := model.AccountRolesFromAppOrgRoles(roles, true, true)
1479+
groupsItems := model.AccountGroupsFromAppOrgGroups(groups, true, true)
1480+
newAppMembership := model.OrgAppMembership{ID: uuid.NewString(), AppOrg: appOrg,
1481+
Permissions: permissions, Roles: rolesItems, Groups: groupsItems, MostRecentClientVersion: clientVersion}
1482+
1483+
//add it to the account
1484+
account.OrgAppsMemberships = append(account.OrgAppsMemberships, newAppMembership)
1485+
1486+
//save the account
1487+
err = a.storage.SaveAccount(context, &account)
1488+
if err != nil {
1489+
return nil, err
1490+
}
1491+
1492+
//set current membership
1493+
account.SetCurrentMembership(newAppMembership)
1494+
1495+
return &account, nil
1496+
}
1497+
14441498
// registerUser registers account for an organization in an application
14451499
//
14461500
// Input:

core/model/user.go

+10
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,16 @@ func (a Account) GetApps() []Application {
158158
return res
159159
}
160160

161+
// SetCurrentMembership sets current membership
162+
func (a *Account) SetCurrentMembership(current OrgAppMembership) {
163+
a.AppOrg = current.AppOrg
164+
a.Permissions = current.Permissions
165+
a.Roles = current.Roles
166+
a.Groups = current.Groups
167+
a.Preferences = current.Preferences
168+
a.MostRecentClientVersion = current.MostRecentClientVersion
169+
}
170+
161171
// GetAccountAuthTypeByID finds account auth type by id
162172
func (a Account) GetAccountAuthTypeByID(ID string) *AccountAuthType {
163173
for _, aat := range a.AuthTypes {

0 commit comments

Comments
 (0)