From 2301a1266014c1a7ee3ac82c65b02cacdeada29d Mon Sep 17 00:00:00 2001 From: Ryan Oberlander Date: Thu, 15 Dec 2022 17:08:26 -0600 Subject: [PATCH] define interfaces package, start using interfaces.Storage for transactions [#613] --- .pre-commit-config.yaml | 2 +- .secrets.baseline | 145 ++++++----- core/app_system.go | 6 +- core/auth/apis.go | 205 +++++++-------- core/auth/auth.go | 159 ++++++------ core/auth/auth_type_email.go | 2 +- core/auth/interfaces.go | 490 +---------------------------------- core/auth/mfa_email.go | 4 +- core/auth/mfa_phone.go | 4 +- core/auth/mfa_recovery.go | 4 +- core/auth/mfa_totp.go | 2 +- core/interfaces.go | 219 ---------------- core/interfaces/auth.go | 366 ++++++++++++++++++++++++++ core/interfaces/core.go | 138 ++++++++++ core/interfaces/driven.go | 247 ++++++++++++++++++ driven/storage/adapter.go | 367 +++++++++++++------------- driven/storage/database.go | 5 +- 17 files changed, 1201 insertions(+), 1164 deletions(-) create mode 100644 core/interfaces/auth.go create mode 100644 core/interfaces/core.go create mode 100644 core/interfaces/driven.go diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7940dcc3e..768de9f58 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/Yelp/detect-secrets - rev: v1.0.3 + rev: v1.4.0 hooks: - id: detect-secrets args: ['--baseline', '.secrets.baseline'] \ No newline at end of file diff --git a/.secrets.baseline b/.secrets.baseline index 54a8a8a3a..74410f540 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -1,5 +1,5 @@ { - "version": "1.0.3", + "version": "1.4.0", "plugins_used": [ { "name": "ArtifactoryDetector" @@ -20,6 +20,12 @@ { "name": "CloudantDetector" }, + { + "name": "DiscordBotTokenDetector" + }, + { + "name": "GitHubTokenDetector" + }, { "name": "HexHighEntropyString", "limit": 3.0 @@ -46,6 +52,9 @@ { "name": "PrivateKeyDetector" }, + { + "name": "SendGridDetector" + }, { "name": "SlackDetector" }, @@ -66,10 +75,6 @@ { "path": "detect_secrets.filters.allowlist.is_line_allowlisted" }, - { - "path": "detect_secrets.filters.common.is_baseline_file", - "filename": ".secrets.baseline" - }, { "path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies", "min_level": 2 @@ -80,6 +85,12 @@ { "path": "detect_secrets.filters.heuristic.is_likely_id_string" }, + { + "path": "detect_secrets.filters.heuristic.is_lock_file" + }, + { + "path": "detect_secrets.filters.heuristic.is_not_alphanumeric_string" + }, { "path": "detect_secrets.filters.heuristic.is_potential_uuid" }, @@ -90,13 +101,10 @@ "path": "detect_secrets.filters.heuristic.is_sequential_string" }, { - "path": "detect_secrets.filters.heuristic.is_templated_secret" + "path": "detect_secrets.filters.heuristic.is_swagger_file" }, { - "path": "detect_secrets.filters.regex.should_exclude_file", - "pattern": [ - "go.sum" - ] + "path": "detect_secrets.filters.heuristic.is_templated_secret" } ], "results": { @@ -109,31 +117,52 @@ "line_number": 38 } ], - "core/apis.go": [ + "core/app_services.go": [ { "type": "Secret Keyword", - "filename": "core/apis.go", - "hashed_secret": "f776bc8b6836b3498c27139f23f5d64e4041af0f", + "filename": "core/app_services.go", + "hashed_secret": "44e17306b837162269a410204daaa5ecee4ec22c", "is_verified": false, - "line_number": 164 + "line_number": 159 } ], "core/auth/apis.go": [ { "type": "Secret Keyword", "filename": "core/auth/apis.go", - "hashed_secret": "4d55af37dbbb6a42088d917caa1ca25428ec42c9", + "hashed_secret": "394e3412459f79523e12e1fa95a4cf141ccff122", "is_verified": false, - "line_number": 2051 + "line_number": 2038 } ], "core/auth/auth.go": [ { "type": "Secret Keyword", "filename": "core/auth/auth.go", - "hashed_secret": "4d55af37dbbb6a42088d917caa1ca25428ec42c9", + "hashed_secret": "417355fe2b66baa6826739a6d8006ab2ddcf5186", + "is_verified": false, + "line_number": 145 + }, + { + "type": "Secret Keyword", + "filename": "core/auth/auth.go", + "hashed_secret": "700f93e97a8aaf0664601a8f298ac5ad0ff13c37", + "is_verified": false, + "line_number": 147 + }, + { + "type": "Secret Keyword", + "filename": "core/auth/auth.go", + "hashed_secret": "58f3388441fbce0e48aef2bf74413a6f43f6dc70", "is_verified": false, - "line_number": 2384 + "line_number": 897 + }, + { + "type": "Secret Keyword", + "filename": "core/auth/auth.go", + "hashed_secret": "94a7f0195bbbd2260c4e4d02b6348fbcd90b2b30", + "is_verified": false, + "line_number": 2385 } ], "core/auth/auth_type_email.go": [ @@ -154,9 +183,9 @@ { "type": "Secret Keyword", "filename": "core/auth/auth_type_email.go", - "hashed_secret": "04e110541a2e8b44bc10939bfaf5d82adfe45158", + "hashed_secret": "06354d205ab5a3b6c7ad2333c58f1ddc810c97ba", "is_verified": false, - "line_number": 109 + "line_number": 87 }, { "type": "Secret Keyword", @@ -168,9 +197,9 @@ { "type": "Secret Keyword", "filename": "core/auth/auth_type_email.go", - "hashed_secret": "f32ddb18dd630c4bb16a5ab053c62d99c94df67f", + "hashed_secret": "69411040443be576ce64fc793269d7c26dd0866a", "is_verified": false, - "line_number": 258 + "line_number": 253 }, { "type": "Secret Keyword", @@ -196,11 +225,20 @@ "line_number": 377 } ], + "core/auth/service_static_token.go": [ + { + "type": "Secret Keyword", + "filename": "core/auth/service_static_token.go", + "hashed_secret": "44e17306b837162269a410204daaa5ecee4ec22c", + "is_verified": false, + "line_number": 78 + } + ], "driven/emailer/adapter.go": [ { "type": "Secret Keyword", "filename": "driven/emailer/adapter.go", - "hashed_secret": "1282d4ec63996a2c4dcb73835bad1c27ea1f901c", + "hashed_secret": "9df4524d2441f00999342c4541a39932198d4bb4", "is_verified": false, "line_number": 70 } @@ -214,70 +252,47 @@ "line_number": 224 } ], - "driver/web/docs/gen/def.yaml": [ + "driven/storage/database.go": [ { "type": "Secret Keyword", - "filename": "driver/web/docs/gen/def.yaml", - "hashed_secret": "dd29ecf524b030a65261e3059c48ab9e1ecb2585", + "filename": "driven/storage/database.go", + "hashed_secret": "6547f385c6d867e20f8217018a4d468a7d67d638", "is_verified": false, - "line_number": 1408 + "line_number": 203 } ], - "driver/web/docs/resources/services/application/configs.yaml": [ + "driver/web/apis_system.go": [ { "type": "Secret Keyword", - "filename": "driver/web/docs/resources/services/application/configs.yaml", - "hashed_secret": "dd29ecf524b030a65261e3059c48ab9e1ecb2585", + "filename": "driver/web/apis_system.go", + "hashed_secret": "44e17306b837162269a410204daaa5ecee4ec22c", "is_verified": false, - "line_number": 19 + "line_number": 692 } ], - "driver/web/ui/reset-credential.html": [ - { - "type": "Secret Keyword", - "filename": "driver/web/ui/reset-credential.html", - "hashed_secret": "ad88769c02358be4b1d42944359820977c4eec28", - "is_verified": false, - "line_number": 195 - }, - { - "type": "Secret Keyword", - "filename": "driver/web/ui/reset-credential.html", - "hashed_secret": "063afcf87eabb84dc0dc528d1b30266217aa71c3", - "is_verified": false, - "line_number": 196 - } - ], - "main.go": [ - { - "type": "Secret Keyword", - "filename": "main.go", - "hashed_secret": "7ee294e78b33e56f1f32f05e03847461cb0008df", - "is_verified": false, - "line_number": 94 - }, + "driver/web/docs/gen/gen_types.go": [ { "type": "Secret Keyword", - "filename": "main.go", - "hashed_secret": "d22d26f750c4f64214b43ec38aaf6e3456407f0a", + "filename": "driver/web/docs/gen/gen_types.go", + "hashed_secret": "c9739eab2dfa093cc0e450bf0ea81a43ae67b581", "is_verified": false, - "line_number": 146 + "line_number": 1564 }, { "type": "Secret Keyword", - "filename": "main.go", - "hashed_secret": "4f2da4710cdfd5c9f655ceb78bcb5ed03c73ddfd", + "filename": "driver/web/docs/gen/gen_types.go", + "hashed_secret": "9afb15df443d57204a2a0f82e164a9c46749dec6", "is_verified": false, - "line_number": 158 + "line_number": 1943 }, { "type": "Secret Keyword", - "filename": "main.go", - "hashed_secret": "24fe4e436894f6911a8234dbf81ad77417eac012", + "filename": "driver/web/docs/gen/gen_types.go", + "hashed_secret": "b296a47f167e06833104ebf060da1b4bbb4d619b", "is_verified": false, - "line_number": 160 + "line_number": 1946 } ] }, - "generated_at": "2022-11-10T19:40:13Z" + "generated_at": "2022-12-15T23:06:32Z" } diff --git a/core/app_system.go b/core/app_system.go index 38e78e8fb..b563ec039 100644 --- a/core/app_system.go +++ b/core/app_system.go @@ -59,15 +59,15 @@ func (app *application) sysUpdateGlobalConfig(setting string) error { } gc.Setting = setting - transaction := func(context storage.TransactionContext) error { + transaction := func(sa storage.Adapter) error { //1. clear the global config - we always keep only one global config - err := app.storage.DeleteGlobalConfig(context) + err := sa.DeleteGlobalConfig(context) if err != nil { return errors.WrapErrorAction(logutils.ActionDelete, model.TypeGlobalConfig, nil, err) } //2. add the new one - err = app.storage.CreateGlobalConfig(context, gc) + err = sa.CreateGlobalConfig(context, gc) if err != nil { return errors.WrapErrorAction(logutils.ActionInsert, model.TypeGlobalConfig, nil, err) } diff --git a/core/auth/apis.go b/core/auth/apis.go index 5f603e479..3b6a00ba7 100644 --- a/core/auth/apis.go +++ b/core/auth/apis.go @@ -179,12 +179,12 @@ func (a *Auth) Login(ipAddress string, deviceType string, deviceOS *string, devi // allSessions (bool): If to remove the current session only or all sessions for the app/org for the account func (a *Auth) Logout(appID string, orgID string, currentAccountID string, sessionID string, allSessions bool, l *logs.Log) error { if allSessions { - err := a.storage.DeleteLoginSessionsByIdentifier(nil, currentAccountID) + err := a.storage.DeleteLoginSessionsByIdentifier(currentAccountID) if err != nil { return errors.Wrapf("error deleting session by accountID - %s", err, currentAccountID) } } else { - err := a.storage.DeleteLoginSession(nil, sessionID) + err := a.storage.DeleteLoginSession(sessionID) if err != nil { return errors.Wrapf("error deleting session - %s", err, sessionID) } @@ -288,9 +288,9 @@ func (a *Auth) Refresh(refreshToken string, apiKey string, clientVersion *string l.Infof("the session is expired, so delete it and return null - %s", refreshToken) //remove the session - err = a.deleteLoginSession(nil, *loginSession, l) + err = a.deleteLoginSession(*a.storage.(*storage.Adapter), *loginSession, l) if err != nil { - return nil, errors.WrapErrorAction("error deleting expired session", "", nil, err) + return nil, errors.WrapErrorAction(logutils.ActionDelete, model.TypeLoginSession, nil, err) } //return nul @@ -307,9 +307,9 @@ func (a *Auth) Refresh(refreshToken string, apiKey string, clientVersion *string l.Infof("previous refresh token being used, so delete login session and return null - %s", refreshToken) //remove the session - err = a.deleteLoginSession(nil, *loginSession, l) + err = a.deleteLoginSession(*a.storage.(*storage.Adapter), *loginSession, l) if err != nil { - return nil, errors.WrapErrorAction("error deleting expired session", "", nil, err) + return nil, errors.WrapErrorAction(logutils.ActionDelete, model.TypeLoginSession, nil, err) } return nil, nil @@ -396,7 +396,7 @@ func (a *Auth) Refresh(refreshToken string, apiKey string, clientVersion *string loginSession.DateRefreshed = &now //store the updated session - err = a.storage.UpdateLoginSession(nil, *loginSession) + err = a.storage.UpdateLoginSession(*loginSession) if err != nil { l.Infof("error updating login session on refresh - %s", refreshToken) return nil, errors.WrapErrorAction("error updating login session on refresh", "", nil, err) @@ -405,7 +405,7 @@ func (a *Auth) Refresh(refreshToken string, apiKey string, clientVersion *string // update account usage information // TODO: Handle anonymous accounts if needed in the future if !anonymous { - err = a.storage.UpdateAccountUsageInfo(nil, loginSession.Identifier, false, true, clientVersion) + err = a.storage.UpdateAccountUsageInfo(loginSession.Identifier, false, true, clientVersion) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionUpdate, model.TypeAccountUsageInfo, nil, err) } @@ -477,15 +477,15 @@ func (a *Auth) LoginMFA(apiKey string, accountID string, sessionID string, ident var message string var loginSession *model.LoginSession var err error - transaction := func(context storage.TransactionContext) error { + transaction := func(sa storage.Adapter) error { //1. find mfa type in account - loginSession, err = a.storage.FindAndUpdateLoginSession(context, sessionID) + loginSession, err = sa.FindAndUpdateLoginSession(sessionID) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeLoginSession, &logutils.FieldArgs{"session_id": sessionID}, err) } if loginSession.MfaAttempts >= maxMfaAttempts { - a.deleteLoginSession(context, *loginSession, l) + a.deleteLoginSession(sa, *loginSession, l) message = fmt.Sprintf("max mfa attempts reached: %d", maxMfaAttempts) return errors.New(message) } @@ -498,7 +498,7 @@ func (a *Auth) LoginMFA(apiKey string, accountID string, sessionID string, ident //3. find mfa type in account errFields := &logutils.FieldArgs{"account_id": accountID, "type": mfaType} - mfa, err := a.storage.FindMFAType(context, accountID, identifier, mfaType) + mfa, err := sa.FindMFAType(accountID, identifier, mfaType) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeMFAType, errFields, err) } @@ -520,7 +520,7 @@ func (a *Auth) LoginMFA(apiKey string, accountID string, sessionID string, ident return errors.ErrorData(logutils.StatusInvalid, "login state", errFields) } if loginSession.StateExpires != nil && time.Now().UTC().After(*loginSession.StateExpires) { - a.deleteLoginSession(context, *loginSession, l) + a.deleteLoginSession(sa, *loginSession, l) message = "expired state" return errors.ErrorData(logutils.StatusInvalid, "expired state", nil) } @@ -530,7 +530,7 @@ func (a *Auth) LoginMFA(apiKey string, accountID string, sessionID string, ident if err != nil { return errors.WrapErrorAction(logutils.ActionLoadCache, typeMfaType, nil, err) } - verifyMsg, err := mfaImpl.verify(context, mfa, accountID, mfaCode) + verifyMsg, err := mfaImpl.verify(sa, mfa, accountID, mfaCode) if err != nil { if verifyMsg != nil { message = *verifyMsg @@ -541,7 +541,7 @@ func (a *Auth) LoginMFA(apiKey string, accountID string, sessionID string, ident loginSession.State = "" loginSession.StateExpires = nil loginSession.MfaAttempts = 0 - err = a.storage.UpdateLoginSession(context, *loginSession) + err = sa.UpdateLoginSession(*loginSession) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeLoginSession, nil, err) } @@ -578,9 +578,9 @@ func (a *Auth) CreateAdminAccount(authenticationType string, appID string, orgID var accountAuthType *model.AccountAuthType var newAccount *model.Account var params map[string]interface{} - transaction := func(context storage.TransactionContext) error { + transaction := func(sa storage.Adapter) error { //1. check if the user exists - account, err := a.storage.FindAccount(context, appOrg.ID, authType.ID, identifier) + account, err := sa.FindAccount(appOrg.ID, authType.ID, identifier) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) } @@ -592,7 +592,7 @@ func (a *Auth) CreateAdminAccount(authenticationType string, appID string, orgID profile.DateCreated = time.Now().UTC() if authType.IsExternal { externalUser := model.ExternalSystemUser{Identifier: identifier} - accountAuthType, err = a.applySignUpAdminExternal(context, *authType, *appOrg, externalUser, profile, username, permissions, roleIDs, groupIDs, creatorPermissions, clientVersion, l) + accountAuthType, err = a.applySignUpAdminExternal(sa, *authType, *appOrg, externalUser, profile, username, permissions, roleIDs, groupIDs, creatorPermissions, clientVersion, l) if err != nil { return errors.WrapErrorAction("signing up", "admin user", &logutils.FieldArgs{"auth_type": authType.Code, "identifier": identifier}, err) } @@ -603,7 +603,7 @@ func (a *Auth) CreateAdminAccount(authenticationType string, appID string, orgID } profile.Email = identifier - params, accountAuthType, err = a.applySignUpAdmin(context, authImpl, account, *authType, *appOrg, identifier, "", profile, username, permissions, roleIDs, groupIDs, creatorPermissions, clientVersion, l) + params, accountAuthType, err = a.applySignUpAdmin(sa, authImpl, account, *authType, *appOrg, identifier, "", profile, username, permissions, roleIDs, groupIDs, creatorPermissions, clientVersion, l) if err != nil { return errors.WrapErrorAction("signing up", "admin user", &logutils.FieldArgs{"auth_type": authType.Code, "identifier": identifier}, err) } @@ -639,9 +639,9 @@ func (a *Auth) UpdateAdminAccount(authenticationType string, appID string, orgID var updatedAccount *model.Account var params map[string]interface{} - transaction := func(context storage.TransactionContext) error { + transaction := func(sa storage.Adapter) error { //1. check if the user exists - account, err := a.storage.FindAccount(context, appOrg.ID, authType.ID, identifier) + account, err := sa.FindAccount(appOrg.ID, authType.ID, identifier) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) } @@ -664,7 +664,7 @@ func (a *Auth) UpdateAdminAccount(authenticationType string, appID string, orgID if len(added) > 0 || len(removed) > 0 { newPermissions := []model.Permission{} if len(added) > 0 { - addedPermissions, err := a.CheckPermissions(context, []model.ApplicationOrganization{*appOrg}, added, updaterPermissions, false) + addedPermissions, err := a.CheckPermissions(sa, []model.ApplicationOrganization{*appOrg}, added, updaterPermissions, false) if err != nil { return errors.WrapErrorAction("adding", model.TypePermission, nil, err) } @@ -672,7 +672,7 @@ func (a *Auth) UpdateAdminAccount(authenticationType string, appID string, orgID } if len(removed) > 0 { - _, err := a.CheckPermissions(context, []model.ApplicationOrganization{*appOrg}, removed, updaterPermissions, true) + _, err := a.CheckPermissions(sa, []model.ApplicationOrganization{*appOrg}, removed, updaterPermissions, true) if err != nil { return errors.WrapErrorAction("revoking", model.TypePermission, nil, err) } @@ -680,14 +680,14 @@ func (a *Auth) UpdateAdminAccount(authenticationType string, appID string, orgID } if len(unchanged) > 0 { - unchangedPermissions, err := a.storage.FindPermissionsByName(context, unchanged) + unchangedPermissions, err := sa.FindPermissionsByName(unchanged) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypePermission, nil, err) } newPermissions = append(newPermissions, unchangedPermissions...) } - err = a.storage.UpdateAccountPermissions(context, account.ID, newPermissions) + err = sa.UpdateAccountPermissions(account.ID, newPermissions) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, "admin account permissions", nil, err) } @@ -701,7 +701,7 @@ func (a *Auth) UpdateAdminAccount(authenticationType string, appID string, orgID if len(added) > 0 || len(removed) > 0 { newRoles := []model.AppOrgRole{} if len(added) > 0 { - addedRoles, err := a.CheckRoles(context, appOrg, added, updaterPermissions, false) + addedRoles, err := a.CheckRoles(sa, appOrg, added, updaterPermissions, false) if err != nil { return errors.WrapErrorAction("adding", model.TypeAccountRoles, nil, err) } @@ -709,7 +709,7 @@ func (a *Auth) UpdateAdminAccount(authenticationType string, appID string, orgID } if len(removed) > 0 { - _, err := a.CheckRoles(context, appOrg, removed, updaterPermissions, true) + _, err := a.CheckRoles(sa, appOrg, removed, updaterPermissions, true) if err != nil { return errors.WrapErrorAction("revoking", model.TypeAccountRoles, nil, err) } @@ -717,7 +717,7 @@ func (a *Auth) UpdateAdminAccount(authenticationType string, appID string, orgID } if len(unchanged) > 0 { - unchangedRoles, err := a.storage.FindAppOrgRolesByIDs(context, unchanged, appOrg.ID) + unchangedRoles, err := sa.FindAppOrgRolesByIDs(unchanged, appOrg.ID) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeAccountRoles, nil, err) } @@ -725,7 +725,7 @@ func (a *Auth) UpdateAdminAccount(authenticationType string, appID string, orgID } newAccountRoles := model.AccountRolesFromAppOrgRoles(newRoles, true, true) - err = a.storage.UpdateAccountRoles(context, account.ID, newAccountRoles) + err = sa.UpdateAccountRoles(account.ID, newAccountRoles) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, "admin account roles", nil, err) } @@ -739,7 +739,7 @@ func (a *Auth) UpdateAdminAccount(authenticationType string, appID string, orgID if len(added) > 0 || len(removed) > 0 { newGroups := []model.AppOrgGroup{} if len(added) > 0 { - addedGroups, err := a.CheckGroups(context, appOrg, added, updaterPermissions, false) + addedGroups, err := a.CheckGroups(sa, appOrg, added, updaterPermissions, false) if err != nil { return errors.WrapErrorAction("adding", model.TypeAccountGroups, nil, err) } @@ -747,7 +747,7 @@ func (a *Auth) UpdateAdminAccount(authenticationType string, appID string, orgID } if len(removed) > 0 { - _, err := a.CheckGroups(context, appOrg, removed, updaterPermissions, true) + _, err := a.CheckGroups(sa, appOrg, removed, updaterPermissions, true) if err != nil { return errors.WrapErrorAction("revoking", model.TypeAccountGroups, nil, err) } @@ -755,7 +755,7 @@ func (a *Auth) UpdateAdminAccount(authenticationType string, appID string, orgID } if len(unchanged) > 0 { - unchangedGroups, err := a.storage.FindAppOrgGroupsByIDs(context, unchanged, appOrg.ID) + unchangedGroups, err := sa.FindAppOrgGroupsByIDs(unchanged, appOrg.ID) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeAccountGroups, nil, err) } @@ -763,7 +763,7 @@ func (a *Auth) UpdateAdminAccount(authenticationType string, appID string, orgID } newAccountGroups := model.AccountGroupsFromAppOrgGroups(newGroups, true, true) - err = a.storage.UpdateAccountGroups(context, account.ID, newAccountGroups) + err = sa.UpdateAccountGroups(account.ID, newAccountGroups) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, "admin account groups", nil, err) } @@ -774,7 +774,7 @@ func (a *Auth) UpdateAdminAccount(authenticationType string, appID string, orgID //6. delete active login sessions if anything was revoked if revoked { - err = a.storage.DeleteLoginSessionsByIdentifier(context, account.ID) + err = sa.DeleteLoginSessionsByIdentifier(account.ID) if err != nil { return errors.WrapErrorAction(logutils.ActionDelete, model.TypeLoginSession, nil, err) } @@ -797,7 +797,7 @@ func (a *Auth) UpdateAdminAccount(authenticationType string, appID string, orgID } // CreateAnonymousAccount creates a new anonymous account -func (a *Auth) CreateAnonymousAccount(context storage.TransactionContext, appID string, orgID string, anonymousID string, preferences map[string]interface{}, +func (a *Auth) CreateAnonymousAccount(sa storage.Adapter, appID string, orgID string, anonymousID string, preferences map[string]interface{}, systemConfigs map[string]interface{}, skipExistsCheck bool, l *logs.Log) (*model.Account, error) { // check if the provided auth type is supported by the provided application and organization authType, appOrg, err := a.validateAuthTypeForAppOrg(AuthTypeAnonymous, appID, orgID) @@ -805,35 +805,22 @@ func (a *Auth) CreateAnonymousAccount(context storage.TransactionContext, appID return nil, errors.WrapErrorAction(logutils.ActionValidate, typeAuthType, nil, err) } - // create account var newAccount *model.Account - transaction := func(context storage.TransactionContext) error { - //1. check if the user exists - if context == nil || !skipExistsCheck { - account, err := a.storage.FindAccountByID(context, anonymousID) - if err != nil { - return errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) - } - if account != nil { - return errors.ErrorData(logutils.StatusFound, model.TypeAccount, &logutils.FieldArgs{"app_org_id": appOrg.ID, "auth_type": authType.Code, "account_id": anonymousID}) - } - } - - newAccount, err = a.applyCreateAnonymousAccount(context, *appOrg, anonymousID, preferences, systemConfigs, l) + //1. check if the user exists + if !skipExistsCheck { + account, err := sa.FindAccountByID(anonymousID) if err != nil { - return errors.WrapErrorAction(logutils.ActionCreate, "anonymous account", &logutils.FieldArgs{"account_id": anonymousID}, err) + return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) + } + if account != nil { + return nil, errors.ErrorData(logutils.StatusFound, model.TypeAccount, &logutils.FieldArgs{"app_org_id": appOrg.ID, "auth_type": authType.Code, "account_id": anonymousID}) } - - return nil } - if context == nil { - err = a.storage.PerformTransaction(transaction) - if err != nil { - return nil, errors.WrapErrorAction(logutils.ActionCreate, "anonymous account", nil, err) - } - } else { - transaction(context) + //2. create account + newAccount, err = a.applyCreateAnonymousAccount(sa, *appOrg, anonymousID, preferences, systemConfigs, l) + if err != nil { + return nil, errors.WrapErrorAction(logutils.ActionCreate, "anonymous account", &logutils.FieldArgs{"account_id": anonymousID}, err) } return newAccount, nil @@ -841,7 +828,7 @@ func (a *Auth) CreateAnonymousAccount(context storage.TransactionContext, appID // VerifyCredential verifies credential (checks the verification code in the credentials collection) func (a *Auth) VerifyCredential(id string, verification string, l *logs.Log) error { - credential, err := a.storage.FindCredential(nil, id) + credential, err := a.storage.FindCredential(id) if err != nil || credential == nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeCredential, nil, err) } @@ -871,7 +858,7 @@ func (a *Auth) VerifyCredential(id string, verification string, l *logs.Log) err credential.Verified = true credential.Value = authTypeCreds - if err = a.storage.UpdateCredential(nil, credential); err != nil { + if err = a.storage.UpdateCredential(credential); err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeCredential, nil, err) } @@ -891,7 +878,7 @@ func (a *Auth) VerifyCredential(id string, verification string, l *logs.Log) err // Handle refresh tokens when applicable func (a *Auth) UpdateCredential(accountID string, accountAuthTypeID string, params string, l *logs.Log) error { //Get the user credential from account auth type in accounts collection - account, err := a.storage.FindAccountByID(nil, accountID) + account, err := a.storage.FindAccountByID(accountID) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) } @@ -921,7 +908,7 @@ func (a *Auth) UpdateCredential(accountID string, accountAuthTypeID string, para } //Update the credential with new password credential.Value = authTypeCreds - if err = a.storage.UpdateCredential(nil, credential); err != nil { + if err = a.storage.UpdateCredential(credential); err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeCredential, nil, err) } @@ -940,7 +927,7 @@ func (a *Auth) UpdateCredential(accountID string, accountAuthTypeID string, para // TODO: Clear login sessions using old creds // Handle refresh tokens when applicable func (a *Auth) ResetForgotCredential(credsID string, resetCode string, params string, l *logs.Log) error { - credential, err := a.storage.FindCredential(nil, credsID) + credential, err := a.storage.FindCredential(credsID) if err != nil || credential == nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeCredential, nil, err) } @@ -965,7 +952,7 @@ func (a *Auth) ResetForgotCredential(credsID string, resetCode string, params st } //Update the credential with new password credential.Value = authTypeCreds - if err = a.storage.UpdateCredential(nil, credential); err != nil { + if err = a.storage.UpdateCredential(credential); err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeCredential, nil, err) } @@ -1013,7 +1000,7 @@ func (a *Auth) ForgotCredential(authenticationType string, appTypeIdentifier str authTypeID := authType.ID //Find the credential for setting reset code and expiry and sending credID in reset link - account, err := a.storage.FindAccount(nil, appOrg.ID, authTypeID, identifier) + account, err := a.storage.FindAccount(appOrg.ID, authTypeID, identifier) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) } @@ -1040,7 +1027,7 @@ func (a *Auth) ForgotCredential(authenticationType string, appTypeIdentifier str } //Update the credential with reset code and expiry credential.Value = authTypeCreds - if err = a.storage.UpdateCredential(nil, credential); err != nil { + if err = a.storage.UpdateCredential(credential); err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeCredential, nil, err) } return nil @@ -1066,7 +1053,7 @@ func (a *Auth) SendVerifyCredential(authenticationType string, appTypeIdentifier if err != nil { return errors.WrapErrorAction(logutils.ActionLoadCache, typeAuthType, nil, err) } - account, err := a.storage.FindAccount(nil, appOrg.ID, authType.ID, identifier) + account, err := a.storage.FindAccount(appOrg.ID, authType.ID, identifier) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) } @@ -1106,10 +1093,10 @@ func (a *Auth) SendVerifyCredential(authenticationType string, appTypeIdentifier func (a *Auth) VerifyMFA(accountID string, identifier string, mfaType string, mfaCode string) (*string, []string, error) { var recoveryMfa *model.MFAType var message *string - transaction := func(context storage.TransactionContext) error { + transaction := func(sa storage.Adapter) error { errFields := &logutils.FieldArgs{"account_id": accountID, "type": mfaType} //1. find mfa type in account - mfa, err := a.storage.FindMFAType(context, accountID, identifier, mfaType) + mfa, err := sa.FindMFAType(accountID, identifier, mfaType) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeMFAType, errFields, err) } @@ -1129,20 +1116,20 @@ func (a *Auth) VerifyMFA(accountID string, identifier string, mfaType string, mf if err != nil { return errors.WrapErrorAction(logutils.ActionLoadCache, typeMfaType, nil, err) } - message, err = mfaImpl.verify(context, mfa, accountID, mfaCode) + message, err = mfaImpl.verify(sa, mfa, accountID, mfaCode) if err != nil { return errors.WrapErrorAction(logutils.ActionValidate, typeMfaType, errFields, err) } //3. update existing MFA type mfa.Verified = true - err = a.storage.UpdateMFAType(context, mfa, accountID) + err = sa.UpdateMFAType(mfa, accountID) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeMFAType, &logutils.FieldArgs{"account_id": accountID, "id": mfa.ID}, err) } //4. find account - account, err := a.storage.FindAccountByID(context, accountID) + account, err := sa.FindAccountByID(accountID) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, &logutils.FieldArgs{"_id": accountID}, err) } @@ -1159,7 +1146,7 @@ func (a *Auth) VerifyMFA(accountID string, identifier string, mfaType string, mf } // insert recovery mfa type - err = a.storage.InsertMFAType(context, recoveryMfa, accountID) + err = sa.InsertMFAType(recoveryMfa, accountID) if err != nil { return errors.WrapErrorAction(logutils.ActionInsert, model.TypeMFAType, &logutils.FieldArgs{"account_id": accountID, "type": MfaTypeRecovery}, err) } @@ -1219,7 +1206,7 @@ func (a *Auth) AddMFAType(accountID string, identifier string, mfaType string) ( return nil, errors.WrapErrorAction("enrolling", typeMfaType, nil, err) } - err = a.storage.InsertMFAType(nil, newMfa, accountID) + err = a.storage.InsertMFAType(newMfa, accountID) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionInsert, typeMfaType, &logutils.FieldArgs{"account_id": accountID, "type": mfaType}, err) } @@ -1234,15 +1221,15 @@ func (a *Auth) AddMFAType(accountID string, identifier string, mfaType string) ( // identifier (string): Email, phone, or TOTP device name // mfaType (string): Type of MFA to remove func (a *Auth) RemoveMFAType(accountID string, identifier string, mfaType string) error { - transaction := func(context storage.TransactionContext) error { + transaction := func(sa storage.Adapter) error { //1. remove mfa type from account - err := a.storage.DeleteMFAType(context, accountID, identifier, mfaType) + err := sa.DeleteMFAType(accountID, identifier, mfaType) if err != nil { return errors.WrapErrorAction(logutils.ActionDelete, model.TypeMFAType, &logutils.FieldArgs{"account_id": accountID, "identifier": identifier, "type": mfaType}, err) } //2. find account - account, err := a.storage.FindAccountByID(context, accountID) + account, err := sa.FindAccountByID(accountID) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) } @@ -1252,7 +1239,7 @@ func (a *Auth) RemoveMFAType(accountID string, identifier string, mfaType string //3. check if account only has recovery MFA remaining if len(account.MFATypes) == 1 && account.MFATypes[0].Type == MfaTypeRecovery { - err = a.storage.DeleteMFAType(context, accountID, MfaTypeRecovery, MfaTypeRecovery) + err = sa.DeleteMFAType(accountID, MfaTypeRecovery, MfaTypeRecovery) if err != nil { return errors.WrapErrorAction(logutils.ActionDelete, model.TypeMFAType, &logutils.FieldArgs{"account_id": accountID, "identifier": MfaTypeRecovery, "type": MfaTypeRecovery}, err) } @@ -1355,7 +1342,7 @@ func (a *Auth) RegisterServiceAccount(accountID *string, fromAppID *string, from if accountID != nil && fromAppID != nil && fromOrgID != nil { var fromAccount *model.ServiceAccount - fromAccount, err = a.storage.FindServiceAccount(nil, *accountID, *fromAppID, *fromOrgID) + fromAccount, err = a.storage.FindServiceAccount(*accountID, *fromAppID, *fromOrgID) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeServiceAccount, nil, err) } @@ -1431,7 +1418,7 @@ func (a *Auth) DeregisterServiceAccount(accountID string) error { // GetServiceAccountInstance gets a service account instance func (a *Auth) GetServiceAccountInstance(accountID string, appID string, orgID string) (*model.ServiceAccount, error) { - serviceAccount, err := a.storage.FindServiceAccount(nil, accountID, appID, orgID) + serviceAccount, err := a.storage.FindServiceAccount(accountID, appID, orgID) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeServiceAccount, nil, err) } @@ -1442,9 +1429,9 @@ func (a *Auth) GetServiceAccountInstance(accountID string, appID string, orgID s // UpdateServiceAccountInstance updates a service account instance func (a *Auth) UpdateServiceAccountInstance(id string, appID string, orgID string, name *string, permissions *[]string, scopes []authorization.Scope, assignerPermissions []string) (*model.ServiceAccount, error) { var updatedAccount *model.ServiceAccount - transaction := func(context storage.TransactionContext) error { + transaction := func(sa storage.Adapter) error { //1. find service account - serviceAccount, err := a.storage.FindServiceAccount(context, id, appID, orgID) + serviceAccount, err := sa.FindServiceAccount(id, appID, orgID) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeServiceAccount, nil, err) } @@ -1477,7 +1464,7 @@ func (a *Auth) UpdateServiceAccountInstance(id string, appID string, orgID strin updatedPermissions := make([]model.Permission, 0) added, removed, unchanged := utils.StringListDiff(*permissions, serviceAccount.GetPermissionNames()) if len(added) > 0 { - permissionList, err := a.CheckPermissions(context, appOrgs, *permissions, assignerPermissions, false) + permissionList, err := a.CheckPermissions(sa, appOrgs, *permissions, assignerPermissions, false) if err != nil { return errors.WrapErrorAction(logutils.ActionValidate, model.TypePermission, nil, err) } @@ -1486,7 +1473,7 @@ func (a *Auth) UpdateServiceAccountInstance(id string, appID string, orgID strin updated = true } if len(removed) > 0 { - _, err := a.CheckPermissions(context, appOrgs, *permissions, assignerPermissions, true) + _, err := a.CheckPermissions(sa, appOrgs, *permissions, assignerPermissions, true) if err != nil { return errors.WrapErrorAction("revoking", model.TypePermission, nil, err) } @@ -1494,7 +1481,7 @@ func (a *Auth) UpdateServiceAccountInstance(id string, appID string, orgID strin updated = true } if len(unchanged) > 0 { - permissionList, err := a.storage.FindPermissionsByName(context, unchanged) + permissionList, err := sa.FindPermissionsByName(unchanged) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypePermission, nil, err) } @@ -1511,7 +1498,7 @@ func (a *Auth) UpdateServiceAccountInstance(id string, appID string, orgID strin //4. update service account in database if updated { - updatedAccount, err = a.storage.UpdateServiceAccount(context, serviceAccount) + updatedAccount, err = sa.UpdateServiceAccount(serviceAccount) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeServiceAccount, nil, err) } @@ -1656,7 +1643,7 @@ func (a *Auth) LinkAccountAuthType(accountID string, authenticationType string, message := "" var newAccountAuthType *model.AccountAuthType - account, err := a.storage.FindAccountByID(nil, accountID) + account, err := a.storage.FindAccountByID(accountID) if err != nil { return nil, nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) } @@ -1708,9 +1695,9 @@ func (a *Auth) UnlinkAccountAuthType(accountID string, authenticationType string // DeleteAccount deletes an account for the given id func (a *Auth) DeleteAccount(id string) error { - transaction := func(context storage.TransactionContext) error { + transaction := func(sa storage.Adapter) error { //1. first find the account record - account, err := a.storage.FindAccountByID(context, id) + account, err := sa.FindAccountByID(id) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) } @@ -1718,7 +1705,7 @@ func (a *Auth) DeleteAccount(id string) error { return errors.ErrorData(logutils.StatusMissing, model.TypeAccount, nil) } - err = a.deleteAccount(context, *account) + err = a.deleteAccount(sa, *account) if err != nil { return errors.WrapErrorAction(logutils.ActionDelete, model.TypeAccount, nil, err) } @@ -1730,7 +1717,7 @@ func (a *Auth) DeleteAccount(id string) error { } // InitializeSystemAccount initializes the first system account -func (a *Auth) InitializeSystemAccount(context storage.TransactionContext, authType model.AuthType, appOrg model.ApplicationOrganization, +func (a *Auth) InitializeSystemAccount(sa storage.Adapter, authType model.AuthType, appOrg model.ApplicationOrganization, allSystemPermission string, email string, password string, clientVersion string, l *logs.Log) (string, error) { //auth type authImpl, err := a.getAuthTypeImpl(authType) @@ -1742,7 +1729,7 @@ func (a *Auth) InitializeSystemAccount(context storage.TransactionContext, authT profile := model.Profile{ID: uuid.NewString(), Email: email, DateCreated: now} permissions := []string{allSystemPermission} - _, accountAuthType, err := a.applySignUpAdmin(context, authImpl, nil, authType, appOrg, email, password, profile, "", permissions, nil, nil, permissions, &clientVersion, l) + _, accountAuthType, err := a.applySignUpAdmin(sa, authImpl, nil, authType, appOrg, email, password, profile, "", permissions, nil, nil, permissions, &clientVersion, l) if err != nil { return "", errors.WrapErrorAction("signing up", "initial system user", &logutils.FieldArgs{"email": email}, err) } @@ -1751,7 +1738,7 @@ func (a *Auth) InitializeSystemAccount(context storage.TransactionContext, authT } // GrantAccountPermissions grants new permissions to an account after validating the assigner has required permissions -func (a *Auth) GrantAccountPermissions(context storage.TransactionContext, account *model.Account, permissionNames []string, assignerPermissions []string) error { +func (a *Auth) GrantAccountPermissions(sa storage.Adapter, account *model.Account, permissionNames []string, assignerPermissions []string) error { //check if there is data if account == nil { return errors.New("no account to grant permissions") @@ -1770,13 +1757,13 @@ func (a *Auth) GrantAccountPermissions(context storage.TransactionContext, accou } //check permissions - permissions, err := a.CheckPermissions(context, []model.ApplicationOrganization{account.AppOrg}, newPermissions, assignerPermissions, false) + permissions, err := a.CheckPermissions(sa, []model.ApplicationOrganization{account.AppOrg}, newPermissions, assignerPermissions, false) if err != nil { return errors.WrapErrorAction(logutils.ActionValidate, model.TypePermission, nil, err) } //update account if authorized - err = a.storage.InsertAccountPermissions(context, account.ID, permissions) + err = sa.InsertAccountPermissions(account.ID, permissions) if err != nil { return errors.WrapErrorAction(logutils.ActionInsert, model.TypeAccountPermissions, &logutils.FieldArgs{"account_id": account.ID}, err) } @@ -1786,7 +1773,7 @@ func (a *Auth) GrantAccountPermissions(context storage.TransactionContext, accou } // CheckPermissions loads permissions by names from storage and checks that they are assignable and valid for the given appOrgs or revocable -func (a *Auth) CheckPermissions(context storage.TransactionContext, appOrgs []model.ApplicationOrganization, permissionNames []string, assignerPermissions []string, revoke bool) ([]model.Permission, error) { +func (a *Auth) CheckPermissions(sa storage.Adapter, appOrgs []model.ApplicationOrganization, permissionNames []string, assignerPermissions []string, revoke bool) ([]model.Permission, error) { if len(appOrgs) == 0 { return nil, errors.ErrorData(logutils.StatusMissing, model.TypeApplicationOrganization, nil) } @@ -1797,7 +1784,7 @@ func (a *Auth) CheckPermissions(context storage.TransactionContext, appOrgs []mo } //find permissions - permissions, err := a.storage.FindPermissionsByName(context, permissionNames) + permissions, err := sa.FindPermissionsByName(permissionNames) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypePermission, nil, err) } @@ -1838,7 +1825,7 @@ func (a *Auth) CheckPermissions(context storage.TransactionContext, appOrgs []mo } // GrantAccountRoles grants new roles to an account after validating the assigner has required permissions -func (a *Auth) GrantAccountRoles(context storage.TransactionContext, account *model.Account, roleIDs []string, assignerPermissions []string) error { +func (a *Auth) GrantAccountRoles(sa storage.Adapter, account *model.Account, roleIDs []string, assignerPermissions []string) error { //check if there is data if account == nil { return errors.New("no account to grant roles") @@ -1857,14 +1844,14 @@ func (a *Auth) GrantAccountRoles(context storage.TransactionContext, account *mo } //check roles - roles, err := a.CheckRoles(context, &account.AppOrg, newRoles, assignerPermissions, false) + roles, err := a.CheckRoles(sa, &account.AppOrg, newRoles, assignerPermissions, false) if err != nil { return errors.WrapErrorAction(logutils.ActionValidate, model.TypeAppOrgRole, nil, err) } //update account if authorized accountRoles := model.AccountRolesFromAppOrgRoles(roles, true, true) - err = a.storage.InsertAccountRoles(context, account.ID, account.AppOrg.ID, accountRoles) + err = sa.InsertAccountRoles(account.ID, account.AppOrg.ID, accountRoles) if err != nil { return errors.WrapErrorAction(logutils.ActionInsert, model.TypeAccountRoles, &logutils.FieldArgs{"account_id": account.ID}, err) } @@ -1874,13 +1861,13 @@ func (a *Auth) GrantAccountRoles(context storage.TransactionContext, account *mo } // CheckRoles loads appOrg roles by IDs from storage and checks that they are assignable or revocable -func (a *Auth) CheckRoles(context storage.TransactionContext, appOrg *model.ApplicationOrganization, roleIDs []string, assignerPermissions []string, revoke bool) ([]model.AppOrgRole, error) { +func (a *Auth) CheckRoles(sa storage.Adapter, appOrg *model.ApplicationOrganization, roleIDs []string, assignerPermissions []string, revoke bool) ([]model.AppOrgRole, error) { if appOrg == nil { return nil, errors.ErrorData(logutils.StatusInvalid, model.TypeApplicationOrganization, nil) } //find roles - roles, err := a.storage.FindAppOrgRolesByIDs(context, roleIDs, appOrg.ID) + roles, err := sa.FindAppOrgRolesByIDs(roleIDs, appOrg.ID) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeAppOrgRole, nil, err) } @@ -1913,7 +1900,7 @@ func (a *Auth) CheckRoles(context storage.TransactionContext, appOrg *model.Appl } // GrantAccountGroups grants new groups to an account after validating the assigner has required permissions -func (a *Auth) GrantAccountGroups(context storage.TransactionContext, account *model.Account, groupIDs []string, assignerPermissions []string) error { +func (a *Auth) GrantAccountGroups(sa storage.Adapter, account *model.Account, groupIDs []string, assignerPermissions []string) error { //check if there is data if account == nil { return errors.New("no accounts to grant groups") @@ -1932,14 +1919,14 @@ func (a *Auth) GrantAccountGroups(context storage.TransactionContext, account *m } //check groups - groups, err := a.CheckGroups(context, &account.AppOrg, newGroups, assignerPermissions, false) + groups, err := a.CheckGroups(sa, &account.AppOrg, newGroups, assignerPermissions, false) if err != nil { return errors.WrapErrorAction(logutils.ActionValidate, model.TypeAppOrgGroup, nil, err) } //update account if authorized accountGroups := model.AccountGroupsFromAppOrgGroups(groups, true, true) - err = a.storage.InsertAccountGroups(context, account.ID, account.AppOrg.ID, accountGroups) + err = sa.InsertAccountGroups(account.ID, account.AppOrg.ID, accountGroups) if err != nil { return errors.WrapErrorAction(logutils.ActionInsert, model.TypeAccountGroups, &logutils.FieldArgs{"account_id": account.ID}, err) } @@ -1949,13 +1936,13 @@ func (a *Auth) GrantAccountGroups(context storage.TransactionContext, account *m } // CheckGroups loads appOrg groups by IDs from storage and checks that they are assignable or revocable -func (a *Auth) CheckGroups(context storage.TransactionContext, appOrg *model.ApplicationOrganization, groupIDs []string, assignerPermissions []string, revoke bool) ([]model.AppOrgGroup, error) { +func (a *Auth) CheckGroups(sa storage.Adapter, appOrg *model.ApplicationOrganization, groupIDs []string, assignerPermissions []string, revoke bool) ([]model.AppOrgGroup, error) { if appOrg == nil { return nil, errors.ErrorData(logutils.StatusInvalid, model.TypeApplicationOrganization, nil) } //find groups - groups, err := a.storage.FindAppOrgGroupsByIDs(context, groupIDs, appOrg.ID) + groups, err := sa.FindAppOrgGroupsByIDs(groupIDs, appOrg.ID) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeAppOrgGroup, nil, err) } @@ -2066,7 +2053,7 @@ func (a *Auth) GetAPIKey(ID string) (*model.APIKey, error) { func (a *Auth) CreateAPIKey(apiKey model.APIKey) (*model.APIKey, error) { id, _ := uuid.NewUUID() apiKey.ID = id.String() - return a.storage.InsertAPIKey(nil, apiKey) + return a.storage.InsertAPIKey(apiKey) } // UpdateAPIKey updates an existing API key diff --git a/core/auth/auth.go b/core/auth/auth.go index 8b7d1a6db..5f2d60e62 100644 --- a/core/auth/auth.go +++ b/core/auth/auth.go @@ -227,7 +227,7 @@ func (a *Auth) applyExternalAuthType(authType model.AuthType, appType model.Appl } //2. check if the user exists - account, err := a.storage.FindAccount(nil, appOrg.ID, authType.ID, externalUser.Identifier) + account, err := a.storage.FindAccount(appOrg.ID, authType.ID, externalUser.Identifier) if err != nil { return nil, nil, nil, nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) } @@ -244,7 +244,7 @@ func (a *Auth) applyExternalAuthType(authType model.AuthType, appType model.Appl externalIDs = account.ExternalIDs } else if !admin { //user does not exist, we need to register it - accountAuthType, err = a.applySignUpExternal(nil, authType, appOrg, *externalUser, regProfile, regPreferences, username, clientVersion, l) + accountAuthType, err = a.applySignUpExternal(*a.storage.(*storage.Adapter), authType, appOrg, *externalUser, regProfile, regPreferences, username, clientVersion, l) if err != nil { return nil, nil, nil, nil, errors.Wrap("error on apply sign up external", err) } @@ -289,7 +289,7 @@ func (a *Auth) applySignInExternal(account *model.Account, authType model.AuthTy return accountAuthType, nil } -func (a *Auth) applySignUpExternal(context storage.TransactionContext, authType model.AuthType, appOrg model.ApplicationOrganization, externalUser model.ExternalSystemUser, +func (a *Auth) applySignUpExternal(sa storage.Adapter, authType model.AuthType, appOrg model.ApplicationOrganization, externalUser model.ExternalSystemUser, regProfile model.Profile, regPreferences map[string]interface{}, username string, clientVersion *string, l *logs.Log) (*model.AccountAuthType, error) { var accountAuthType *model.AccountAuthType @@ -322,14 +322,14 @@ func (a *Auth) applySignUpExternal(context storage.TransactionContext, authType //4. check username if username != "" { - err = a.checkUsername(nil, &appOrg, username) + err = a.checkUsername(sa, &appOrg, username) if err != nil { return nil, err } } //5. register the account - accountAuthType, err = a.registerUser(context, authType, identifier, aatParams, appOrg, nil, useSharedProfile, + accountAuthType, err = a.registerUser(sa, authType, identifier, aatParams, appOrg, nil, useSharedProfile, externalUser.ExternalIDs, *profile, preferences, username, nil, externalRoles, externalGroups, nil, clientVersion, l) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionRegister, model.TypeAccount, nil, err) @@ -338,7 +338,7 @@ func (a *Auth) applySignUpExternal(context storage.TransactionContext, authType return accountAuthType, nil } -func (a *Auth) applySignUpAdminExternal(context storage.TransactionContext, authType model.AuthType, appOrg model.ApplicationOrganization, externalUser model.ExternalSystemUser, regProfile model.Profile, +func (a *Auth) applySignUpAdminExternal(sa storage.Adapter, authType model.AuthType, appOrg model.ApplicationOrganization, externalUser model.ExternalSystemUser, regProfile model.Profile, username string, permissions []string, roleIDs []string, groupIDs []string, creatorPermissions []string, clientVersion *string, l *logs.Log) (*model.AccountAuthType, error) { var accountAuthType *model.AccountAuthType @@ -350,14 +350,14 @@ func (a *Auth) applySignUpAdminExternal(context storage.TransactionContext, auth //2. check username if username != "" { - err = a.checkUsername(nil, &appOrg, username) + err = a.checkUsername(sa, &appOrg, username) if err != nil { return nil, err } } //3. register the account - accountAuthType, err = a.registerUser(context, authType, identifier, aatParams, appOrg, nil, useSharedProfile, nil, *profile, nil, + accountAuthType, err = a.registerUser(sa, authType, identifier, aatParams, appOrg, nil, useSharedProfile, nil, *profile, nil, username, permissions, roleIDs, groupIDs, creatorPermissions, clientVersion, l) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionRegister, "admin account", nil, err) @@ -468,9 +468,9 @@ func (a *Auth) updateExternalUserIfNeeded(accountAuthType model.AccountAuthType, now := time.Now() accountAuthType.DateUpdated = &now - transaction := func(context storage.TransactionContext) error { + transaction := func(sa storage.Adapter) error { //1. first find the account record - account, err := a.storage.FindAccountByAuthTypeID(context, accountAuthType.ID) + account, err := sa.FindAccountByAuthTypeID(accountAuthType.ID) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) } @@ -522,7 +522,7 @@ func (a *Auth) updateExternalUserIfNeeded(accountAuthType model.AccountAuthType, // 6. update account if needed if updated || profileUpdated || rolesUpdated || groupsUpdated { - err = a.storage.SaveAccount(context, account) + err = sa.SaveAccount(account) if err != nil { return errors.WrapErrorAction(logutils.ActionSave, model.TypeAccount, nil, err) } @@ -551,7 +551,7 @@ func (a *Auth) applyAnonymousAuthType(authType model.AuthType, creds string) (st return "", nil, nil, errors.WrapErrorAction(logutils.ActionValidate, model.TypeCreds, nil, err) } - account, err := a.storage.FindAccountByID(nil, anonymousID) + account, err := a.storage.FindAccountByID(anonymousID) if err != nil { return "", nil, nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, &logutils.FieldArgs{"id": anonymousID}, err) } @@ -585,7 +585,7 @@ func (a *Auth) applyAuthType(authType model.AuthType, appOrg model.ApplicationOr } } - account, err := a.storage.FindAccount(nil, appOrg.ID, authType.ID, userIdentifier) + account, err := a.storage.FindAccount(appOrg.ID, authType.ID, userIdentifier) if err != nil { return "", nil, nil, nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) //TODO add args.. } @@ -700,14 +700,15 @@ func (a *Auth) applySignUp(authImpl authType, account *model.Account, authType m } } + sa := a.storage.(*storage.Adapter) if username != "" { - err := a.checkUsername(nil, &appOrg, username) + err := a.checkUsername(*sa, &appOrg, username) if err != nil { return "", nil, err } } - retParams, accountAuthType, err := a.signUpNewAccount(nil, authImpl, authType, appOrg, userIdentifier, creds, params, clientVersion, regProfile, regPreferences, username, nil, nil, nil, nil, l) + retParams, accountAuthType, err := a.signUpNewAccount(*sa, authImpl, authType, appOrg, userIdentifier, creds, params, clientVersion, regProfile, regPreferences, username, nil, nil, nil, nil, l) if err != nil { return "", nil, err } @@ -716,26 +717,26 @@ func (a *Auth) applySignUp(authImpl authType, account *model.Account, authType m return message, accountAuthType, nil } -func (a *Auth) applySignUpAdmin(context storage.TransactionContext, authImpl authType, account *model.Account, authType model.AuthType, appOrg model.ApplicationOrganization, identifier string, password string, +func (a *Auth) applySignUpAdmin(sa storage.Adapter, authImpl authType, account *model.Account, authType model.AuthType, appOrg model.ApplicationOrganization, identifier string, password string, regProfile model.Profile, username string, permissions []string, roles []string, groups []string, creatorPermissions []string, clientVersion *string, l *logs.Log) (map[string]interface{}, *model.AccountAuthType, error) { if username != "" { - err := a.checkUsername(nil, &appOrg, username) + err := a.checkUsername(sa, &appOrg, username) if err != nil { return nil, nil, err } } - return a.signUpNewAccount(context, authImpl, authType, appOrg, identifier, password, "", clientVersion, regProfile, nil, username, permissions, roles, groups, creatorPermissions, l) + return a.signUpNewAccount(sa, authImpl, authType, appOrg, identifier, password, "", clientVersion, regProfile, nil, username, permissions, roles, groups, creatorPermissions, l) } -func (a *Auth) applyCreateAnonymousAccount(context storage.TransactionContext, appOrg model.ApplicationOrganization, anonymousID string, +func (a *Auth) applyCreateAnonymousAccount(sa storage.Adapter, appOrg model.ApplicationOrganization, anonymousID string, preferences map[string]interface{}, systemConfigs map[string]interface{}, l *logs.Log) (*model.Account, error) { account := model.Account{ID: anonymousID, AppOrg: appOrg, Preferences: preferences, SystemConfigs: systemConfigs, Anonymous: true, DateCreated: time.Now()} - return a.storage.InsertAccount(context, account) + return sa.InsertAccount(account) } -func (a *Auth) signUpNewAccount(context storage.TransactionContext, authImpl authType, authType model.AuthType, appOrg model.ApplicationOrganization, userIdentifier string, +func (a *Auth) signUpNewAccount(sa storage.Adapter, authImpl authType, authType model.AuthType, appOrg model.ApplicationOrganization, userIdentifier string, creds string, params string, clientVersion *string, regProfile model.Profile, regPreferences map[string]interface{}, username string, permissions []string, roles []string, groups []string, creatorPermissions []string, l *logs.Log) (map[string]interface{}, *model.AccountAuthType, error) { var retParams map[string]interface{} @@ -804,7 +805,7 @@ func (a *Auth) signUpNewAccount(context storage.TransactionContext, authImpl aut } } - accountAuthType, err := a.registerUser(context, authType, userIdentifier, nil, appOrg, credential, useSharedProfile, nil, profile, preferences, username, permissions, roles, groups, creatorPermissions, clientVersion, l) + accountAuthType, err := a.registerUser(sa, authType, userIdentifier, nil, appOrg, credential, useSharedProfile, nil, profile, preferences, username, permissions, roles, groups, creatorPermissions, clientVersion, l) if err != nil { return nil, nil, errors.WrapErrorAction(logutils.ActionRegister, model.TypeAccount, nil, err) } @@ -882,7 +883,7 @@ func (a *Auth) hasSharedProfile(app model.Application, authTypeID string, userId //find the credential if credentialID != nil { - credential, err = a.storage.FindCredential(nil, *credentialID) + credential, err = a.storage.FindCredential(*credentialID) if err != nil { return false, nil, nil, errors.Wrap("error finding a credential", err) } @@ -958,7 +959,7 @@ func (a *Auth) getAccount(authenticationType string, userIdentifier string, apiK } //check if the account exists check - account, err := a.storage.FindAccount(nil, appOrg.ID, authType.ID, userIdentifier) + account, err := a.storage.FindAccount(appOrg.ID, authType.ID, userIdentifier) if err != nil { return nil, "", errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) } @@ -984,7 +985,7 @@ func (a *Auth) findAccountAuthType(account *model.Account, authType *model.AuthT if accountAuthType.Credential != nil { //populate credentials in accountAuthType - credential, err := a.storage.FindCredential(nil, accountAuthType.Credential.ID) + credential, err := a.storage.FindCredential(accountAuthType.Credential.ID) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeCredential, nil, err) } @@ -1018,7 +1019,7 @@ func (a *Auth) findAccountAuthTypeByID(account *model.Account, accountAuthTypeID if accountAuthType.Credential != nil { //populate credentials in accountAuthType - credential, err := a.storage.FindCredential(nil, accountAuthType.Credential.ID) + credential, err := a.storage.FindCredential(accountAuthType.Credential.ID) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeCredential, nil, err) } @@ -1032,7 +1033,7 @@ func (a *Auth) clearExpiredSessions(identifier string, l *logs.Log) error { l.Info("clearExpiredSessions") //load the sessions for the identifier - loginsSessions, err := a.storage.FindLoginSessions(nil, identifier) + loginsSessions, err := a.storage.FindLoginSessions(identifier) if err != nil { return errors.Wrap("error finding logins sessions for clearing them", err) } @@ -1053,7 +1054,7 @@ func (a *Auth) clearExpiredSessions(identifier string, l *logs.Log) error { if len(expiredSessions) > 0 { l.Info("there is expired sessions for deleting") - err = a.deleteLoginSessions(nil, expiredSessions, l) + err = a.deleteLoginSessions(*a.storage.(*storage.Adapter), expiredSessions, l) if err != nil { return errors.Wrap("error on deleting logins sessions", err) } @@ -1071,12 +1072,12 @@ func (a *Auth) applyLogin(anonymous bool, sub string, authType model.AuthType, a var err error var loginSession *model.LoginSession - transaction := func(context storage.TransactionContext) error { + transaction := func(sa storage.Adapter) error { ///1. assign device to session and account var device *model.Device if !anonymous { //1. check if the device exists - device, err = a.storage.FindDevice(context, deviceID, sub) + device, err = sa.FindDevice(deviceID, sub) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeDevice, nil, err) } @@ -1089,7 +1090,7 @@ func (a *Auth) applyLogin(anonymous bool, sub string, authType model.AuthType, a if err != nil { return errors.WrapErrorAction("error creating device", model.TypeDevice, nil, err) } - _, err := a.storage.InsertDevice(context, *device) + _, err := sa.InsertDevice(*device) if err != nil { return errors.WrapErrorAction(logutils.ActionInsert, model.TypeDevice, nil, err) } @@ -1104,7 +1105,7 @@ func (a *Auth) applyLogin(anonymous bool, sub string, authType model.AuthType, a } //1. store login session - err = a.storage.InsertLoginSession(context, *loginSession) + err = sa.InsertLoginSession(*loginSession) if err != nil { return errors.WrapErrorAction(logutils.ActionInsert, model.TypeLoginSession, nil, err) } @@ -1112,7 +1113,7 @@ func (a *Auth) applyLogin(anonymous bool, sub string, authType model.AuthType, a //2. check session limit against number of active sessions sessionLimit := appOrg.LoginsSessionsSetting.MaxConcurrentSessions if sessionLimit > 0 { - loginSessions, err := a.storage.FindLoginSessions(context, loginSession.Identifier) + loginSessions, err := sa.FindLoginSessions(loginSession.Identifier) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeLoginSession, nil, err) } @@ -1122,7 +1123,7 @@ func (a *Auth) applyLogin(anonymous bool, sub string, authType model.AuthType, a if len(loginSessions) > sessionLimit { // delete first session in list (sorted by date created) - err = a.deleteLoginSession(context, loginSessions[0], l) + err = a.deleteLoginSession(sa, loginSessions[0], l) if err != nil { return errors.WrapErrorAction(logutils.ActionDelete, model.TypeLoginSession, nil, err) } @@ -1131,7 +1132,7 @@ func (a *Auth) applyLogin(anonymous bool, sub string, authType model.AuthType, a // update account usage information // TODO: Handle anonymous accounts if needed in the future if !anonymous { - err = a.storage.UpdateAccountUsageInfo(context, sub, true, true, clientVersion) + err = sa.UpdateAccountUsageInfo(sub, true, true, clientVersion) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeAccountUsageInfo, nil, err) } @@ -1215,11 +1216,11 @@ func (a *Auth) createLoginSession(anonymous bool, sub string, authType model.Aut return &loginSession, nil } -func (a *Auth) deleteLoginSession(context storage.TransactionContext, loginSession model.LoginSession, l *logs.Log) error { +func (a *Auth) deleteLoginSession(sa storage.Adapter, loginSession model.LoginSession, l *logs.Log) error { //always log what session has been deleted l.Info("deleting loging session - " + loginSession.LogInfo()) - err := a.storage.DeleteLoginSession(context, loginSession.ID) + err := sa.DeleteLoginSession(loginSession.ID) if err != nil { l.WarnAction(logutils.ActionDelete, model.TypeLoginSession, err) return err @@ -1227,7 +1228,7 @@ func (a *Auth) deleteLoginSession(context storage.TransactionContext, loginSessi return nil } -func (a *Auth) deleteLoginSessions(context storage.TransactionContext, loginSessions []model.LoginSession, l *logs.Log) error { +func (a *Auth) deleteLoginSessions(sa storage.Adapter, loginSessions []model.LoginSession, l *logs.Log) error { //always log what session has been deleted, also prepare the IDs ids := make([]string, len(loginSessions)) l.Info("expired sessions to be deleted:") @@ -1238,7 +1239,7 @@ func (a *Auth) deleteLoginSessions(context storage.TransactionContext, loginSess } //delete the sessions from the storage - err := a.storage.DeleteLoginSessionsByIDs(context, ids) + err := sa.DeleteLoginSessionsByIDs(ids) if err != nil { l.WarnAction(logutils.ActionDelete, model.TypeLoginSession, err) return err @@ -1387,7 +1388,7 @@ func (a *Auth) getProfileBBData(authType model.AuthType, identifier string, l *l // l (*logs.Log): Log object pointer for request // Returns: // Registered account (AccountAuthType): Registered Account object -func (a *Auth) registerUser(context storage.TransactionContext, authType model.AuthType, userIdentifier string, accountAuthTypeParams map[string]interface{}, +func (a *Auth) registerUser(sa storage.Adapter, authType model.AuthType, userIdentifier string, accountAuthTypeParams map[string]interface{}, appOrg model.ApplicationOrganization, credential *model.Credential, useSharedProfile bool, externalIDs map[string]string, profile model.Profile, preferences map[string]interface{}, username string, permissionNames []string, roleIDs []string, groupIDs []string, creatorPermissions []string, clientVersion *string, l *logs.Log) (*model.AccountAuthType, error) { @@ -1401,13 +1402,13 @@ func (a *Auth) registerUser(context storage.TransactionContext, authType model.A } } - accountAuthType, err := a.constructAccount(context, authType, userIdentifier, accountAuthTypeParams, appOrg, credential, + accountAuthType, err := a.constructAccount(sa, authType, userIdentifier, accountAuthTypeParams, appOrg, credential, unverified, externalIDs, profile, preferences, username, permissionNames, roleIDs, groupIDs, creatorPermissions, clientVersion, l) if err != nil { return nil, errors.WrapErrorAction("constructing", model.TypeAccount, nil, err) } - err = a.storeNewAccountInfo(context, accountAuthType.Account, credential, useSharedProfile, profile) + err = a.storeNewAccountInfo(sa, accountAuthType.Account, credential, useSharedProfile, profile) if err != nil { return nil, errors.WrapErrorAction("storing", "new account information", nil, err) } @@ -1415,7 +1416,7 @@ func (a *Auth) registerUser(context storage.TransactionContext, authType model.A return accountAuthType, nil } -func (a *Auth) constructAccount(context storage.TransactionContext, authType model.AuthType, userIdentifier string, accountAuthTypeParams map[string]interface{}, +func (a *Auth) constructAccount(sa storage.Adapter, authType model.AuthType, userIdentifier string, accountAuthTypeParams map[string]interface{}, appOrg model.ApplicationOrganization, credential *model.Credential, unverified bool, externalIDs map[string]string, profile model.Profile, preferences map[string]interface{}, username string, permissionNames []string, roleIDs []string, groupIDs []string, assignerPermissions []string, clientVersion *string, l *logs.Log) (*model.AccountAuthType, error) { //create account auth type @@ -1434,32 +1435,32 @@ func (a *Auth) constructAccount(context storage.TransactionContext, authType mod var roles []model.AppOrgRole var groups []model.AppOrgGroup if adminSet { - permissions, err = a.CheckPermissions(context, []model.ApplicationOrganization{appOrg}, permissionNames, assignerPermissions, false) + permissions, err = a.CheckPermissions(sa, []model.ApplicationOrganization{appOrg}, permissionNames, assignerPermissions, false) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionValidate, model.TypePermission, nil, err) } - roles, err = a.CheckRoles(context, &appOrg, roleIDs, assignerPermissions, false) + roles, err = a.CheckRoles(sa, &appOrg, roleIDs, assignerPermissions, false) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionValidate, model.TypeAppOrgRole, nil, err) } - groups, err = a.CheckGroups(context, &appOrg, groupIDs, assignerPermissions, false) + groups, err = a.CheckGroups(sa, &appOrg, groupIDs, assignerPermissions, false) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionGet, model.TypeAppOrgGroup, nil, err) } } else { - permissions, err = a.storage.FindPermissionsByName(context, permissionNames) + permissions, err = sa.FindPermissionsByName(permissionNames) if err != nil { l.WarnError(logutils.MessageAction(logutils.StatusError, logutils.ActionFind, model.TypePermission, nil), err) } - roles, err = a.storage.FindAppOrgRolesByIDs(context, roleIDs, appOrg.ID) + roles, err = sa.FindAppOrgRolesByIDs(roleIDs, appOrg.ID) if err != nil { l.WarnError(logutils.MessageAction(logutils.StatusError, logutils.ActionFind, model.TypeAppOrgRole, nil), err) } - groups, err = a.storage.FindAppOrgGroupsByIDs(context, groupIDs, appOrg.ID) + groups, err = sa.FindAppOrgGroupsByIDs(groupIDs, appOrg.ID) if err != nil { l.WarnError(logutils.MessageAction(logutils.StatusError, logutils.ActionFind, model.TypeAppOrgGroup, nil), err) } @@ -1473,9 +1474,9 @@ func (a *Auth) constructAccount(context storage.TransactionContext, authType mod return accountAuthType, nil } -func (a *Auth) storeNewAccountInfo(context storage.TransactionContext, account model.Account, credential *model.Credential, useSharedProfile bool, profile model.Profile) error { +func (a *Auth) storeNewAccountInfo(sa storage.Adapter, account model.Account, credential *model.Credential, useSharedProfile bool, profile model.Profile) error { //insert account object - it includes the account auth type - _, err := a.storage.InsertAccount(context, account) + _, err := sa.InsertAccount(account) if err != nil { return errors.WrapErrorAction(logutils.ActionInsert, model.TypeAccount, nil, err) } @@ -1484,13 +1485,13 @@ func (a *Auth) storeNewAccountInfo(context storage.TransactionContext, account m if credential != nil { if useSharedProfile { //update credential - err = a.storage.UpdateCredential(context, credential) + err = sa.UpdateCredential(credential) if err != nil { return errors.Wrapf("error updating a credential", err) } } else { //create credential - err = a.storage.InsertCredential(context, credential) + err = sa.InsertCredential(credential) if err != nil { return errors.Wrapf("error inserting a credential", err) } @@ -1499,7 +1500,7 @@ func (a *Auth) storeNewAccountInfo(context storage.TransactionContext, account m //update profile if shared if useSharedProfile { - err = a.storage.UpdateProfile(context, profile) + err = sa.UpdateProfile(profile) if err != nil { return errors.Wrapf("error updating profile on register", err) } @@ -1508,8 +1509,8 @@ func (a *Auth) storeNewAccountInfo(context storage.TransactionContext, account m return nil } -func (a *Auth) checkUsername(context storage.TransactionContext, appOrg *model.ApplicationOrganization, username string) error { - accounts, err := a.storage.FindAccountsByUsername(context, appOrg, username) +func (a *Auth) checkUsername(sa Storage, appOrg *model.ApplicationOrganization, username string) error { + accounts, err := sa.FindAccountsByUsername(appOrg, username) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) } @@ -1533,7 +1534,7 @@ func (a *Auth) linkAccountAuthType(account model.Account, authType model.AuthTyp } //2. check if the user exists - newCredsAccount, err := a.storage.FindAccount(nil, appOrg.ID, authType.ID, userIdentifier) + newCredsAccount, err := a.storage.FindAccount(appOrg.ID, authType.ID, userIdentifier) if err != nil { return "", nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) } @@ -1633,7 +1634,7 @@ func (a *Auth) linkAccountAuthTypeExternal(account model.Account, authType model } //2. check if the user exists - newCredsAccount, err := a.storage.FindAccount(nil, appOrg.ID, authType.ID, externalUser.Identifier) + newCredsAccount, err := a.storage.FindAccount(appOrg.ID, authType.ID, externalUser.Identifier) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) } @@ -1672,7 +1673,7 @@ func (a *Auth) registerAccountAuthType(accountAuthType model.AccountAuthType, cr var err error if credential != nil { //TODO - in one transaction - if err = a.storage.InsertCredential(nil, credential); err != nil { + if err = a.storage.InsertCredential(credential); err != nil { return errors.WrapErrorAction(logutils.ActionInsert, model.TypeCredential, nil, err) } } @@ -1698,7 +1699,7 @@ func (a *Auth) registerAccountAuthType(accountAuthType model.AccountAuthType, cr } func (a *Auth) unlinkAccountAuthType(accountID string, authenticationType string, appTypeIdentifier string, identifier string, l *logs.Log) (*model.Account, error) { - account, err := a.storage.FindAccountByID(nil, accountID) + account, err := a.storage.FindAccountByID(accountID) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) } @@ -1737,7 +1738,7 @@ func (a *Auth) handleAccountAuthTypeConflict(account model.Account, authTypeID s return errors.New("account already exists").SetStatus(utils.ErrorStatusAlreadyExists) } //if linked to a different unverified account, remove whole account - err := a.deleteAccount(nil, account) + err := a.deleteAccount(*a.storage.(*storage.Adapter), account) if err != nil { return errors.WrapErrorAction(logutils.ActionDelete, model.TypeAccount, nil, err) } @@ -1753,16 +1754,16 @@ func (a *Auth) handleAccountAuthTypeConflict(account model.Account, authTypeID s } func (a *Auth) removeAccountAuthType(aat model.AccountAuthType) error { - transaction := func(context storage.TransactionContext) error { + transaction := func(sa storage.Adapter) error { //1. delete account auth type in account - err := a.storage.DeleteAccountAuthType(context, aat) + err := sa.DeleteAccountAuthType(aat) if err != nil { return errors.WrapErrorAction(logutils.ActionDelete, model.TypeAccountAuthType, nil, err) } //2. delete credential if it exists if aat.Credential != nil { - err = a.removeAccountAuthTypeCredential(context, aat) + err = a.removeAccountAuthTypeCredential(sa, aat) if err != nil { return errors.WrapErrorAction(logutils.ActionDelete, model.TypeCredential, nil, err) } @@ -1770,7 +1771,7 @@ func (a *Auth) removeAccountAuthType(aat model.AccountAuthType) error { //3. delete login sessions using unlinked account auth type (if unverified no sessions should exist) if !aat.Unverified { - err = a.storage.DeleteLoginSessionsByAccountAuthTypeID(context, aat.ID) + err = sa.DeleteLoginSessionsByAccountAuthTypeID(aat.ID) if err != nil { return errors.WrapErrorAction(logutils.ActionDelete, model.TypeLoginSession, nil, err) } @@ -1782,8 +1783,8 @@ func (a *Auth) removeAccountAuthType(aat model.AccountAuthType) error { return a.storage.PerformTransaction(transaction) } -func (a *Auth) removeAccountAuthTypeCredential(context storage.TransactionContext, aat model.AccountAuthType) error { - credential, err := a.storage.FindCredential(context, aat.Credential.ID) +func (a *Auth) removeAccountAuthTypeCredential(sa storage.Adapter, aat model.AccountAuthType) error { + credential, err := sa.FindCredential(aat.Credential.ID) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeCredential, nil, err) } @@ -1794,7 +1795,7 @@ func (a *Auth) removeAccountAuthTypeCredential(context storage.TransactionContex if credAat.ID == aat.ID { credential.AccountsAuthTypes = append(credential.AccountsAuthTypes[:i], credential.AccountsAuthTypes[i+1:]...) credential.DateUpdated = &now - err = a.storage.UpdateCredential(context, credential) + err = sa.UpdateCredential(credential) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeCredential, nil, err) } @@ -1802,7 +1803,7 @@ func (a *Auth) removeAccountAuthTypeCredential(context storage.TransactionContex } } } else { - err = a.storage.DeleteCredential(context, credential.ID) + err = sa.DeleteCredential(credential.ID) if err != nil { return errors.WrapErrorAction(logutils.ActionDelete, model.TypeCredential, nil, err) } @@ -1811,9 +1812,9 @@ func (a *Auth) removeAccountAuthTypeCredential(context storage.TransactionContex return nil } -func (a *Auth) deleteAccount(context storage.TransactionContext, account model.Account) error { +func (a *Auth) deleteAccount(sa storage.Adapter, account model.Account) error { //1. delete the account record - err := a.storage.DeleteAccount(context, account.ID) + err := sa.DeleteAccount(account.ID) if err != nil { return errors.WrapErrorAction(logutils.ActionDelete, model.TypeAccount, nil, err) } @@ -1821,7 +1822,7 @@ func (a *Auth) deleteAccount(context storage.TransactionContext, account model.A //2. remove account auth types from or delete credentials for _, aat := range account.AuthTypes { if aat.Credential != nil { - err = a.removeAccountAuthTypeCredential(context, aat) + err = a.removeAccountAuthTypeCredential(sa, aat) if err != nil { return errors.WrapErrorAction(logutils.ActionDelete, model.TypeCredential, nil, err) } @@ -1829,14 +1830,14 @@ func (a *Auth) deleteAccount(context storage.TransactionContext, account model.A } //3. delete login sessions - err = a.storage.DeleteLoginSessionsByIdentifier(context, account.ID) + err = sa.DeleteLoginSessionsByIdentifier(account.ID) if err != nil { return errors.WrapErrorAction(logutils.ActionDelete, model.TypeLoginSession, nil, err) } //4. delete devices records for _, device := range account.Devices { - err = a.storage.DeleteDevice(context, device.ID) + err = sa.DeleteDevice(device.ID) if err != nil { return errors.WrapErrorAction(logutils.ActionDelete, model.TypeDevice, nil, err) } @@ -1846,7 +1847,7 @@ func (a *Auth) deleteAccount(context storage.TransactionContext, account model.A } func (a *Auth) constructServiceAccount(accountID string, name string, appID string, orgID string, permissions []string, scopes []authorization.Scope, firstParty bool, assignerPermissions []string) (*model.ServiceAccount, error) { - permissionList, err := a.storage.FindPermissionsByName(nil, permissions) + permissionList, err := a.storage.FindPermissionsByName(permissions) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypePermission, nil, err) } @@ -1859,7 +1860,7 @@ func (a *Auth) constructServiceAccount(accountID string, name string, appID stri var application *model.Application if appID != authutils.AllApps { - application, err = a.storage.FindApplication(nil, appID) + application, err = a.storage.FindApplication(appID) if err != nil || application == nil { return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeApplication, nil, err) } @@ -2233,7 +2234,7 @@ func (a *Auth) updateExternalAccountRoles(account *model.Account, newExternalRol } } - addedRoles, err := a.storage.FindAppOrgRolesByIDs(nil, addedRoleIDs, account.AppOrg.ID) + addedRoles, err := a.storage.FindAppOrgRolesByIDs(addedRoleIDs, account.AppOrg.ID) if err != nil { return false, errors.WrapErrorAction(logutils.ActionFind, model.TypeAccountRoles, nil, err) } @@ -2267,7 +2268,7 @@ func (a *Auth) updateExternalAccountGroups(account *model.Account, newExternalGr } } - addedGroups, err := a.storage.FindAppOrgGroupsByIDs(nil, addedGroupIDs, account.AppOrg.ID) + addedGroups, err := a.storage.FindAppOrgGroupsByIDs(addedGroupIDs, account.AppOrg.ID) if err != nil { return false, errors.WrapErrorAction(logutils.ActionFind, model.TypeAccountGroups, nil, err) } @@ -2545,7 +2546,7 @@ func (a *Auth) deleteExpiredSessions() { } //delete the sessions from the storage - err = a.storage.DeleteLoginSessionsByIDs(nil, ids) + err = a.storage.DeleteLoginSessionsByIDs(ids) if err != nil { a.logger.Errorf("error on deleting logins sessions - %s", err) } diff --git a/core/auth/auth_type_email.go b/core/auth/auth_type_email.go index c1cfbbe26..befd49c84 100644 --- a/core/auth/auth_type_email.go +++ b/core/auth/auth_type_email.go @@ -327,7 +327,7 @@ func (a *emailAuthImpl) sendVerifyCredential(credential *model.Credential, appNa } credential.Value = credsMap - if err = a.auth.storage.UpdateCredential(nil, credential); err != nil { + if err = a.auth.storage.UpdateCredential(credential); err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeCredential, nil, err) } diff --git a/core/auth/interfaces.go b/core/auth/interfaces.go index 4c0601c61..40ac387dd 100644 --- a/core/auth/interfaces.go +++ b/core/auth/interfaces.go @@ -19,9 +19,7 @@ import ( "core-building-block/driven/storage" "time" - "github.com/rokwire/core-auth-library-go/v2/authorization" "github.com/rokwire/core-auth-library-go/v2/sigauth" - "github.com/rokwire/core-auth-library-go/v2/tokenauth" "github.com/rokwire/logging-library-go/logs" ) @@ -100,495 +98,9 @@ type serviceAuthType interface { // mfaType is the interface for multi-factor authentication type mfaType interface { //verify verifies the code based on stored mfa params - verify(context storage.TransactionContext, mfa *model.MFAType, accountID string, code string) (*string, error) + verify(sa storage.Adapter, mfa *model.MFAType, accountID string, code string) (*string, error) //enroll creates a mfa type to be added to an account enroll(identifier string) (*model.MFAType, error) //sendCode generates a mfa code and expiration time and sends the code to the user sendCode(identifier string) (string, *time.Time, error) } - -// APIs is the interface which defines the APIs provided by the auth package -type APIs interface { - //Start starts the auth service - Start() - - //GetHost returns the host/issuer of the auth service - GetHost() string - - //Login logs a user in a specific application using the specified credentials and authentication method. - //The authentication method must be one of the supported for the application. - // Input: - // ipAddress (string): Client's IP address - // deviceType (string): "mobile" or "web" or "desktop" etc - // deviceOS (*string): Device OS - // deviceID (string): Device ID - // authenticationType (string): Name of the authentication method for provided creds (eg. "email", "username", "illinois_oidc") - // creds (string): Credentials/JSON encoded credential structure defined for the specified auth type - // apiKey (string): API key to validate the specified app - // appTypeIdentifier (string): identifier of the app type/client that the user is logging in from - // orgID (string): ID of the organization that the user is logging in - // params (string): JSON encoded params defined by specified auth type - // clientVersion(*string): Most recent client version - // profile (Profile): Account profile - // preferences (map): Account preferences - // admin (bool): Is this an admin login? - // l (*logs.Log): Log object pointer for request - // Returns: - // Message (*string): message - // Login session (*LoginSession): Signed ROKWIRE access token to be used to authorize future requests - // Access token (string): Signed ROKWIRE access token to be used to authorize future requests - // Refresh Token (string): Refresh token that can be sent to refresh the access token once it expires - // AccountAuthType (AccountAuthType): AccountAuthType object for authenticated user - // Params (interface{}): authType-specific set of parameters passed back to client - // State (string): login state used if account is enrolled in MFA - // MFA types ([]model.MFAType): list of MFA types account is enrolled in - Login(ipAddress string, deviceType string, deviceOS *string, deviceID string, authenticationType string, creds string, apiKey string, - appTypeIdentifier string, orgID string, params string, clientVersion *string, profile model.Profile, preferences map[string]interface{}, - username string, admin bool, l *logs.Log) (*string, *model.LoginSession, []model.MFAType, error) - - //Logout logouts an account from app/org - // Input: - // allSessions (bool): If to remove the current session only or all sessions for the app/org for the account - Logout(appID string, orgID string, currentAccountID string, sessionID string, allSessions bool, l *logs.Log) error - - //AccountExists checks if a user is already registered - //The authentication method must be one of the supported for the application. - // Input: - // authenticationType (string): Name of the authentication method for provided creds (eg. "email", "username", "illinois_oidc") - // userIdentifier (string): User identifier for the specified auth type - // apiKey (string): API key to validate the specified app - // appTypeIdentifier (string): identifier of the app type/client that the user is logging in from - // orgID (string): ID of the organization that the user is logging in - // Returns: - // accountExisted (bool): valid when error is nil - AccountExists(authenticationType string, userIdentifier string, apiKey string, appTypeIdentifier string, orgID string) (bool, error) - - //CanSignIn checks if a user can sign in - //The authentication method must be one of the supported for the application. - // Input: - // authenticationType (string): Name of the authentication method for provided creds (eg. "email", "username", "illinois_oidc") - // userIdentifier (string): User identifier for the specified auth type - // apiKey (string): API key to validate the specified app - // appTypeIdentifier (string): identifier of the app type/client being used - // orgID (string): ID of the organization being used - // Returns: - // canSignIn (bool): valid when error is nil - CanSignIn(authenticationType string, userIdentifier string, apiKey string, appTypeIdentifier string, orgID string) (bool, error) - - //CanLink checks if a user can link a new auth type - //The authentication method must be one of the supported for the application. - // Input: - // authenticationType (string): Name of the authentication method for provided creds (eg. "email", "username", "illinois_oidc") - // userIdentifier (string): User identifier for the specified auth type - // apiKey (string): API key to validate the specified app - // appTypeIdentifier (string): identifier of the app type/client being used - // orgID (string): ID of the organization being used - // Returns: - // canLink (bool): valid when error is nil - CanLink(authenticationType string, userIdentifier string, apiKey string, appTypeIdentifier string, orgID string) (bool, error) - - //Refresh refreshes an access token using a refresh token - // Input: - // refreshToken (string): Refresh token - // apiKey (string): API key to validate the specified app - // clientVersion(*string): Most recent client version - // l (*logs.Log): Log object pointer for request - // Returns: - // Login session (*LoginSession): Signed ROKWIRE access token to be used to authorize future requests - // Access token (string): Signed ROKWIRE access token to be used to authorize future requests - // Refresh Token (string): Refresh token that can be sent to refresh the access token once it expires - // Params (interface{}): authType-specific set of parameters passed back to client - Refresh(refreshToken string, apiKey string, clientVersion *string, l *logs.Log) (*model.LoginSession, error) - - //GetLoginURL returns a pre-formatted login url for SSO providers - // Input: - // authType (string): Name of the authentication method for provided creds (eg. "email", "username", "illinois_oidc") - // appTypeIdentifier (string): Identifier of the app type/client that the user is logging in from - // orgID (string): ID of the organization that the user is logging in - // redirectURI (string): Registered redirect URI where client will receive response - // apiKey (string): API key to validate the specified app - // l (*loglib.Log): Log object pointer for request - // Returns: - // Login URL (string): SSO provider login URL to be launched in a browser - // Params (map[string]interface{}): Params to be sent in subsequent request (if necessary) - GetLoginURL(authType string, appTypeIdentifier string, orgID string, redirectURI string, apiKey string, l *logs.Log) (string, map[string]interface{}, error) - - //LoginMFA verifies a code sent by a user as a final login step for enrolled accounts. - //The MFA type must be one of the supported for the application. - // Input: - // apiKey (string): API key to validate the specified app - // accountID (string): ID of account user is trying to access - // sessionID (string): ID of login session generated during login - // identifier (string): Email, phone, or TOTP device name - // mfaType (string): Type of MFA code sent - // mfaCode (string): Code that must be verified - // state (string): Variable used to verify user has already passed credentials check - // l (*logs.Log): Log object pointer for request - // Returns: - // Message (*string): message - // Login session (*LoginSession): Signed ROKWIRE access token to be used to authorize future requests - // Access token (string): Signed ROKWIRE access token to be used to authorize future requests - // Refresh Token (string): Refresh token that can be sent to refresh the access token once it expires - // AccountAuthType (AccountAuthType): AccountAuthType object for authenticated user - LoginMFA(apiKey string, accountID string, sessionID string, identifier string, mfaType string, mfaCode string, state string, l *logs.Log) (*string, *model.LoginSession, error) - - //CreateAdminAccount creates an account for a new admin user - CreateAdminAccount(authenticationType string, appID string, orgID string, identifier string, profile model.Profile, username string, permissions []string, - roleIDs []string, groupIDs []string, creatorPermissions []string, clientVersion *string, l *logs.Log) (*model.Account, map[string]interface{}, error) - - //UpdateAdminAccount updates an existing user's account with new permissions, roles, and groups - UpdateAdminAccount(authenticationType string, appID string, orgID string, identifier string, permissions []string, roleIDs []string, - groupIDs []string, updaterPermissions []string, l *logs.Log) (*model.Account, map[string]interface{}, error) - - //CreateAnonymousAccount creates a new anonymous account - CreateAnonymousAccount(context storage.TransactionContext, appID string, orgID string, anonymousID string, preferences map[string]interface{}, - systemConfigs map[string]interface{}, skipExistsCheck bool, l *logs.Log) (*model.Account, error) - - //VerifyCredential verifies credential (checks the verification code in the credentials collection) - VerifyCredential(id string, verification string, l *logs.Log) error - - //SendVerifyCredential sends verification code to identifier - SendVerifyCredential(authenticationType string, appTypeIdentifier string, orgID string, apiKey string, identifier string, l *logs.Log) error - - //UpdateCredential updates the credential object with the new value - // Input: - // accountID: id of the associated account to reset - // accountAuthTypeID (string): id of the AccountAuthType - // params: specific params for the different auth types - // Returns: - // error: if any - UpdateCredential(accountID string, accountAuthTypeID string, params string, l *logs.Log) error - - //ForgotCredential initiate forgot credential process (generates a reset link and sends to the given identifier for email auth type) - // Input: - // authenticationType (string): Name of the authentication method for provided creds (eg. "email", "username", "illinois_oidc") - // identifier: identifier of the account auth type - // appTypeIdentifier (string): Identifier of the app type/client that the user is logging in from - // orgID (string): ID of the organization that the user is logging in - // apiKey (string): API key to validate the specified app - // Returns: - // error: if any - ForgotCredential(authenticationType string, appTypeIdentifier string, orgID string, apiKey string, identifier string, l *logs.Log) error - - //ResetForgotCredential resets forgot credential - // Input: - // credsID: id of the credential object - // resetCode: code from the reset link - // params: specific params for the different auth types - // Returns: - // error: if any - ResetForgotCredential(credsID string, resetCode string, params string, l *logs.Log) error - - //VerifyMFA verifies a code sent by a user as a final MFA enrollment step. - //The MFA type must be one of the supported for the application. - // Input: - // accountID (string): ID of account for which user is trying to verify MFA - // identifier (string): Email, phone, or TOTP device name - // mfaType (string): Type of MFA code sent - // mfaCode (string): Code that must be verified - // Returns: - // Message (*string): message - // Recovery codes ([]string): List of account recovery codes returned if enrolling in MFA for first time - VerifyMFA(accountID string, identifier string, mfaType string, mfaCode string) (*string, []string, error) - - //GetMFATypes gets all MFA types set up for an account - // Input: - // accountID (string): Account ID to find MFA types - // Returns: - // MFA Types ([]model.MFAType): MFA information for all enrolled types - GetMFATypes(accountID string) ([]model.MFAType, error) - - //AddMFAType adds a form of MFA to an account - // Input: - // accountID (string): Account ID to add MFA - // identifier (string): Email, phone, or TOTP device name - // mfaType (string): Type of MFA to be added - // Returns: - // MFA Type (*model.MFAType): MFA information for the specified type - AddMFAType(accountID string, identifier string, mfaType string) (*model.MFAType, error) - - //RemoveMFAType removes a form of MFA from an account - // Input: - // accountID (string): Account ID to remove MFA - // identifier (string): Email, phone, or TOTP device name - // mfaType (string): Type of MFA to remove - RemoveMFAType(accountID string, identifier string, mfaType string) error - - //GetServiceAccountParams returns a list of app, org pairs a service account has access to - GetServiceAccountParams(accountID string, firstParty bool, r *sigauth.Request, l *logs.Log) ([]model.AppOrgPair, error) - - //GetServiceAccessToken returns an access token for a non-human client - GetServiceAccessToken(firstParty bool, r *sigauth.Request, l *logs.Log) (string, error) - - //GetAllServiceAccessTokens returns an access token for each app, org pair a service account has access to - GetAllServiceAccessTokens(firstParty bool, r *sigauth.Request, l *logs.Log) (map[model.AppOrgPair]string, error) - - //GetServiceAccounts gets all service accounts matching a search - GetServiceAccounts(params map[string]interface{}) ([]model.ServiceAccount, error) - - //RegisterServiceAccount registers a service account - RegisterServiceAccount(accountID *string, fromAppID *string, fromOrgID *string, name *string, appID string, orgID string, permissions *[]string, scopes []authorization.Scope, - firstParty *bool, creds []model.ServiceAccountCredential, assignerPermissions []string, l *logs.Log) (*model.ServiceAccount, error) - - //DeregisterServiceAccount deregisters a service account - DeregisterServiceAccount(accountID string) error - - //GetServiceAccountInstance gets a service account instance - GetServiceAccountInstance(accountID string, appID string, orgID string) (*model.ServiceAccount, error) - - //UpdateServiceAccountInstance updates a service account instance - UpdateServiceAccountInstance(id string, appID string, orgID string, name *string, permissions *[]string, scopes []authorization.Scope, assignerPermissions []string) (*model.ServiceAccount, error) - - //DeregisterServiceAccountInstance deregisters a service account instance - DeregisterServiceAccountInstance(id string, appID string, orgID string) error - - //AddServiceAccountCredential adds a credential to a service account - AddServiceAccountCredential(accountID string, creds *model.ServiceAccountCredential, l *logs.Log) (*model.ServiceAccountCredential, error) - - //RemoveServiceAccountCredential removes a credential from a service account - RemoveServiceAccountCredential(accountID string, credID string) error - - //AuthorizeService returns a scoped token for the specified service and the service registration record if authorized or - // the service registration record if not. Passing "approvedScopes" will update the service authorization for this user and - // return a scoped access token which reflects this change. - // Input: - // claims (tokenauth.Claims): Claims from un-scoped user access token - // serviceID (string): ID of the service to be authorized - // approvedScopes ([]string): list of scope strings to be approved - // l (*logs.Log): Log object pointer for request - // Returns: - // Access token (string): Signed scoped access token to be used to authorize requests to the specified service - // Approved Scopes ([]authorization.Scope): The approved scopes included in the provided token - // Service reg (*model.ServiceReg): The service registration record for the requested service - AuthorizeService(claims tokenauth.Claims, serviceID string, approvedScopes []authorization.Scope, l *logs.Log) (string, []authorization.Scope, *model.ServiceReg, error) - - //LinkAccountAuthType links new credentials to an existing account. - //The authentication method must be one of the supported for the application. - // Input: - // accountID (string): ID of the account to link the creds to - // authenticationType (string): Name of the authentication method for provided creds (eg. "email", "username", "illinois_oidc") - // appTypeIdentifier (string): identifier of the app type/client that the user is logging in from - // creds (string): Credentials/JSON encoded credential structure defined for the specified auth type - // params (string): JSON encoded params defined by specified auth type - // l (*logs.Log): Log object pointer for request - // Returns: - // message (*string): response message - // account (*model.Account): account data after the operation - LinkAccountAuthType(accountID string, authenticationType string, appTypeIdentifier string, creds string, params string, l *logs.Log) (*string, *model.Account, error) - - //UnlinkAccountAuthType unlinks credentials from an existing account. - //The authentication method must be one of the supported for the application. - // Input: - // accountID (string): ID of the account to unlink creds from - // authenticationType (string): Name of the authentication method of account auth type to unlink - // appTypeIdentifier (string): Identifier of the app type/client that the user is logging in from - // identifier (string): Identifier of account auth type to unlink - // l (*logs.Log): Log object pointer for request - // Returns: - // account (*model.Account): account data after the operation - UnlinkAccountAuthType(accountID string, authenticationType string, appTypeIdentifier string, identifier string, l *logs.Log) (*model.Account, error) - - //InitializeSystemAccount initializes the first system account - InitializeSystemAccount(context storage.TransactionContext, authType model.AuthType, appOrg model.ApplicationOrganization, allSystemPermission string, email string, password string, clientVersion string, l *logs.Log) (string, error) - - //GrantAccountPermissions grants new permissions to an account after validating the assigner has required permissions - GrantAccountPermissions(context storage.TransactionContext, account *model.Account, permissionNames []string, assignerPermissions []string) error - - //CheckPermissions loads permissions by names from storage and checks that they are assignable and valid for the given appOrgs or revocable - CheckPermissions(context storage.TransactionContext, appOrgs []model.ApplicationOrganization, permissionNames []string, assignerPermissions []string, revoke bool) ([]model.Permission, error) - - //GrantAccountRoles grants new roles to an account after validating the assigner has required permissions - GrantAccountRoles(context storage.TransactionContext, account *model.Account, roleIDs []string, assignerPermissions []string) error - - //CheckRoles loads appOrg roles by IDs from storage and checks that they are assignable or revocable - CheckRoles(context storage.TransactionContext, appOrg *model.ApplicationOrganization, roleIDs []string, assignerPermissions []string, revoke bool) ([]model.AppOrgRole, error) - - //GrantAccountGroups grants new groups to an account after validating the assigner has required permissions - GrantAccountGroups(context storage.TransactionContext, account *model.Account, groupIDs []string, assignerPermissions []string) error - - //CheckGroups loads appOrg groups by IDs from storage and checks that they are assignable or revocable - CheckGroups(context storage.TransactionContext, appOrg *model.ApplicationOrganization, groupIDs []string, assignerPermissions []string, revoke bool) ([]model.AppOrgGroup, error) - - //DeleteAccount deletes an account for the given id - DeleteAccount(id string) error - - //GetAdminToken returns an admin token for the specified application and organization - GetAdminToken(claims tokenauth.Claims, appID string, orgID string, l *logs.Log) (string, error) - - //GetAuthKeySet generates a JSON Web Key Set for auth service registration - GetAuthKeySet() (*model.JSONWebKeySet, error) - - //GetServiceRegistrations retrieves all service registrations - GetServiceRegistrations(serviceIDs []string) []model.ServiceReg - - //RegisterService creates a new service registration - RegisterService(reg *model.ServiceReg) error - - //UpdateServiceRegistration updates an existing service registration - UpdateServiceRegistration(reg *model.ServiceReg) error - - //DeregisterService deletes an existing service registration - DeregisterService(serviceID string) error - - //GetApplicationAPIKeys finds and returns the API keys for an application - GetApplicationAPIKeys(appID string) ([]model.APIKey, error) - - //GetAPIKey finds and returns an API key - GetAPIKey(ID string) (*model.APIKey, error) - - //CreateAPIKey creates a new API key - CreateAPIKey(apiKey model.APIKey) (*model.APIKey, error) - - //UpdateAPIKey updates an existing API key - UpdateAPIKey(apiKey model.APIKey) error - - //DeleteAPIKey deletes an API key - DeleteAPIKey(ID string) error - - //ValidateAPIKey validates the given API key for the given app ID - ValidateAPIKey(appID string, apiKey string) error -} - -// Storage interface to communicate with the storage -type Storage interface { - RegisterStorageListener(storageListener storage.Listener) - - PerformTransaction(func(context storage.TransactionContext) error) error - - //AuthTypes - FindAuthType(codeOrID string) (*model.AuthType, error) - - //LoginsSessions - InsertLoginSession(context storage.TransactionContext, session model.LoginSession) error - FindLoginSessions(context storage.TransactionContext, identifier string) ([]model.LoginSession, error) - FindLoginSession(refreshToken string) (*model.LoginSession, error) - FindAndUpdateLoginSession(context storage.TransactionContext, id string) (*model.LoginSession, error) - UpdateLoginSession(context storage.TransactionContext, loginSession model.LoginSession) error - DeleteLoginSession(context storage.TransactionContext, id string) error - DeleteLoginSessionsByIDs(context storage.TransactionContext, ids []string) error - DeleteLoginSessionsByAccountAuthTypeID(context storage.TransactionContext, id string) error - DeleteLoginSessionsByIdentifier(context storage.TransactionContext, identifier string) error - - //LoginsSessions - predefined queries for manage deletion logic - DeleteMFAExpiredSessions() error - FindSessionsLazy(appID string, orgID string) ([]model.LoginSession, error) - /// - - //Accounts - FindAccount(context storage.TransactionContext, appOrgID string, authTypeID string, accountAuthTypeIdentifier string) (*model.Account, error) - FindAccountByID(context storage.TransactionContext, id string) (*model.Account, error) - FindAccountsByUsername(context storage.TransactionContext, appOrg *model.ApplicationOrganization, username string) ([]model.Account, error) - InsertAccount(context storage.TransactionContext, account model.Account) (*model.Account, error) - SaveAccount(context storage.TransactionContext, account *model.Account) error - DeleteAccount(context storage.TransactionContext, id string) error - UpdateAccountUsageInfo(context storage.TransactionContext, accountID string, updateLoginTime bool, updateAccessTokenTime bool, clientVersion *string) error - - //Profiles - UpdateProfile(context storage.TransactionContext, profile model.Profile) error - FindProfiles(appID string, authTypeID string, accountAuthTypeIdentifier string) ([]model.Profile, error) - - //ServiceAccounts - FindServiceAccount(context storage.TransactionContext, accountID string, appID string, orgID string) (*model.ServiceAccount, error) - FindServiceAccounts(params map[string]interface{}) ([]model.ServiceAccount, error) - InsertServiceAccount(account *model.ServiceAccount) error - UpdateServiceAccount(context storage.TransactionContext, account *model.ServiceAccount) (*model.ServiceAccount, error) - DeleteServiceAccount(accountID string, appID string, orgID string) error - DeleteServiceAccounts(accountID string) error - - //ServiceAccountCredentials - InsertServiceAccountCredential(accountID string, creds *model.ServiceAccountCredential) error - DeleteServiceAccountCredential(accountID string, credID string) error - - //AccountAuthTypes - FindAccountByAuthTypeID(context storage.TransactionContext, id string) (*model.Account, error) - InsertAccountAuthType(item model.AccountAuthType) error - UpdateAccountAuthType(item model.AccountAuthType) error - DeleteAccountAuthType(context storage.TransactionContext, item model.AccountAuthType) error - - //ExternalIDs - UpdateAccountExternalIDs(accountID string, externalIDs map[string]string) error - UpdateLoginSessionExternalIDs(accountID string, externalIDs map[string]string) error - - //Applications - FindApplication(context storage.TransactionContext, ID string) (*model.Application, error) - - //Organizations - FindOrganization(id string) (*model.Organization, error) - - //Credentials - InsertCredential(context storage.TransactionContext, creds *model.Credential) error - FindCredential(context storage.TransactionContext, ID string) (*model.Credential, error) - UpdateCredential(context storage.TransactionContext, creds *model.Credential) error - UpdateCredentialValue(ID string, value map[string]interface{}) error - DeleteCredential(context storage.TransactionContext, ID string) error - - //MFA - FindMFAType(context storage.TransactionContext, accountID string, identifier string, mfaType string) (*model.MFAType, error) - FindMFATypes(accountID string) ([]model.MFAType, error) - InsertMFAType(context storage.TransactionContext, mfa *model.MFAType, accountID string) error - UpdateMFAType(context storage.TransactionContext, mfa *model.MFAType, accountID string) error - DeleteMFAType(context storage.TransactionContext, accountID string, identifier string, mfaType string) error - - //ServiceRegs - FindServiceRegs(serviceIDs []string) []model.ServiceReg - FindServiceReg(serviceID string) (*model.ServiceReg, error) - InsertServiceReg(reg *model.ServiceReg) error - UpdateServiceReg(reg *model.ServiceReg) error - SaveServiceReg(reg *model.ServiceReg) error - DeleteServiceReg(serviceID string) error - - //IdentityProviders - LoadIdentityProviders() ([]model.IdentityProvider, error) - - //ServiceAuthorizations - FindServiceAuthorization(userID string, orgID string) (*model.ServiceAuthorization, error) - SaveServiceAuthorization(authorization *model.ServiceAuthorization) error - DeleteServiceAuthorization(userID string, orgID string) error - - //APIKeys - LoadAPIKeys() ([]model.APIKey, error) - InsertAPIKey(context storage.TransactionContext, apiKey model.APIKey) (*model.APIKey, error) - UpdateAPIKey(apiKey model.APIKey) error - DeleteAPIKey(ID string) error - - //ApplicationTypes - FindApplicationType(id string) (*model.ApplicationType, error) - - //ApplicationsOrganizations - FindApplicationsOrganizations() ([]model.ApplicationOrganization, error) - FindApplicationOrganizations(appID *string, orgID *string) ([]model.ApplicationOrganization, error) - FindApplicationOrganization(appID string, orgID string) (*model.ApplicationOrganization, error) - - //Device - FindDevice(context storage.TransactionContext, deviceID string, accountID string) (*model.Device, error) - InsertDevice(context storage.TransactionContext, device model.Device) (*model.Device, error) - DeleteDevice(context storage.TransactionContext, id string) error - - //Permissions - FindPermissions(context storage.TransactionContext, ids []string) ([]model.Permission, error) - FindPermissionsByName(context storage.TransactionContext, names []string) ([]model.Permission, error) - InsertAccountPermissions(context storage.TransactionContext, accountID string, permissions []model.Permission) error - UpdateAccountPermissions(context storage.TransactionContext, accountID string, permissions []model.Permission) error - - //ApplicationRoles - FindAppOrgRolesByIDs(context storage.TransactionContext, ids []string, appOrgID string) ([]model.AppOrgRole, error) - //AccountRoles - UpdateAccountRoles(context storage.TransactionContext, accountID string, roles []model.AccountRole) error - InsertAccountRoles(context storage.TransactionContext, accountID string, appOrgID string, roles []model.AccountRole) error - - //ApplicationGroups - FindAppOrgGroupsByIDs(context storage.TransactionContext, ids []string, appOrgID string) ([]model.AppOrgGroup, error) - //AccountGroups - UpdateAccountGroups(context storage.TransactionContext, accountID string, groups []model.AccountGroup) error - InsertAccountGroups(context storage.TransactionContext, accountID string, appOrgID string, groups []model.AccountGroup) error -} - -// ProfileBuildingBlock is used by auth to communicate with the profile building block. -type ProfileBuildingBlock interface { - GetProfileBBData(queryParams map[string]string, l *logs.Log) (*model.Profile, map[string]interface{}, error) -} - -// Emailer is used by core to send emails -type Emailer interface { - Send(toEmail string, subject string, body string, attachmentFilename *string) error -} diff --git a/core/auth/mfa_email.go b/core/auth/mfa_email.go index bbb03dce6..9f46300a9 100644 --- a/core/auth/mfa_email.go +++ b/core/auth/mfa_email.go @@ -37,7 +37,7 @@ type emailMfaImpl struct { mfaType string } -func (m *emailMfaImpl) verify(context storage.TransactionContext, mfa *model.MFAType, accountID string, code string) (*string, error) { +func (m *emailMfaImpl) verify(sa storage.Adapter, mfa *model.MFAType, accountID string, code string) (*string, error) { if mfa == nil || mfa.Params == nil { return nil, errors.ErrorData(logutils.StatusMissing, "mfa params", nil) } @@ -65,7 +65,7 @@ func (m *emailMfaImpl) verify(context storage.TransactionContext, mfa *model.MFA //remove code and expiration from params in storage delete(mfa.Params, "code") delete(mfa.Params, "expires") - err := m.auth.storage.UpdateMFAType(context, mfa, accountID) + err := sa.UpdateMFAType(mfa, accountID) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionUpdate, model.TypeMFAType, nil, err) } diff --git a/core/auth/mfa_phone.go b/core/auth/mfa_phone.go index deae323ee..f7c5c654f 100644 --- a/core/auth/mfa_phone.go +++ b/core/auth/mfa_phone.go @@ -37,7 +37,7 @@ type phoneMfaImpl struct { mfaType string } -func (m *phoneMfaImpl) verify(context storage.TransactionContext, mfa *model.MFAType, accountID string, code string) (*string, error) { +func (m *phoneMfaImpl) verify(sa storage.Adapter, mfa *model.MFAType, accountID string, code string) (*string, error) { if mfa == nil || mfa.Params == nil { return nil, errors.ErrorData(logutils.StatusMissing, "mfa params", nil) } @@ -65,7 +65,7 @@ func (m *phoneMfaImpl) verify(context storage.TransactionContext, mfa *model.MFA //remove code and expiration from params in storage delete(mfa.Params, "code") delete(mfa.Params, "expires") - err := m.auth.storage.UpdateMFAType(context, mfa, accountID) + err := sa.UpdateMFAType(mfa, accountID) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionUpdate, model.TypeMFAType, nil, err) } diff --git a/core/auth/mfa_recovery.go b/core/auth/mfa_recovery.go index 03aa76de3..afd0cc402 100644 --- a/core/auth/mfa_recovery.go +++ b/core/auth/mfa_recovery.go @@ -40,7 +40,7 @@ type recoveryMfaImpl struct { mfaType string } -func (m *recoveryMfaImpl) verify(context storage.TransactionContext, mfa *model.MFAType, accountID string, code string) (*string, error) { +func (m *recoveryMfaImpl) verify(sa storage.Adapter, mfa *model.MFAType, accountID string, code string) (*string, error) { if mfa == nil || mfa.Params == nil { return nil, errors.ErrorData(logutils.StatusMissing, "mfa params", nil) } @@ -66,7 +66,7 @@ func (m *recoveryMfaImpl) verify(context storage.TransactionContext, mfa *model. now := time.Now().UTC() mfa.DateUpdated = &now - err := m.auth.storage.UpdateMFAType(context, mfa, accountID) + err := sa.UpdateMFAType(mfa, accountID) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionUpdate, model.TypeMFAType, &logutils.FieldArgs{"account_id": accountID, "id": mfa.ID}, err) } diff --git a/core/auth/mfa_totp.go b/core/auth/mfa_totp.go index 5bffca23c..803f60cc8 100644 --- a/core/auth/mfa_totp.go +++ b/core/auth/mfa_totp.go @@ -38,7 +38,7 @@ type totpMfaImpl struct { mfaType string } -func (m *totpMfaImpl) verify(context storage.TransactionContext, mfa *model.MFAType, accountID string, code string) (*string, error) { +func (m *totpMfaImpl) verify(sa storage.Adapter, mfa *model.MFAType, accountID string, code string) (*string, error) { if mfa == nil || mfa.Params == nil { return nil, errors.ErrorData(logutils.StatusMissing, "mfa params", nil) } diff --git a/core/interfaces.go b/core/interfaces.go index 7105be281..0ba9ebf33 100644 --- a/core/interfaces.go +++ b/core/interfaces.go @@ -15,228 +15,9 @@ package core import ( - "core-building-block/core/model" "core-building-block/driven/storage" - - "github.com/rokwire/logging-library-go/logs" ) -// Services exposes APIs for the driver adapters -type Services interface { - SerDeleteAccount(id string) error - SerGetAccount(accountID string) (*model.Account, error) - SerGetProfile(accountID string) (*model.Profile, error) - SerGetPreferences(accountID string) (map[string]interface{}, error) - SerGetAccountSystemConfigs(accountID string) (map[string]interface{}, error) - SerUpdateAccountPreferences(id string, appID string, orgID string, anonymous bool, preferences map[string]interface{}, l *logs.Log) (bool, error) - SerUpdateProfile(accountID string, profile model.Profile) error - SerUpdateAccountUsername(accountID string, appID string, orgID string, username string) error - - SerGetAccounts(limit int, offset int, appID string, orgID string, accountID *string, firstName *string, lastName *string, authType *string, - authTypeIdentifier *string, anonymous *bool, hasPermissions *bool, permissions []string, roleIDs []string, groupIDs []string) ([]model.Account, error) - - SerGetAuthTest(l *logs.Log) string - SerGetCommonTest(l *logs.Log) string - - SerGetAppConfig(appTypeIdentifier string, orgID *string, versionNumbers model.VersionNumbers, apiKey *string) (*model.ApplicationConfig, error) -} - -// Administration exposes administration APIs for the driver adapters -type Administration interface { - AdmGetTest() string - AdmGetTestModel() string - - AdmGetApplications(orgID string) ([]model.Application, error) - - AdmCreateAppOrgGroup(name string, description string, system bool, permissionNames []string, rolesIDs []string, accountIDs []string, appID string, orgID string, assignerPermissions []string, systemClaim bool, l *logs.Log) (*model.AppOrgGroup, error) - AdmUpdateAppOrgGroup(ID string, name string, description string, system bool, permissionNames []string, rolesIDs []string, accountIDs []string, appID string, orgID string, assignerPermissions []string, systemClaim bool, l *logs.Log) (*model.AppOrgGroup, error) - AdmGetAppOrgGroups(appID string, orgID string) ([]model.AppOrgGroup, error) - AdmAddAccountsToGroup(appID string, orgID string, groupID string, accountIDs []string, assignerPermissions []string, l *logs.Log) error - AdmRemoveAccountsFromGroup(appID string, orgID string, groupID string, accountIDs []string, assignerPermissions []string, l *logs.Log) error - AdmDeleteAppOrgGroup(ID string, appID string, orgID string, assignerPermissions []string, system bool, l *logs.Log) error - - AdmCreateAppOrgRole(name string, description string, permissionNames []string, appID string, orgID string, assignerPermissions []string, system bool, l *logs.Log) (*model.AppOrgRole, error) - AdmGetAppOrgRoles(appID string, orgID string) ([]model.AppOrgRole, error) - AdmGrantPermissionsToRole(appID string, orgID string, roleID string, permissionNames []string, assignerPermissions []string, system bool, l *logs.Log) error - AdmDeleteAppOrgRole(ID string, appID string, orgID string, assignerPermissions []string, system bool, l *logs.Log) error - - AdmGetApplicationPermissions(appID string, orgID string, l *logs.Log) ([]model.Permission, error) - - AdmGetAccounts(limit int, offset int, appID string, orgID string, accountID *string, firstName *string, lastName *string, authType *string, - authTypeIdentifier *string, anonymous *bool, hasPermissions *bool, permissions []string, roleIDs []string, groupIDs []string) ([]model.Account, error) - AdmGetAccount(accountID string) (*model.Account, error) - - AdmUpdateAccountUsername(accountID string, appID string, orgID string, username string) error - - AdmGetAccountSystemConfigs(appID string, orgID string, accountID string, l *logs.Log) (map[string]interface{}, error) - AdmUpdateAccountSystemConfigs(appID string, orgID string, accountID string, configs map[string]interface{}, createAnonymous bool, l *logs.Log) (bool, error) - - AdmGrantAccountPermissions(appID string, orgID string, accountID string, permissionNames []string, assignerPermissions []string, l *logs.Log) error - AdmRevokeAccountPermissions(appID string, orgID string, accountID string, permissions []string, assignerPermissions []string, l *logs.Log) error - - AdmGrantAccountRoles(appID string, orgID string, accountID string, roleIDs []string, assignerPermissions []string, l *logs.Log) error - AdmRevokeAccountRoles(appID string, orgID string, accountID string, roleIDs []string, assignerPermissions []string, l *logs.Log) error - - AdmGetApplicationLoginSessions(appID string, orgID string, identifier *string, accountAuthTypeIdentifier *string, - appTypeID *string, appTypeIdentifier *string, anonymous *bool, deviceID *string, ipAddress *string) ([]model.LoginSession, error) - AdmDeleteApplicationLoginSession(appID string, orgID string, currentAccountID string, identifier string, sessionID string, l *logs.Log) error - - AdmGetApplicationAccountDevices(appID string, orgID string, accountID string, l *logs.Log) ([]model.Device, error) -} - -// Encryption exposes APIs for the Encryption building block -type Encryption interface { - EncGetTest() string -} - -// BBs exposes users related APIs used by the platform building blocks -type BBs interface { - BBsGetTest() string - - BBsGetAccounts(searchParams map[string]interface{}, appID string, orgID string, limit int, offset int, allAccess bool, approvedKeys []string) ([]map[string]interface{}, error) - BBsGetAccountsCount(searchParams map[string]interface{}, appID string, orgID string) (int64, error) -} - -// TPS exposes user related APIs used by third-party services -type TPS interface { - TPSGetAccounts(searchParams map[string]interface{}, appID string, orgID string, limit int, offset int, allAccess bool, approvedKeys []string) ([]map[string]interface{}, error) - TPsGetAccountsCount(searchParams map[string]interface{}, appID string, orgID string) (int64, error) -} - -// System exposes system APIs for the driver adapters -type System interface { - SysCreateGlobalConfig(setting string) (*model.GlobalConfig, error) - SysGetGlobalConfig() (*model.GlobalConfig, error) - SysUpdateGlobalConfig(setting string) error - - SysGetApplicationOrganization(ID string) (*model.ApplicationOrganization, error) - SysGetApplicationOrganizations(appID *string, orgID *string) ([]model.ApplicationOrganization, error) - SysCreateApplicationOrganization(appID string, orgID string, appOrg model.ApplicationOrganization) (*model.ApplicationOrganization, error) - SysUpdateApplicationOrganization(updateAppOrg model.ApplicationOrganization) error - - SysCreateOrganization(name string, requestType string, organizationDomains []string) (*model.Organization, error) - SysGetOrganizations() ([]model.Organization, error) - SysGetOrganization(ID string) (*model.Organization, error) - SysUpdateOrganization(ID string, name string, requestType string, organizationDomains []string) error - - SysCreateApplication(name string, multiTenant bool, admin bool, sharedIdentities bool, appTypes []model.ApplicationType) (*model.Application, error) - SysUpdateApplication(ID string, name string, multiTenant bool, admin bool, sharedIdentities bool, appTypes []model.ApplicationType) error - SysGetApplication(ID string) (*model.Application, error) - SysGetApplications() ([]model.Application, error) - - SysCreatePermission(name string, description *string, serviceID *string, assigners *[]string) (*model.Permission, error) - SysUpdatePermission(name string, description *string, serviceID *string, assigners *[]string) (*model.Permission, error) - - SysGetAppConfigs(appTypeID string, orgID *string, versionNumbers *model.VersionNumbers) ([]model.ApplicationConfig, error) - SysGetAppConfig(id string) (*model.ApplicationConfig, error) - SysCreateAppConfig(appTypeID string, orgID *string, data map[string]interface{}, versionNumbers model.VersionNumbers) (*model.ApplicationConfig, error) - SysUpdateAppConfig(id string, appTypeID string, orgID *string, data map[string]interface{}, versionNumbers model.VersionNumbers) error - SysDeleteAppConfig(id string) error - - SysCreateAuthTypes(code string, description string, isExternal bool, isAnonymous bool, useCredentials bool, ignoreMFA bool, params map[string]interface{}) (*model.AuthType, error) - SysGetAuthTypes() ([]model.AuthType, error) - SysUpdateAuthTypes(ID string, code string, description string, isExternal bool, isAnonymous bool, useCredentials bool, ignoreMFA bool, params map[string]interface{}) error -} - -// Storage is used by core to storage data - DB storage adapter, file storage adapter etc -type Storage interface { - RegisterStorageListener(storageListener storage.Listener) - - PerformTransaction(func(context storage.TransactionContext) error) error - - FindAuthType(codeOrID string) (*model.AuthType, error) - - FindAccountByID(context storage.TransactionContext, id string) (*model.Account, error) - FindAccounts(context storage.TransactionContext, limit *int, offset *int, appID string, orgID string, accountID *string, firstName *string, lastName *string, authType *string, - authTypeIdentifier *string, anonymous *bool, hasPermissions *bool, permissions []string, roleIDs []string, groupIDs []string) ([]model.Account, error) - FindAccountsByParams(searchParams map[string]interface{}, appID string, orgID string, limit int, offset int, allAccess bool, approvedKeys []string) ([]map[string]interface{}, error) - CountAccountsByParams(searchParams map[string]interface{}, appID string, orgID string) (int64, error) - FindAccountsByAccountID(context storage.TransactionContext, appID string, orgID string, accountIDs []string) ([]model.Account, error) - FindAccountsByUsername(context storage.TransactionContext, appOrg *model.ApplicationOrganization, username string) ([]model.Account, error) - - UpdateAccountPreferences(context storage.TransactionContext, accountID string, preferences map[string]interface{}) error - UpdateAccountSystemConfigs(context storage.TransactionContext, accountID string, configs map[string]interface{}) error - InsertAccountPermissions(context storage.TransactionContext, accountID string, permissions []model.Permission) error - DeleteAccountPermissions(context storage.TransactionContext, accountID string, permissionNames []string) error - UpdateAccountUsername(context storage.TransactionContext, accountID, username string) error - InsertAccountRoles(context storage.TransactionContext, accountID string, appOrgID string, roles []model.AccountRole) error - DeleteAccountRoles(context storage.TransactionContext, accountID string, roleIDs []string) error - InsertAccountsGroup(context storage.TransactionContext, group model.AccountGroup, accountIDs []string) error - RemoveAccountsGroup(context storage.TransactionContext, groupID string, accountIDs []string) error - CountAccountsByRoleID(roleID string) (*int64, error) - CountAccountsByGroupID(groupID string) (*int64, error) - - UpdateProfile(context storage.TransactionContext, profile model.Profile) error - - FindLoginSessionsByParams(appID string, orgID string, sessionID *string, identifier *string, accountAuthTypeIdentifier *string, - appTypeID *string, appTypeIdentifier *string, anonymous *bool, deviceID *string, ipAddress *string) ([]model.LoginSession, error) - DeleteLoginSessionByID(context storage.TransactionContext, id string) error - DeleteLoginSessionsByIdentifier(context storage.TransactionContext, identifier string) error - - SaveDevice(context storage.TransactionContext, device *model.Device) error - DeleteDevice(context storage.TransactionContext, id string) error - - CreateGlobalConfig(context storage.TransactionContext, globalConfig *model.GlobalConfig) error - GetGlobalConfig() (*model.GlobalConfig, error) - DeleteGlobalConfig(context storage.TransactionContext) error - - FindPermissionsByName(context storage.TransactionContext, names []string) ([]model.Permission, error) - FindPermissionsByServiceIDs(serviceIDs []string) ([]model.Permission, error) - InsertPermission(context storage.TransactionContext, item model.Permission) error - InsertPermissions(context storage.TransactionContext, items []model.Permission) error - UpdatePermission(item model.Permission) error - DeletePermission(id string) error - - FindAppOrgRoles(appOrgID string) ([]model.AppOrgRole, error) - FindAppOrgRolesByIDs(context storage.TransactionContext, ids []string, appOrgID string) ([]model.AppOrgRole, error) - FindAppOrgRole(id string, appOrgID string) (*model.AppOrgRole, error) - InsertAppOrgRole(context storage.TransactionContext, item model.AppOrgRole) error - UpdateAppOrgRole(item model.AppOrgRole) error - DeleteAppOrgRole(id string) error - InsertAppOrgRolePermissions(context storage.TransactionContext, roleID string, permissionNames []model.Permission) error - - FindAppOrgGroups(appOrgID string) ([]model.AppOrgGroup, error) - FindAppOrgGroupsByIDs(context storage.TransactionContext, ids []string, appOrgID string) ([]model.AppOrgGroup, error) - FindAppOrgGroup(context storage.TransactionContext, id string, appOrgID string) (*model.AppOrgGroup, error) - InsertAppOrgGroup(context storage.TransactionContext, item model.AppOrgGroup) error - UpdateAppOrgGroup(context storage.TransactionContext, item model.AppOrgGroup) error - DeleteAppOrgGroup(id string) error - CountGroupsByRoleID(roleID string) (*int64, error) - - InsertOrganization(context storage.TransactionContext, organization model.Organization) (*model.Organization, error) - UpdateOrganization(ID string, name string, requestType string, organizationDomains []string) error - FindOrganization(id string) (*model.Organization, error) - FindSystemOrganization() (*model.Organization, error) - FindOrganizations() ([]model.Organization, error) - - InsertApplication(context storage.TransactionContext, application model.Application) (*model.Application, error) - SaveApplication(context storage.TransactionContext, application model.Application) error - FindApplication(context storage.TransactionContext, ID string) (*model.Application, error) - FindApplications() ([]model.Application, error) - - InsertAuthType(context storage.TransactionContext, authType model.AuthType) (*model.AuthType, error) - FindAuthTypes() ([]model.AuthType, error) - UpdateAuthTypes(ID string, code string, description string, isExternal bool, isAnonymous bool, useCredentials bool, ignoreMFA bool, params map[string]interface{}) error - - FindApplicationType(id string) (*model.ApplicationType, error) - - FindAppConfigs(appTypeIdentifier string, appOrgID *string, versionNumbers *model.VersionNumbers) ([]model.ApplicationConfig, error) - FindAppConfigByVersion(appTypeIdentifier string, appOrgID *string, versionNumbers model.VersionNumbers) (*model.ApplicationConfig, error) - FindAppConfigByID(ID string) (*model.ApplicationConfig, error) - InsertAppConfig(item model.ApplicationConfig) (*model.ApplicationConfig, error) - UpdateAppConfig(ID string, appType model.ApplicationType, appOrg *model.ApplicationOrganization, version model.Version, data map[string]interface{}) error - DeleteAppConfig(ID string) error - - FindApplicationsOrganizationsByOrgID(orgID string) ([]model.ApplicationOrganization, error) - FindApplicationOrganizations(appID *string, orgID *string) ([]model.ApplicationOrganization, error) - FindApplicationOrganization(appID string, orgID string) (*model.ApplicationOrganization, error) - FindApplicationOrganizationByID(ID string) (*model.ApplicationOrganization, error) - InsertApplicationOrganization(context storage.TransactionContext, applicationOrganization model.ApplicationOrganization) (*model.ApplicationOrganization, error) - UpdateApplicationOrganization(context storage.TransactionContext, applicationOrganization model.ApplicationOrganization) error - - InsertAPIKey(context storage.TransactionContext, apiKey model.APIKey) (*model.APIKey, error) -} - // StorageListener listenes for change data storage events type StorageListener struct { app *application diff --git a/core/interfaces/auth.go b/core/interfaces/auth.go new file mode 100644 index 000000000..bf8dd963b --- /dev/null +++ b/core/interfaces/auth.go @@ -0,0 +1,366 @@ +// Copyright 2022 Board of Trustees of the University of Illinois. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package interfaces + +import ( + "core-building-block/core/model" + + "github.com/rokwire/core-auth-library-go/v2/authorization" + "github.com/rokwire/core-auth-library-go/v2/sigauth" + "github.com/rokwire/core-auth-library-go/v2/tokenauth" + "github.com/rokwire/logging-library-go/logs" +) + +// APIs is the interface which defines the APIs provided by the auth package +type APIs interface { + //Start starts the auth service + Start() + + //GetHost returns the host/issuer of the auth service + GetHost() string + + //Login logs a user in a specific application using the specified credentials and authentication method. + //The authentication method must be one of the supported for the application. + // Input: + // ipAddress (string): Client's IP address + // deviceType (string): "mobile" or "web" or "desktop" etc + // deviceOS (*string): Device OS + // deviceID (string): Device ID + // authenticationType (string): Name of the authentication method for provided creds (eg. "email", "username", "illinois_oidc") + // creds (string): Credentials/JSON encoded credential structure defined for the specified auth type + // apiKey (string): API key to validate the specified app + // appTypeIdentifier (string): identifier of the app type/client that the user is logging in from + // orgID (string): ID of the organization that the user is logging in + // params (string): JSON encoded params defined by specified auth type + // clientVersion(*string): Most recent client version + // profile (Profile): Account profile + // preferences (map): Account preferences + // admin (bool): Is this an admin login? + // l (*logs.Log): Log object pointer for request + // Returns: + // Message (*string): message + // Login session (*LoginSession): Signed ROKWIRE access token to be used to authorize future requests + // Access token (string): Signed ROKWIRE access token to be used to authorize future requests + // Refresh Token (string): Refresh token that can be sent to refresh the access token once it expires + // AccountAuthType (AccountAuthType): AccountAuthType object for authenticated user + // Params (interface{}): authType-specific set of parameters passed back to client + // State (string): login state used if account is enrolled in MFA + // MFA types ([]model.MFAType): list of MFA types account is enrolled in + Login(ipAddress string, deviceType string, deviceOS *string, deviceID string, authenticationType string, creds string, apiKey string, + appTypeIdentifier string, orgID string, params string, clientVersion *string, profile model.Profile, preferences map[string]interface{}, + username string, admin bool, l *logs.Log) (*string, *model.LoginSession, []model.MFAType, error) + + //Logout logouts an account from app/org + // Input: + // allSessions (bool): If to remove the current session only or all sessions for the app/org for the account + Logout(appID string, orgID string, currentAccountID string, sessionID string, allSessions bool, l *logs.Log) error + + //AccountExists checks if a user is already registered + //The authentication method must be one of the supported for the application. + // Input: + // authenticationType (string): Name of the authentication method for provided creds (eg. "email", "username", "illinois_oidc") + // userIdentifier (string): User identifier for the specified auth type + // apiKey (string): API key to validate the specified app + // appTypeIdentifier (string): identifier of the app type/client that the user is logging in from + // orgID (string): ID of the organization that the user is logging in + // Returns: + // accountExisted (bool): valid when error is nil + AccountExists(authenticationType string, userIdentifier string, apiKey string, appTypeIdentifier string, orgID string) (bool, error) + + //CanSignIn checks if a user can sign in + //The authentication method must be one of the supported for the application. + // Input: + // authenticationType (string): Name of the authentication method for provided creds (eg. "email", "username", "illinois_oidc") + // userIdentifier (string): User identifier for the specified auth type + // apiKey (string): API key to validate the specified app + // appTypeIdentifier (string): identifier of the app type/client being used + // orgID (string): ID of the organization being used + // Returns: + // canSignIn (bool): valid when error is nil + CanSignIn(authenticationType string, userIdentifier string, apiKey string, appTypeIdentifier string, orgID string) (bool, error) + + //CanLink checks if a user can link a new auth type + //The authentication method must be one of the supported for the application. + // Input: + // authenticationType (string): Name of the authentication method for provided creds (eg. "email", "username", "illinois_oidc") + // userIdentifier (string): User identifier for the specified auth type + // apiKey (string): API key to validate the specified app + // appTypeIdentifier (string): identifier of the app type/client being used + // orgID (string): ID of the organization being used + // Returns: + // canLink (bool): valid when error is nil + CanLink(authenticationType string, userIdentifier string, apiKey string, appTypeIdentifier string, orgID string) (bool, error) + + //Refresh refreshes an access token using a refresh token + // Input: + // refreshToken (string): Refresh token + // apiKey (string): API key to validate the specified app + // clientVersion(*string): Most recent client version + // l (*logs.Log): Log object pointer for request + // Returns: + // Login session (*LoginSession): Signed ROKWIRE access token to be used to authorize future requests + // Access token (string): Signed ROKWIRE access token to be used to authorize future requests + // Refresh Token (string): Refresh token that can be sent to refresh the access token once it expires + // Params (interface{}): authType-specific set of parameters passed back to client + Refresh(refreshToken string, apiKey string, clientVersion *string, l *logs.Log) (*model.LoginSession, error) + + //GetLoginURL returns a pre-formatted login url for SSO providers + // Input: + // authType (string): Name of the authentication method for provided creds (eg. "email", "username", "illinois_oidc") + // appTypeIdentifier (string): Identifier of the app type/client that the user is logging in from + // orgID (string): ID of the organization that the user is logging in + // redirectURI (string): Registered redirect URI where client will receive response + // apiKey (string): API key to validate the specified app + // l (*loglib.Log): Log object pointer for request + // Returns: + // Login URL (string): SSO provider login URL to be launched in a browser + // Params (map[string]interface{}): Params to be sent in subsequent request (if necessary) + GetLoginURL(authType string, appTypeIdentifier string, orgID string, redirectURI string, apiKey string, l *logs.Log) (string, map[string]interface{}, error) + + //LoginMFA verifies a code sent by a user as a final login step for enrolled accounts. + //The MFA type must be one of the supported for the application. + // Input: + // apiKey (string): API key to validate the specified app + // accountID (string): ID of account user is trying to access + // sessionID (string): ID of login session generated during login + // identifier (string): Email, phone, or TOTP device name + // mfaType (string): Type of MFA code sent + // mfaCode (string): Code that must be verified + // state (string): Variable used to verify user has already passed credentials check + // l (*logs.Log): Log object pointer for request + // Returns: + // Message (*string): message + // Login session (*LoginSession): Signed ROKWIRE access token to be used to authorize future requests + // Access token (string): Signed ROKWIRE access token to be used to authorize future requests + // Refresh Token (string): Refresh token that can be sent to refresh the access token once it expires + // AccountAuthType (AccountAuthType): AccountAuthType object for authenticated user + LoginMFA(apiKey string, accountID string, sessionID string, identifier string, mfaType string, mfaCode string, state string, l *logs.Log) (*string, *model.LoginSession, error) + + //CreateAdminAccount creates an account for a new admin user + CreateAdminAccount(authenticationType string, appID string, orgID string, identifier string, profile model.Profile, username string, permissions []string, + roleIDs []string, groupIDs []string, creatorPermissions []string, clientVersion *string, l *logs.Log) (*model.Account, map[string]interface{}, error) + + //UpdateAdminAccount updates an existing user's account with new permissions, roles, and groups + UpdateAdminAccount(authenticationType string, appID string, orgID string, identifier string, permissions []string, roleIDs []string, + groupIDs []string, updaterPermissions []string, l *logs.Log) (*model.Account, map[string]interface{}, error) + + //CreateAnonymousAccount creates a new anonymous account + CreateAnonymousAccount(storage Storage, appID string, orgID string, anonymousID string, preferences map[string]interface{}, + systemConfigs map[string]interface{}, skipExistsCheck bool, l *logs.Log) (*model.Account, error) + + //VerifyCredential verifies credential (checks the verification code in the credentials collection) + VerifyCredential(id string, verification string, l *logs.Log) error + + //SendVerifyCredential sends verification code to identifier + SendVerifyCredential(authenticationType string, appTypeIdentifier string, orgID string, apiKey string, identifier string, l *logs.Log) error + + //UpdateCredential updates the credential object with the new value + // Input: + // accountID: id of the associated account to reset + // accountAuthTypeID (string): id of the AccountAuthType + // params: specific params for the different auth types + // Returns: + // error: if any + UpdateCredential(accountID string, accountAuthTypeID string, params string, l *logs.Log) error + + //ForgotCredential initiate forgot credential process (generates a reset link and sends to the given identifier for email auth type) + // Input: + // authenticationType (string): Name of the authentication method for provided creds (eg. "email", "username", "illinois_oidc") + // identifier: identifier of the account auth type + // appTypeIdentifier (string): Identifier of the app type/client that the user is logging in from + // orgID (string): ID of the organization that the user is logging in + // apiKey (string): API key to validate the specified app + // Returns: + // error: if any + ForgotCredential(authenticationType string, appTypeIdentifier string, orgID string, apiKey string, identifier string, l *logs.Log) error + + //ResetForgotCredential resets forgot credential + // Input: + // credsID: id of the credential object + // resetCode: code from the reset link + // params: specific params for the different auth types + // Returns: + // error: if any + ResetForgotCredential(credsID string, resetCode string, params string, l *logs.Log) error + + //VerifyMFA verifies a code sent by a user as a final MFA enrollment step. + //The MFA type must be one of the supported for the application. + // Input: + // accountID (string): ID of account for which user is trying to verify MFA + // identifier (string): Email, phone, or TOTP device name + // mfaType (string): Type of MFA code sent + // mfaCode (string): Code that must be verified + // Returns: + // Message (*string): message + // Recovery codes ([]string): List of account recovery codes returned if enrolling in MFA for first time + VerifyMFA(accountID string, identifier string, mfaType string, mfaCode string) (*string, []string, error) + + //GetMFATypes gets all MFA types set up for an account + // Input: + // accountID (string): Account ID to find MFA types + // Returns: + // MFA Types ([]model.MFAType): MFA information for all enrolled types + GetMFATypes(accountID string) ([]model.MFAType, error) + + //AddMFAType adds a form of MFA to an account + // Input: + // accountID (string): Account ID to add MFA + // identifier (string): Email, phone, or TOTP device name + // mfaType (string): Type of MFA to be added + // Returns: + // MFA Type (*model.MFAType): MFA information for the specified type + AddMFAType(accountID string, identifier string, mfaType string) (*model.MFAType, error) + + //RemoveMFAType removes a form of MFA from an account + // Input: + // accountID (string): Account ID to remove MFA + // identifier (string): Email, phone, or TOTP device name + // mfaType (string): Type of MFA to remove + RemoveMFAType(accountID string, identifier string, mfaType string) error + + //GetServiceAccountParams returns a list of app, org pairs a service account has access to + GetServiceAccountParams(accountID string, firstParty bool, r *sigauth.Request, l *logs.Log) ([]model.AppOrgPair, error) + + //GetServiceAccessToken returns an access token for a non-human client + GetServiceAccessToken(firstParty bool, r *sigauth.Request, l *logs.Log) (string, error) + + //GetAllServiceAccessTokens returns an access token for each app, org pair a service account has access to + GetAllServiceAccessTokens(firstParty bool, r *sigauth.Request, l *logs.Log) (map[model.AppOrgPair]string, error) + + //GetServiceAccounts gets all service accounts matching a search + GetServiceAccounts(params map[string]interface{}) ([]model.ServiceAccount, error) + + //RegisterServiceAccount registers a service account + RegisterServiceAccount(accountID *string, fromAppID *string, fromOrgID *string, name *string, appID string, orgID string, permissions *[]string, scopes []authorization.Scope, + firstParty *bool, creds []model.ServiceAccountCredential, assignerPermissions []string, l *logs.Log) (*model.ServiceAccount, error) + + //DeregisterServiceAccount deregisters a service account + DeregisterServiceAccount(accountID string) error + + //GetServiceAccountInstance gets a service account instance + GetServiceAccountInstance(accountID string, appID string, orgID string) (*model.ServiceAccount, error) + + //UpdateServiceAccountInstance updates a service account instance + UpdateServiceAccountInstance(id string, appID string, orgID string, name *string, permissions *[]string, scopes []authorization.Scope, assignerPermissions []string) (*model.ServiceAccount, error) + + //DeregisterServiceAccountInstance deregisters a service account instance + DeregisterServiceAccountInstance(id string, appID string, orgID string) error + + //AddServiceAccountCredential adds a credential to a service account + AddServiceAccountCredential(accountID string, creds *model.ServiceAccountCredential, l *logs.Log) (*model.ServiceAccountCredential, error) + + //RemoveServiceAccountCredential removes a credential from a service account + RemoveServiceAccountCredential(accountID string, credID string) error + + //AuthorizeService returns a scoped token for the specified service and the service registration record if authorized or + // the service registration record if not. Passing "approvedScopes" will update the service authorization for this user and + // return a scoped access token which reflects this change. + // Input: + // claims (tokenauth.Claims): Claims from un-scoped user access token + // serviceID (string): ID of the service to be authorized + // approvedScopes ([]string): list of scope strings to be approved + // l (*logs.Log): Log object pointer for request + // Returns: + // Access token (string): Signed scoped access token to be used to authorize requests to the specified service + // Approved Scopes ([]authorization.Scope): The approved scopes included in the provided token + // Service reg (*model.ServiceReg): The service registration record for the requested service + AuthorizeService(claims tokenauth.Claims, serviceID string, approvedScopes []authorization.Scope, l *logs.Log) (string, []authorization.Scope, *model.ServiceReg, error) + + //LinkAccountAuthType links new credentials to an existing account. + //The authentication method must be one of the supported for the application. + // Input: + // accountID (string): ID of the account to link the creds to + // authenticationType (string): Name of the authentication method for provided creds (eg. "email", "username", "illinois_oidc") + // appTypeIdentifier (string): identifier of the app type/client that the user is logging in from + // creds (string): Credentials/JSON encoded credential structure defined for the specified auth type + // params (string): JSON encoded params defined by specified auth type + // l (*logs.Log): Log object pointer for request + // Returns: + // message (*string): response message + // account (*model.Account): account data after the operation + LinkAccountAuthType(accountID string, authenticationType string, appTypeIdentifier string, creds string, params string, l *logs.Log) (*string, *model.Account, error) + + //UnlinkAccountAuthType unlinks credentials from an existing account. + //The authentication method must be one of the supported for the application. + // Input: + // accountID (string): ID of the account to unlink creds from + // authenticationType (string): Name of the authentication method of account auth type to unlink + // appTypeIdentifier (string): Identifier of the app type/client that the user is logging in from + // identifier (string): Identifier of account auth type to unlink + // l (*logs.Log): Log object pointer for request + // Returns: + // account (*model.Account): account data after the operation + UnlinkAccountAuthType(accountID string, authenticationType string, appTypeIdentifier string, identifier string, l *logs.Log) (*model.Account, error) + + //InitializeSystemAccount initializes the first system account + InitializeSystemAccount(storage Storage, authType model.AuthType, appOrg model.ApplicationOrganization, allSystemPermission string, email string, password string, clientVersion string, l *logs.Log) (string, error) + + //GrantAccountPermissions grants new permissions to an account after validating the assigner has required permissions + GrantAccountPermissions(storage Storage, account *model.Account, permissionNames []string, assignerPermissions []string) error + + //CheckPermissions loads permissions by names from storage and checks that they are assignable and valid for the given appOrgs or revocable + CheckPermissions(storage Storage, appOrgs []model.ApplicationOrganization, permissionNames []string, assignerPermissions []string, revoke bool) ([]model.Permission, error) + + //GrantAccountRoles grants new roles to an account after validating the assigner has required permissions + GrantAccountRoles(storage Storage, account *model.Account, roleIDs []string, assignerPermissions []string) error + + //CheckRoles loads appOrg roles by IDs from storage and checks that they are assignable or revocable + CheckRoles(storage Storage, appOrg *model.ApplicationOrganization, roleIDs []string, assignerPermissions []string, revoke bool) ([]model.AppOrgRole, error) + + //GrantAccountGroups grants new groups to an account after validating the assigner has required permissions + GrantAccountGroups(storage Storage, account *model.Account, groupIDs []string, assignerPermissions []string) error + + //CheckGroups loads appOrg groups by IDs from storage and checks that they are assignable or revocable + CheckGroups(storage Storage, appOrg *model.ApplicationOrganization, groupIDs []string, assignerPermissions []string, revoke bool) ([]model.AppOrgGroup, error) + + //DeleteAccount deletes an account for the given id + DeleteAccount(id string) error + + //GetAdminToken returns an admin token for the specified application and organization + GetAdminToken(claims tokenauth.Claims, appID string, orgID string, l *logs.Log) (string, error) + + //GetAuthKeySet generates a JSON Web Key Set for auth service registration + GetAuthKeySet() (*model.JSONWebKeySet, error) + + //GetServiceRegistrations retrieves all service registrations + GetServiceRegistrations(serviceIDs []string) []model.ServiceReg + + //RegisterService creates a new service registration + RegisterService(reg *model.ServiceReg) error + + //UpdateServiceRegistration updates an existing service registration + UpdateServiceRegistration(reg *model.ServiceReg) error + + //DeregisterService deletes an existing service registration + DeregisterService(serviceID string) error + + //GetApplicationAPIKeys finds and returns the API keys for an application + GetApplicationAPIKeys(appID string) ([]model.APIKey, error) + + //GetAPIKey finds and returns an API key + GetAPIKey(ID string) (*model.APIKey, error) + + //CreateAPIKey creates a new API key + CreateAPIKey(apiKey model.APIKey) (*model.APIKey, error) + + //UpdateAPIKey updates an existing API key + UpdateAPIKey(apiKey model.APIKey) error + + //DeleteAPIKey deletes an API key + DeleteAPIKey(ID string) error + + //ValidateAPIKey validates the given API key for the given app ID + ValidateAPIKey(appID string, apiKey string) error +} diff --git a/core/interfaces/core.go b/core/interfaces/core.go new file mode 100644 index 000000000..53f69d675 --- /dev/null +++ b/core/interfaces/core.go @@ -0,0 +1,138 @@ +// Copyright 2022 Board of Trustees of the University of Illinois. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package interfaces + +import ( + "core-building-block/core/model" + + "github.com/rokwire/logging-library-go/logs" +) + +// Services exposes APIs for the driver adapters +type Services interface { + SerDeleteAccount(id string) error + SerGetAccount(accountID string) (*model.Account, error) + SerGetProfile(accountID string) (*model.Profile, error) + SerGetPreferences(accountID string) (map[string]interface{}, error) + SerGetAccountSystemConfigs(accountID string) (map[string]interface{}, error) + SerUpdateAccountPreferences(id string, appID string, orgID string, anonymous bool, preferences map[string]interface{}, l *logs.Log) (bool, error) + SerUpdateProfile(accountID string, profile model.Profile) error + SerUpdateAccountUsername(accountID string, appID string, orgID string, username string) error + + SerGetAccounts(limit int, offset int, appID string, orgID string, accountID *string, firstName *string, lastName *string, authType *string, + authTypeIdentifier *string, anonymous *bool, hasPermissions *bool, permissions []string, roleIDs []string, groupIDs []string) ([]model.Account, error) + + SerGetAuthTest(l *logs.Log) string + SerGetCommonTest(l *logs.Log) string + + SerGetAppConfig(appTypeIdentifier string, orgID *string, versionNumbers model.VersionNumbers, apiKey *string) (*model.ApplicationConfig, error) +} + +// Administration exposes administration APIs for the driver adapters +type Administration interface { + AdmGetTest() string + AdmGetTestModel() string + + AdmGetApplications(orgID string) ([]model.Application, error) + + AdmCreateAppOrgGroup(name string, description string, system bool, permissionNames []string, rolesIDs []string, accountIDs []string, appID string, orgID string, assignerPermissions []string, systemClaim bool, l *logs.Log) (*model.AppOrgGroup, error) + AdmUpdateAppOrgGroup(ID string, name string, description string, system bool, permissionNames []string, rolesIDs []string, accountIDs []string, appID string, orgID string, assignerPermissions []string, systemClaim bool, l *logs.Log) (*model.AppOrgGroup, error) + AdmGetAppOrgGroups(appID string, orgID string) ([]model.AppOrgGroup, error) + AdmAddAccountsToGroup(appID string, orgID string, groupID string, accountIDs []string, assignerPermissions []string, l *logs.Log) error + AdmRemoveAccountsFromGroup(appID string, orgID string, groupID string, accountIDs []string, assignerPermissions []string, l *logs.Log) error + AdmDeleteAppOrgGroup(ID string, appID string, orgID string, assignerPermissions []string, system bool, l *logs.Log) error + + AdmCreateAppOrgRole(name string, description string, permissionNames []string, appID string, orgID string, assignerPermissions []string, system bool, l *logs.Log) (*model.AppOrgRole, error) + AdmGetAppOrgRoles(appID string, orgID string) ([]model.AppOrgRole, error) + AdmGrantPermissionsToRole(appID string, orgID string, roleID string, permissionNames []string, assignerPermissions []string, system bool, l *logs.Log) error + AdmDeleteAppOrgRole(ID string, appID string, orgID string, assignerPermissions []string, system bool, l *logs.Log) error + + AdmGetApplicationPermissions(appID string, orgID string, l *logs.Log) ([]model.Permission, error) + + AdmGetAccounts(limit int, offset int, appID string, orgID string, accountID *string, firstName *string, lastName *string, authType *string, + authTypeIdentifier *string, anonymous *bool, hasPermissions *bool, permissions []string, roleIDs []string, groupIDs []string) ([]model.Account, error) + AdmGetAccount(accountID string) (*model.Account, error) + + AdmUpdateAccountUsername(accountID string, appID string, orgID string, username string) error + + AdmGetAccountSystemConfigs(appID string, orgID string, accountID string, l *logs.Log) (map[string]interface{}, error) + AdmUpdateAccountSystemConfigs(appID string, orgID string, accountID string, configs map[string]interface{}, createAnonymous bool, l *logs.Log) (bool, error) + + AdmGrantAccountPermissions(appID string, orgID string, accountID string, permissionNames []string, assignerPermissions []string, l *logs.Log) error + AdmRevokeAccountPermissions(appID string, orgID string, accountID string, permissions []string, assignerPermissions []string, l *logs.Log) error + + AdmGrantAccountRoles(appID string, orgID string, accountID string, roleIDs []string, assignerPermissions []string, l *logs.Log) error + AdmRevokeAccountRoles(appID string, orgID string, accountID string, roleIDs []string, assignerPermissions []string, l *logs.Log) error + + AdmGetApplicationLoginSessions(appID string, orgID string, identifier *string, accountAuthTypeIdentifier *string, + appTypeID *string, appTypeIdentifier *string, anonymous *bool, deviceID *string, ipAddress *string) ([]model.LoginSession, error) + AdmDeleteApplicationLoginSession(appID string, orgID string, currentAccountID string, identifier string, sessionID string, l *logs.Log) error + + AdmGetApplicationAccountDevices(appID string, orgID string, accountID string, l *logs.Log) ([]model.Device, error) +} + +// Encryption exposes APIs for the Encryption building block +type Encryption interface { + EncGetTest() string +} + +// BBs exposes users related APIs used by the platform building blocks +type BBs interface { + BBsGetTest() string + + BBsGetAccounts(searchParams map[string]interface{}, appID string, orgID string, limit int, offset int, allAccess bool, approvedKeys []string) ([]map[string]interface{}, error) + BBsGetAccountsCount(searchParams map[string]interface{}, appID string, orgID string) (int64, error) +} + +// TPS exposes user related APIs used by third-party services +type TPS interface { + TPSGetAccounts(searchParams map[string]interface{}, appID string, orgID string, limit int, offset int, allAccess bool, approvedKeys []string) ([]map[string]interface{}, error) + TPsGetAccountsCount(searchParams map[string]interface{}, appID string, orgID string) (int64, error) +} + +// System exposes system APIs for the driver adapters +type System interface { + SysCreateGlobalConfig(setting string) (*model.GlobalConfig, error) + SysGetGlobalConfig() (*model.GlobalConfig, error) + SysUpdateGlobalConfig(setting string) error + + SysGetApplicationOrganization(ID string) (*model.ApplicationOrganization, error) + SysGetApplicationOrganizations(appID *string, orgID *string) ([]model.ApplicationOrganization, error) + SysCreateApplicationOrganization(appID string, orgID string, appOrg model.ApplicationOrganization) (*model.ApplicationOrganization, error) + SysUpdateApplicationOrganization(updateAppOrg model.ApplicationOrganization) error + + SysCreateOrganization(name string, requestType string, organizationDomains []string) (*model.Organization, error) + SysGetOrganizations() ([]model.Organization, error) + SysGetOrganization(ID string) (*model.Organization, error) + SysUpdateOrganization(ID string, name string, requestType string, organizationDomains []string) error + + SysCreateApplication(name string, multiTenant bool, admin bool, sharedIdentities bool, appTypes []model.ApplicationType) (*model.Application, error) + SysUpdateApplication(ID string, name string, multiTenant bool, admin bool, sharedIdentities bool, appTypes []model.ApplicationType) error + SysGetApplication(ID string) (*model.Application, error) + SysGetApplications() ([]model.Application, error) + + SysCreatePermission(name string, description *string, serviceID *string, assigners *[]string) (*model.Permission, error) + SysUpdatePermission(name string, description *string, serviceID *string, assigners *[]string) (*model.Permission, error) + + SysGetAppConfigs(appTypeID string, orgID *string, versionNumbers *model.VersionNumbers) ([]model.ApplicationConfig, error) + SysGetAppConfig(id string) (*model.ApplicationConfig, error) + SysCreateAppConfig(appTypeID string, orgID *string, data map[string]interface{}, versionNumbers model.VersionNumbers) (*model.ApplicationConfig, error) + SysUpdateAppConfig(id string, appTypeID string, orgID *string, data map[string]interface{}, versionNumbers model.VersionNumbers) error + SysDeleteAppConfig(id string) error + + SysCreateAuthTypes(code string, description string, isExternal bool, isAnonymous bool, useCredentials bool, ignoreMFA bool, params map[string]interface{}) (*model.AuthType, error) + SysGetAuthTypes() ([]model.AuthType, error) + SysUpdateAuthTypes(ID string, code string, description string, isExternal bool, isAnonymous bool, useCredentials bool, ignoreMFA bool, params map[string]interface{}) error +} diff --git a/core/interfaces/driven.go b/core/interfaces/driven.go new file mode 100644 index 000000000..373d46633 --- /dev/null +++ b/core/interfaces/driven.go @@ -0,0 +1,247 @@ +// Copyright 2022 Board of Trustees of the University of Illinois. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package interfaces + +import ( + "core-building-block/core/model" + + "github.com/rokwire/logging-library-go/logs" +) + +// Storage interface to communicate with the storage +type Storage interface { + RegisterStorageListener(storageListener Listener) + + PerformTransaction(func(adapter Storage) error) error + + //AuthTypes + FindAuthType(codeOrID string) (*model.AuthType, error) + + //LoginsSessions + InsertLoginSession(session model.LoginSession) error + FindLoginSessions(identifier string) ([]model.LoginSession, error) + FindLoginSessionsByParams(appID string, orgID string, sessionID *string, identifier *string, accountAuthTypeIdentifier *string, + appTypeID *string, appTypeIdentifier *string, anonymous *bool, deviceID *string, ipAddress *string) ([]model.LoginSession, error) + FindLoginSession(refreshToken string) (*model.LoginSession, error) + FindAndUpdateLoginSession(id string) (*model.LoginSession, error) + UpdateLoginSession(loginSession model.LoginSession) error + DeleteLoginSession(id string) error + DeleteLoginSessionsByIDs(ids []string) error + DeleteLoginSessionsByAccountAuthTypeID(id string) error + DeleteLoginSessionsByIdentifier(identifier string) error + + //LoginsSessions - predefined queries for manage deletion logic + DeleteMFAExpiredSessions() error + FindSessionsLazy(appID string, orgID string) ([]model.LoginSession, error) + /// + + //Accounts + FindAccount(appOrgID string, authTypeID string, accountAuthTypeIdentifier string) (*model.Account, error) + FindAccountByID(id string) (*model.Account, error) + FindAccounts(limit *int, offset *int, appID string, orgID string, accountID *string, firstName *string, lastName *string, authType *string, + authTypeIdentifier *string, anonymous *bool, hasPermissions *bool, permissions []string, roleIDs []string, groupIDs []string) ([]model.Account, error) + FindAccountsByParams(searchParams map[string]interface{}, appID string, orgID string, limit int, offset int, allAccess bool, approvedKeys []string) ([]map[string]interface{}, error) + FindAccountsByAccountID(appID string, orgID string, accountIDs []string) ([]model.Account, error) + InsertAccount(account model.Account) (*model.Account, error) + SaveAccount(account *model.Account) error + DeleteAccount(id string) error + UpdateAccountUsageInfo(accountID string, updateLoginTime bool, updateAccessTokenTime bool, clientVersion *string) error + CountAccountsByParams(searchParams map[string]interface{}, appID string, orgID string) (int64, error) + CountAccountsByRoleID(roleID string) (*int64, error) + CountAccountsByGroupID(groupID string) (*int64, error) + + //Profiles + UpdateProfile(profile model.Profile) error + FindProfiles(appID string, authTypeID string, accountAuthTypeIdentifier string) ([]model.Profile, error) + + //Preferences + UpdateAccountPreferences(accountID string, preferences map[string]interface{}) error + + //SystemConfigs + UpdateAccountSystemConfigs(accountID string, configs map[string]interface{}) error + + //Username + FindAccountsByUsername(appOrg *model.ApplicationOrganization, username string) ([]model.Account, error) + UpdateAccountUsername(accountID, username string) error + + //ServiceAccounts + FindServiceAccount(accountID string, appID string, orgID string) (*model.ServiceAccount, error) + FindServiceAccounts(params map[string]interface{}) ([]model.ServiceAccount, error) + InsertServiceAccount(account *model.ServiceAccount) error + UpdateServiceAccount(account *model.ServiceAccount) (*model.ServiceAccount, error) + DeleteServiceAccount(accountID string, appID string, orgID string) error + DeleteServiceAccounts(accountID string) error + + //ServiceAccountCredentials + InsertServiceAccountCredential(accountID string, creds *model.ServiceAccountCredential) error + DeleteServiceAccountCredential(accountID string, credID string) error + + //AccountAuthTypes + FindAccountByAuthTypeID(id string) (*model.Account, error) + InsertAccountAuthType(item model.AccountAuthType) error + UpdateAccountAuthType(item model.AccountAuthType) error + DeleteAccountAuthType(item model.AccountAuthType) error + + //ExternalIDs + UpdateAccountExternalIDs(accountID string, externalIDs map[string]string) error + UpdateLoginSessionExternalIDs(accountID string, externalIDs map[string]string) error + + //Applications + InsertApplication(application model.Application) (*model.Application, error) + SaveApplication(application model.Application) error + FindApplication(ID string) (*model.Application, error) + FindApplications() ([]model.Application, error) + + //Organizations + InsertOrganization(organization model.Organization) (*model.Organization, error) + UpdateOrganization(ID string, name string, requestType string, organizationDomains []string) error + FindOrganization(id string) (*model.Organization, error) + FindSystemOrganization() (*model.Organization, error) + FindOrganizations() ([]model.Organization, error) + + //Credentials + InsertCredential(creds *model.Credential) error + FindCredential(ID string) (*model.Credential, error) + UpdateCredential(creds *model.Credential) error + UpdateCredentialValue(ID string, value map[string]interface{}) error + DeleteCredential(ID string) error + + //MFA + FindMFAType(accountID string, identifier string, mfaType string) (*model.MFAType, error) + FindMFATypes(accountID string) ([]model.MFAType, error) + InsertMFAType(mfa *model.MFAType, accountID string) error + UpdateMFAType(mfa *model.MFAType, accountID string) error + DeleteMFAType(accountID string, identifier string, mfaType string) error + + //ServiceRegs + FindServiceRegs(serviceIDs []string) []model.ServiceReg + FindServiceReg(serviceID string) (*model.ServiceReg, error) + InsertServiceReg(reg *model.ServiceReg) error + UpdateServiceReg(reg *model.ServiceReg) error + SaveServiceReg(reg *model.ServiceReg) error + DeleteServiceReg(serviceID string) error + + //AuthTypes + FindAuthTypes() ([]model.AuthType, error) + InsertAuthType(authType model.AuthType) (*model.AuthType, error) + UpdateAuthTypes(ID string, code string, description string, isExternal bool, isAnonymous bool, useCredentials bool, ignoreMFA bool, params map[string]interface{}) error + + //IdentityProviders + LoadIdentityProviders() ([]model.IdentityProvider, error) + + //ServiceAuthorizations + FindServiceAuthorization(userID string, orgID string) (*model.ServiceAuthorization, error) + SaveServiceAuthorization(authorization *model.ServiceAuthorization) error + DeleteServiceAuthorization(userID string, orgID string) error + + //APIKeys + LoadAPIKeys() ([]model.APIKey, error) + InsertAPIKey(apiKey model.APIKey) (*model.APIKey, error) + UpdateAPIKey(apiKey model.APIKey) error + DeleteAPIKey(ID string) error + + //ApplicationTypes + FindApplicationType(id string) (*model.ApplicationType, error) + + //ApplicationsOrganizations + FindApplicationsOrganizations() ([]model.ApplicationOrganization, error) + FindApplicationsOrganizationsByOrgID(orgID string) ([]model.ApplicationOrganization, error) + FindApplicationOrganizations(appID *string, orgID *string) ([]model.ApplicationOrganization, error) + FindApplicationOrganization(appID string, orgID string) (*model.ApplicationOrganization, error) + FindApplicationOrganizationByID(ID string) (*model.ApplicationOrganization, error) + InsertApplicationOrganization(applicationOrganization model.ApplicationOrganization) (*model.ApplicationOrganization, error) + UpdateApplicationOrganization(applicationOrganization model.ApplicationOrganization) error + + //Device + FindDevice(deviceID string, accountID string) (*model.Device, error) + InsertDevice(device model.Device) (*model.Device, error) + SaveDevice(device *model.Device) error + DeleteDevice(id string) error + + //Permissions + FindPermissions(ids []string) ([]model.Permission, error) + FindPermissionsByName(names []string) ([]model.Permission, error) + FindPermissionsByServiceIDs(serviceIDs []string) ([]model.Permission, error) + InsertPermission(item model.Permission) error + InsertPermissions(items []model.Permission) error + UpdatePermission(item model.Permission) error + DeletePermission(id string) error + //AccountPermissions + InsertAccountPermissions(accountID string, permissions []model.Permission) error + UpdateAccountPermissions(accountID string, permissions []model.Permission) error + DeleteAccountPermissions(accountID string, permissionNames []string) error + + //ApplicationRoles + FindAppOrgRoles(appOrgID string) ([]model.AppOrgRole, error) + FindAppOrgRolesByIDs(ids []string, appOrgID string) ([]model.AppOrgRole, error) + FindAppOrgRole(id string, appOrgID string) (*model.AppOrgRole, error) + InsertAppOrgRole(item model.AppOrgRole) error + UpdateAppOrgRole(item model.AppOrgRole) error + DeleteAppOrgRole(id string) error + InsertAppOrgRolePermissions(roleID string, permissionNames []model.Permission) error + //AccountRoles + UpdateAccountRoles(accountID string, roles []model.AccountRole) error + InsertAccountRoles(accountID string, appOrgID string, roles []model.AccountRole) error + DeleteAccountRoles(accountID string, roleIDs []string) error + + //ApplicationGroups + FindAppOrgGroups(appOrgID string) ([]model.AppOrgGroup, error) + FindAppOrgGroupsByIDs(ids []string, appOrgID string) ([]model.AppOrgGroup, error) + FindAppOrgGroup(id string, appOrgID string) (*model.AppOrgGroup, error) + InsertAppOrgGroup(item model.AppOrgGroup) error + UpdateAppOrgGroup(item model.AppOrgGroup) error + DeleteAppOrgGroup(id string) error + CountGroupsByRoleID(roleID string) (*int64, error) + //AccountGroups + InsertAccountGroups(accountID string, appOrgID string, groups []model.AccountGroup) error + InsertAccountsGroup(group model.AccountGroup, accountIDs []string) error + UpdateAccountGroups(accountID string, groups []model.AccountGroup) error + RemoveAccountsGroup(groupID string, accountIDs []string) error + + //GlobalConfigs + CreateGlobalConfig(globalConfig *model.GlobalConfig) error + GetGlobalConfig() (*model.GlobalConfig, error) + DeleteGlobalConfig() error + + //AppConfigs + FindAppConfigs(appTypeIdentifier string, appOrgID *string, versionNumbers *model.VersionNumbers) ([]model.ApplicationConfig, error) + FindAppConfigByVersion(appTypeIdentifier string, appOrgID *string, versionNumbers model.VersionNumbers) (*model.ApplicationConfig, error) + FindAppConfigByID(ID string) (*model.ApplicationConfig, error) + InsertAppConfig(item model.ApplicationConfig) (*model.ApplicationConfig, error) + UpdateAppConfig(ID string, appType model.ApplicationType, appOrg *model.ApplicationOrganization, version model.Version, data map[string]interface{}) error + DeleteAppConfig(ID string) error +} + +// Listener represents storage listener +type Listener interface { + OnAPIKeysUpdated() + OnAuthTypesUpdated() + OnIdentityProvidersUpdated() + OnServiceRegsUpdated() + OnOrganizationsUpdated() + OnApplicationsUpdated() + OnApplicationsOrganizationsUpdated() + OnApplicationConfigsUpdated() +} + +// ProfileBuildingBlock is used by auth to communicate with the profile building block. +type ProfileBuildingBlock interface { + GetProfileBBData(queryParams map[string]string, l *logs.Log) (*model.Profile, map[string]interface{}, error) +} + +// Emailer is used by core to send emails +type Emailer interface { + Send(toEmail string, subject string, body string, attachmentFilename *string) error +} diff --git a/driven/storage/adapter.go b/driven/storage/adapter.go index d2c3e1d9f..d2b2abe63 100644 --- a/driven/storage/adapter.go +++ b/driven/storage/adapter.go @@ -16,6 +16,7 @@ package storage import ( "context" + "core-building-block/core/interfaces" "core-building-block/core/model" "core-building-block/utils" "fmt" @@ -40,6 +41,8 @@ import ( type Adapter struct { db *database + context mongo.SessionContext + logger *logs.Logger cachedServiceRegs *syncmap.Map @@ -113,29 +116,31 @@ func (sa *Adapter) Start() error { } // RegisterStorageListener registers a data change listener with the storage adapter -func (sa *Adapter) RegisterStorageListener(storageListener Listener) { +func (sa *Adapter) RegisterStorageListener(storageListener interfaces.Listener) { sa.db.listeners = append(sa.db.listeners, storageListener) } // PerformTransaction performs a transaction -func (sa *Adapter) PerformTransaction(transaction func(context TransactionContext) error) error { +func (sa *Adapter) PerformTransaction(transaction func(sa interfaces.Storage) error) error { // transaction err := sa.db.dbClient.UseSession(context.Background(), func(sessionContext mongo.SessionContext) error { - err := sessionContext.StartTransaction() + adapter := sa.withContext(sessionContext) + + err := sa.context.StartTransaction() if err != nil { - sa.abortTransaction(sessionContext) + adapter.abortTransaction() return errors.WrapErrorAction(logutils.ActionStart, logutils.TypeTransaction, nil, err) } - err = transaction(sessionContext) + err = transaction(adapter) if err != nil { - sa.abortTransaction(sessionContext) + sa.abortTransaction() return errors.WrapErrorAction("performing", logutils.TypeTransaction, nil, err) } - err = sessionContext.CommitTransaction(sessionContext) + err = sa.context.CommitTransaction(sa.context) if err != nil { - sa.abortTransaction(sessionContext) + sa.abortTransaction() return errors.WrapErrorAction(logutils.ActionCommit, logutils.TypeTransaction, nil, err) } return nil @@ -724,10 +729,10 @@ func (sa *Adapter) FindAuthTypes() ([]model.AuthType, error) { } // InsertLoginSession inserts login session -func (sa *Adapter) InsertLoginSession(context TransactionContext, session model.LoginSession) error { +func (sa *Adapter) InsertLoginSession(session model.LoginSession) error { storageLoginSession := loginSessionToStorage(session) - _, err := sa.db.loginsSessions.InsertOneWithContext(context, storageLoginSession) + _, err := sa.db.loginsSessions.InsertOneWithContext(sa.context, storageLoginSession) if err != nil { return errors.WrapErrorAction(logutils.ActionInsert, model.TypeLoginSession, nil, err) } @@ -736,19 +741,19 @@ func (sa *Adapter) InsertLoginSession(context TransactionContext, session model. } // FindLoginSessions finds login sessions by identifier and sorts by date created -func (sa *Adapter) FindLoginSessions(context TransactionContext, identifier string) ([]model.LoginSession, error) { +func (sa *Adapter) FindLoginSessions(identifier string) ([]model.LoginSession, error) { filter := bson.D{primitive.E{Key: "identifier", Value: identifier}} opts := options.Find() opts.SetSort(bson.D{primitive.E{Key: "date_created", Value: 1}}) var loginSessions []loginSession - err := sa.db.loginsSessions.FindWithContext(context, filter, &loginSessions, opts) + err := sa.db.loginsSessions.FindWithContext(sa.context, filter, &loginSessions, opts) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeLoginSession, &logutils.FieldArgs{"identifier": identifier}, err) } //account - from storage - account, err := sa.FindAccountByID(context, identifier) + account, err := sa.FindAccountByID(identifier) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, &logutils.FieldArgs{"_id": identifier}, err) } @@ -834,7 +839,7 @@ func (sa *Adapter) FindLoginSessionsByParams(appID string, orgID string, session loginSessions := make([]model.LoginSession, len(result)) for i, ls := range result { //we could allow calling buildLoginSession function as we have limitted the items to max 20 - loginSession, err := sa.buildLoginSession(nil, &ls) + loginSession, err := sa.buildLoginSession(&ls) if err != nil { return nil, errors.WrapErrorAction("build", model.TypeLoginSession, nil, err) } @@ -858,11 +863,11 @@ func (sa *Adapter) FindLoginSession(refreshToken string) (*model.LoginSession, e } loginSession := loginsSessions[0] - return sa.buildLoginSession(nil, &loginSession) + return sa.buildLoginSession(&loginSession) } // FindAndUpdateLoginSession finds and updates a login session -func (sa *Adapter) FindAndUpdateLoginSession(context TransactionContext, id string) (*model.LoginSession, error) { +func (sa *Adapter) FindAndUpdateLoginSession(id string) (*model.LoginSession, error) { //find loggin session filter := bson.D{primitive.E{Key: "_id", Value: id}} update := bson.D{ @@ -877,20 +882,20 @@ func (sa *Adapter) FindAndUpdateLoginSession(context TransactionContext, id stri opts.SetReturnDocument(options.Before) var loginSession loginSession - err := sa.db.loginsSessions.FindOneAndUpdateWithContext(context, filter, update, &loginSession, &opts) + err := sa.db.loginsSessions.FindOneAndUpdateWithContext(sa.context, filter, update, &loginSession, &opts) if err != nil { return nil, errors.WrapErrorAction("finding and updating", model.TypeLoginSession, &logutils.FieldArgs{"_id": id}, err) } - return sa.buildLoginSession(context, &loginSession) + return sa.buildLoginSession(&loginSession) } -func (sa *Adapter) buildLoginSession(context TransactionContext, ls *loginSession) (*model.LoginSession, error) { +func (sa *Adapter) buildLoginSession(ls *loginSession) (*model.LoginSession, error) { //account - from storage var account *model.Account var err error if ls.AccountAuthTypeID != nil { - account, err = sa.FindAccountByID(context, ls.Identifier) + account, err = sa.FindAccountByID(ls.Identifier) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, &logutils.FieldArgs{"_id": ls.Identifier}, err) } @@ -919,11 +924,11 @@ func (sa *Adapter) buildLoginSession(context TransactionContext, ls *loginSessio } // UpdateLoginSession updates login session -func (sa *Adapter) UpdateLoginSession(context TransactionContext, loginSession model.LoginSession) error { +func (sa *Adapter) UpdateLoginSession(loginSession model.LoginSession) error { storageLoginSession := loginSessionToStorage(loginSession) filter := bson.D{primitive.E{Key: "_id", Value: storageLoginSession.ID}} - err := sa.db.loginsSessions.ReplaceOneWithContext(context, filter, storageLoginSession, nil) + err := sa.db.loginsSessions.ReplaceOneWithContext(sa.context, filter, storageLoginSession, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeLoginSession, &logutils.FieldArgs{"_id": storageLoginSession.ID}, err) } @@ -932,10 +937,10 @@ func (sa *Adapter) UpdateLoginSession(context TransactionContext, loginSession m } // DeleteLoginSession deletes login session -func (sa *Adapter) DeleteLoginSession(context TransactionContext, id string) error { +func (sa *Adapter) DeleteLoginSession(id string) error { filter := bson.M{"_id": id} - res, err := sa.db.loginsSessions.DeleteOneWithContext(context, filter, nil) + res, err := sa.db.loginsSessions.DeleteOneWithContext(sa.context, filter, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionDelete, model.TypeLoginSession, &logutils.FieldArgs{"_id": id}, err) } @@ -946,18 +951,11 @@ func (sa *Adapter) DeleteLoginSession(context TransactionContext, id string) err } // DeleteLoginSessionsByIDs deletes login sessions by ids -func (sa *Adapter) DeleteLoginSessionsByIDs(transaction TransactionContext, ids []string) error { +func (sa *Adapter) DeleteLoginSessionsByIDs(ids []string) error { filter := bson.D{primitive.E{Key: "_id", Value: bson.M{"$in": ids}}} - var res *mongo.DeleteResult - var err error timeout := time.Millisecond * time.Duration(5000) //5 seconds - if transaction != nil { - res, err = sa.db.loginsSessions.DeleteManyWithParams(transaction, filter, nil, &timeout) - } else { - res, err = sa.db.loginsSessions.DeleteManyWithParams(context.Background(), filter, nil, &timeout) - } - + res, err := sa.db.loginsSessions.DeleteManyWithParams(sa.context, filter, nil, &timeout) if err != nil { return errors.WrapErrorAction(logutils.ActionDelete, model.TypeLoginSession, &logutils.FieldArgs{"identifier": ids}, err) @@ -968,24 +966,19 @@ func (sa *Adapter) DeleteLoginSessionsByIDs(transaction TransactionContext, ids } // DeleteLoginSessionsByIdentifier deletes all login sessions with the identifier -func (sa *Adapter) DeleteLoginSessionsByIdentifier(context TransactionContext, identifier string) error { - return sa.deleteLoginSessions(context, "identifier", identifier, false) -} - -// DeleteLoginSessionByID deletes a login session by id -func (sa *Adapter) DeleteLoginSessionByID(context TransactionContext, id string) error { - return sa.deleteLoginSessions(context, "_id", id, true) +func (sa *Adapter) DeleteLoginSessionsByIdentifier(identifier string) error { + return sa.deleteLoginSessions("identifier", identifier, false) } // DeleteLoginSessionsByAccountAuthTypeID deletes login sessions by account auth type ID -func (sa *Adapter) DeleteLoginSessionsByAccountAuthTypeID(context TransactionContext, id string) error { - return sa.deleteLoginSessions(context, "account_auth_type_id", id, false) +func (sa *Adapter) DeleteLoginSessionsByAccountAuthTypeID(id string) error { + return sa.deleteLoginSessions("account_auth_type_id", id, false) } -func (sa *Adapter) deleteLoginSessions(context TransactionContext, key string, value string, checkDeletedCount bool) error { +func (sa *Adapter) deleteLoginSessions(key string, value string, checkDeletedCount bool) error { filter := bson.M{key: value} - res, err := sa.db.loginsSessions.DeleteManyWithContext(context, filter, nil) + res, err := sa.db.loginsSessions.DeleteManyWithContext(sa.context, filter, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionDelete, model.TypeLoginSession, &logutils.FieldArgs{key: value}, err) } @@ -996,7 +989,7 @@ func (sa *Adapter) deleteLoginSessions(context TransactionContext, key string, v } // DeleteLoginSessionsByAccountAndSessionID deletes all login sessions with the identifier and sessionID -func (sa *Adapter) DeleteLoginSessionsByAccountAndSessionID(context TransactionContext, identifier string, sessionID string) error { +func (sa *Adapter) DeleteLoginSessionsByAccountAndSessionID(identifier string, sessionID string) error { filter := bson.M{"identifier": identifier, "_id": sessionID} result, err := sa.db.loginsSessions.DeleteOne(filter, nil) if err != nil { @@ -1066,12 +1059,12 @@ func (sa *Adapter) FindSessionsLazy(appID string, orgID string) ([]model.LoginSe } // FindAccount finds an account for app, org, auth type and account auth type identifier -func (sa *Adapter) FindAccount(context TransactionContext, appOrgID string, authTypeID string, accountAuthTypeIdentifier string) (*model.Account, error) { +func (sa *Adapter) FindAccount(appOrgID string, authTypeID string, accountAuthTypeIdentifier string) (*model.Account, error) { filter := bson.D{primitive.E{Key: "app_org_id", Value: appOrgID}, primitive.E{Key: "auth_types.auth_type_id", Value: authTypeID}, primitive.E{Key: "auth_types.identifier", Value: accountAuthTypeIdentifier}} var accounts []account - err := sa.db.accounts.FindWithContext(context, filter, &accounts, nil) + err := sa.db.accounts.FindWithContext(sa.context, filter, &accounts, nil) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) } @@ -1095,7 +1088,7 @@ func (sa *Adapter) FindAccount(context TransactionContext, appOrgID string, auth } // FindAccounts finds accounts -func (sa *Adapter) FindAccounts(context TransactionContext, limit *int, offset *int, appID string, orgID string, accountID *string, firstName *string, lastName *string, authType *string, +func (sa *Adapter) FindAccounts(limit *int, offset *int, appID string, orgID string, accountID *string, firstName *string, lastName *string, authType *string, authTypeIdentifier *string, anonymous *bool, hasPermissions *bool, permissions []string, roleIDs []string, groupIDs []string) ([]model.Account, error) { //find app org id appOrg, err := sa.getCachedApplicationOrganization(appID, orgID) @@ -1178,7 +1171,7 @@ func (sa *Adapter) FindAccounts(context TransactionContext, limit *int, offset * findOptions.SetSkip(int64(*offset)) } - err = sa.db.accounts.FindWithContext(context, filter, &list, findOptions) + err = sa.db.accounts.FindWithContext(sa.context, filter, &list, findOptions) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) } @@ -1254,7 +1247,7 @@ func (sa *Adapter) CountAccountsByParams(searchParams map[string]interface{}, ap } // FindAccountsByAccountID finds accounts -func (sa *Adapter) FindAccountsByAccountID(context TransactionContext, appID string, orgID string, accountIDs []string) ([]model.Account, error) { +func (sa *Adapter) FindAccountsByAccountID(appID string, orgID string, accountIDs []string) ([]model.Account, error) { if len(accountIDs) == 0 { return make([]model.Account, 0), nil } @@ -1267,7 +1260,7 @@ func (sa *Adapter) FindAccountsByAccountID(context TransactionContext, appID str accountFilter := bson.D{primitive.E{Key: "_id", Value: bson.M{"$in": accountIDs}}, primitive.E{Key: "app_org_id", Value: appOrg.ID}} var accountResult []account - err = sa.db.accounts.FindWithContext(context, accountFilter, &accountResult, nil) + err = sa.db.accounts.FindWithContext(sa.context, accountFilter, &accountResult, nil) if err != nil { return nil, err } @@ -1276,7 +1269,7 @@ func (sa *Adapter) FindAccountsByAccountID(context TransactionContext, appID str } // FindAccountsByUsername finds accounts with a username for a given appOrg -func (sa *Adapter) FindAccountsByUsername(context TransactionContext, appOrg *model.ApplicationOrganization, username string) ([]model.Account, error) { +func (sa *Adapter) FindAccountsByUsername(appOrg *model.ApplicationOrganization, username string) ([]model.Account, error) { if appOrg == nil { return nil, errors.ErrorData(logutils.StatusMissing, model.TypeApplicationOrganization, nil) } @@ -1297,17 +1290,17 @@ func (sa *Adapter) FindAccountsByUsername(context TransactionContext, appOrg *mo } // FindAccountByID finds an account by id -func (sa *Adapter) FindAccountByID(context TransactionContext, id string) (*model.Account, error) { - return sa.findAccount(context, "_id", id) +func (sa *Adapter) FindAccountByID(id string) (*model.Account, error) { + return sa.findAccount("_id", id) } // FindAccountByAuthTypeID finds an account by auth type id -func (sa *Adapter) FindAccountByAuthTypeID(context TransactionContext, id string) (*model.Account, error) { - return sa.findAccount(context, "auth_types.id", id) +func (sa *Adapter) FindAccountByAuthTypeID(id string) (*model.Account, error) { + return sa.findAccount("auth_types.id", id) } -func (sa *Adapter) findAccount(context TransactionContext, key string, id string) (*model.Account, error) { - account, err := sa.findStorageAccount(context, key, id) +func (sa *Adapter) findAccount(key string, id string) (*model.Account, error) { + account, err := sa.findStorageAccount(key, id) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) } @@ -1330,10 +1323,10 @@ func (sa *Adapter) findAccount(context TransactionContext, key string, id string return &modelAccount, nil } -func (sa *Adapter) findStorageAccount(context TransactionContext, key string, id string) (*account, error) { +func (sa *Adapter) findStorageAccount(key string, id string) (*account, error) { filter := bson.M{key: id} var accounts []account - err := sa.db.accounts.FindWithContext(context, filter, &accounts, nil) + err := sa.db.accounts.FindWithContext(sa.context, filter, &accounts, nil) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, &logutils.FieldArgs{key: id}, err) } @@ -1347,10 +1340,10 @@ func (sa *Adapter) findStorageAccount(context TransactionContext, key string, id } // InsertAccount inserts an account -func (sa *Adapter) InsertAccount(context TransactionContext, account model.Account) (*model.Account, error) { +func (sa *Adapter) InsertAccount(account model.Account) (*model.Account, error) { storageAccount := accountToStorage(&account) - _, err := sa.db.accounts.InsertOneWithContext(context, storageAccount) + _, err := sa.db.accounts.InsertOneWithContext(sa.context, storageAccount) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionInsert, model.TypeAccount, nil, err) } @@ -1359,7 +1352,7 @@ func (sa *Adapter) InsertAccount(context TransactionContext, account model.Accou } // SaveAccount saves an existing account -func (sa *Adapter) SaveAccount(context TransactionContext, account *model.Account) error { +func (sa *Adapter) SaveAccount(account *model.Account) error { if account == nil { return errors.ErrorData(logutils.StatusInvalid, logutils.TypeArg, logutils.StringArgs("account")) } @@ -1367,7 +1360,7 @@ func (sa *Adapter) SaveAccount(context TransactionContext, account *model.Accoun storageAccount := accountToStorage(account) filter := bson.M{"_id": account.ID} - err := sa.db.accounts.ReplaceOneWithContext(context, filter, storageAccount, nil) + err := sa.db.accounts.ReplaceOneWithContext(sa.context, filter, storageAccount, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeAccount, nil, err) } @@ -1376,7 +1369,7 @@ func (sa *Adapter) SaveAccount(context TransactionContext, account *model.Accoun } // UpdateAccountUsageInfo updates the usage information in accounts -func (sa *Adapter) UpdateAccountUsageInfo(context TransactionContext, accountID string, updateLoginTime bool, updateAccessTokenTime bool, clientVersion *string) error { +func (sa *Adapter) UpdateAccountUsageInfo(accountID string, updateLoginTime bool, updateAccessTokenTime bool, clientVersion *string) error { filter := bson.D{primitive.E{Key: "_id", Value: accountID}} now := time.Now().UTC() update := bson.M{} @@ -1391,7 +1384,7 @@ func (sa *Adapter) UpdateAccountUsageInfo(context TransactionContext, accountID } usageInfoUpdate := bson.M{"$set": update} - res, err := sa.db.accounts.UpdateOneWithContext(context, filter, usageInfoUpdate, nil) + res, err := sa.db.accounts.UpdateOneWithContext(sa.context, filter, usageInfoUpdate, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeAccountUsageInfo, nil, err) } @@ -1403,11 +1396,11 @@ func (sa *Adapter) UpdateAccountUsageInfo(context TransactionContext, accountID } // DeleteAccount deletes an account -func (sa *Adapter) DeleteAccount(context TransactionContext, id string) error { +func (sa *Adapter) DeleteAccount(id string) error { //TODO - we have to decide what we do on delete user operation - removing all user relations, (or) mark the user disabled etc filter := bson.M{"_id": id} - res, err := sa.db.accounts.DeleteOneWithContext(context, filter, nil) + res, err := sa.db.accounts.DeleteOneWithContext(sa.context, filter, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionDelete, model.TypeAccount, nil, err) } @@ -1419,12 +1412,12 @@ func (sa *Adapter) DeleteAccount(context TransactionContext, id string) error { } // FindServiceAccount finds a service account by accountID, appID, and orgID -func (sa *Adapter) FindServiceAccount(context TransactionContext, accountID string, appID string, orgID string) (*model.ServiceAccount, error) { +func (sa *Adapter) FindServiceAccount(accountID string, appID string, orgID string) (*model.ServiceAccount, error) { filter := bson.D{primitive.E{Key: "account_id", Value: accountID}, primitive.E{Key: "app_id", Value: appID}, primitive.E{Key: "org_id", Value: orgID}} var account serviceAccount errFields := logutils.FieldArgs{"account_id": accountID, "app_id": appID, "org_id": orgID} - err := sa.db.serviceAccounts.FindOneWithContext(context, filter, &account, nil) + err := sa.db.serviceAccounts.FindOneWithContext(sa.context, filter, &account, nil) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeServiceAccount, &errFields, err) } @@ -1479,7 +1472,7 @@ func (sa *Adapter) InsertServiceAccount(account *model.ServiceAccount) error { } // UpdateServiceAccount updates a service account -func (sa *Adapter) UpdateServiceAccount(context TransactionContext, account *model.ServiceAccount) (*model.ServiceAccount, error) { +func (sa *Adapter) UpdateServiceAccount(account *model.ServiceAccount) (*model.ServiceAccount, error) { if account == nil { return nil, errors.ErrorData(logutils.StatusInvalid, model.TypeServiceAccount, nil) } @@ -1501,7 +1494,7 @@ func (sa *Adapter) UpdateServiceAccount(context TransactionContext, account *mod var updated serviceAccount errFields := logutils.FieldArgs{"account_id": storageAccount.AccountID, "app_id": storageAccount.AppID, "org_id": storageAccount.OrgID} - err := sa.db.serviceAccounts.FindOneAndUpdateWithContext(context, filter, update, &updated, &opts) + err := sa.db.serviceAccounts.FindOneAndUpdateWithContext(sa.context, filter, update, &updated, &opts) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionUpdate, model.TypeServiceAccount, &errFields, err) } @@ -1605,7 +1598,7 @@ func (sa *Adapter) DeleteServiceAccountCredential(accountID string, credID strin } // UpdateAccountPreferences updates account preferences -func (sa *Adapter) UpdateAccountPreferences(context TransactionContext, accountID string, preferences map[string]interface{}) error { +func (sa *Adapter) UpdateAccountPreferences(accountID string, preferences map[string]interface{}) error { filter := bson.D{primitive.E{Key: "_id", Value: accountID}} update := bson.D{ primitive.E{Key: "$set", Value: bson.D{ @@ -1614,7 +1607,7 @@ func (sa *Adapter) UpdateAccountPreferences(context TransactionContext, accountI }}, } - res, err := sa.db.accounts.UpdateOneWithContext(context, filter, update, nil) + res, err := sa.db.accounts.UpdateOneWithContext(sa.context, filter, update, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeAccountPreferences, nil, err) } @@ -1626,7 +1619,7 @@ func (sa *Adapter) UpdateAccountPreferences(context TransactionContext, accountI } // UpdateAccountSystemConfigs updates account system configs -func (sa *Adapter) UpdateAccountSystemConfigs(context TransactionContext, accountID string, configs map[string]interface{}) error { +func (sa *Adapter) UpdateAccountSystemConfigs(accountID string, configs map[string]interface{}) error { filter := bson.D{primitive.E{Key: "_id", Value: accountID}} update := bson.D{ primitive.E{Key: "$set", Value: bson.D{ @@ -1647,7 +1640,7 @@ func (sa *Adapter) UpdateAccountSystemConfigs(context TransactionContext, accoun } // InsertAccountPermissions inserts account permissions -func (sa *Adapter) InsertAccountPermissions(context TransactionContext, accountID string, permissions []model.Permission) error { +func (sa *Adapter) InsertAccountPermissions(accountID string, permissions []model.Permission) error { filter := bson.D{primitive.E{Key: "_id", Value: accountID}} update := bson.D{ primitive.E{Key: "$push", Value: bson.D{ @@ -1658,7 +1651,7 @@ func (sa *Adapter) InsertAccountPermissions(context TransactionContext, accountI }}, } - res, err := sa.db.accounts.UpdateOneWithContext(context, filter, update, nil) + res, err := sa.db.accounts.UpdateOneWithContext(sa.context, filter, update, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeAccount, nil, err) } @@ -1670,7 +1663,7 @@ func (sa *Adapter) InsertAccountPermissions(context TransactionContext, accountI } // UpdateAccountPermissions updates account permissions -func (sa *Adapter) UpdateAccountPermissions(context TransactionContext, accountID string, permissions []model.Permission) error { +func (sa *Adapter) UpdateAccountPermissions(accountID string, permissions []model.Permission) error { filter := bson.D{primitive.E{Key: "_id", Value: accountID}} update := bson.D{ primitive.E{Key: "$set", Value: bson.D{ @@ -1679,7 +1672,7 @@ func (sa *Adapter) UpdateAccountPermissions(context TransactionContext, accountI }}, } - res, err := sa.db.accounts.UpdateOneWithContext(context, filter, update, nil) + res, err := sa.db.accounts.UpdateOneWithContext(sa.context, filter, update, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeAccount, nil, err) } @@ -1691,7 +1684,7 @@ func (sa *Adapter) UpdateAccountPermissions(context TransactionContext, accountI } // DeleteAccountPermissions deletes permissions from an account -func (sa *Adapter) DeleteAccountPermissions(context TransactionContext, accountID string, permissionNames []string) error { +func (sa *Adapter) DeleteAccountPermissions(accountID string, permissionNames []string) error { //filter filter := bson.D{primitive.E{Key: "_id", Value: accountID}} @@ -1705,7 +1698,7 @@ func (sa *Adapter) DeleteAccountPermissions(context TransactionContext, accountI }}, } - res, err := sa.db.accounts.UpdateOneWithContext(context, filter, update, nil) + res, err := sa.db.accounts.UpdateOneWithContext(sa.context, filter, update, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeAccount, nil, err) } @@ -1716,7 +1709,7 @@ func (sa *Adapter) DeleteAccountPermissions(context TransactionContext, accountI } // UpdateAccountUsername updates an account's username -func (sa *Adapter) UpdateAccountUsername(context TransactionContext, accountID string, username string) error { +func (sa *Adapter) UpdateAccountUsername(accountID string, username string) error { filter := bson.D{primitive.E{Key: "_id", Value: accountID}} update := bson.D{ primitive.E{Key: "$set", Value: bson.D{ @@ -1725,7 +1718,7 @@ func (sa *Adapter) UpdateAccountUsername(context TransactionContext, accountID s }}, } - res, err := sa.db.accounts.UpdateOneWithContext(context, filter, update, nil) + res, err := sa.db.accounts.UpdateOneWithContext(sa.context, filter, update, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeAccount, &logutils.FieldArgs{"id": accountID}, err) } @@ -1737,7 +1730,7 @@ func (sa *Adapter) UpdateAccountUsername(context TransactionContext, accountID s } // InsertAccountRoles inserts account roles -func (sa *Adapter) InsertAccountRoles(context TransactionContext, accountID string, appOrgID string, roles []model.AccountRole) error { +func (sa *Adapter) InsertAccountRoles(accountID string, appOrgID string, roles []model.AccountRole) error { stgRoles := accountRolesToStorage(roles) //appID included in search to prevent accidentally assigning permissions to account from different application @@ -1751,7 +1744,7 @@ func (sa *Adapter) InsertAccountRoles(context TransactionContext, accountID stri }}, } - res, err := sa.db.accounts.UpdateOneWithContext(context, filter, update, nil) + res, err := sa.db.accounts.UpdateOneWithContext(sa.context, filter, update, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeAccount, nil, err) } @@ -1763,7 +1756,7 @@ func (sa *Adapter) InsertAccountRoles(context TransactionContext, accountID stri } // InsertAccountGroups inserts account groups -func (sa *Adapter) InsertAccountGroups(context TransactionContext, accountID string, appOrgID string, groups []model.AccountGroup) error { +func (sa *Adapter) InsertAccountGroups(accountID string, appOrgID string, groups []model.AccountGroup) error { stgGroups := accountGroupsToStorage(groups) //appID included in search to prevent accidentally assigning permissions to account from different application @@ -1777,7 +1770,7 @@ func (sa *Adapter) InsertAccountGroups(context TransactionContext, accountID str }}, } - res, err := sa.db.accounts.UpdateOneWithContext(context, filter, update, nil) + res, err := sa.db.accounts.UpdateOneWithContext(sa.context, filter, update, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeAccount, &logutils.FieldArgs{"_id": accountID, "app_org_id": appOrgID}, err) } @@ -1789,7 +1782,7 @@ func (sa *Adapter) InsertAccountGroups(context TransactionContext, accountID str } // InsertAccountsGroup inserts accounts into a group -func (sa *Adapter) InsertAccountsGroup(context TransactionContext, group model.AccountGroup, accountIDs []string) error { +func (sa *Adapter) InsertAccountsGroup(group model.AccountGroup, accountIDs []string) error { if len(accountIDs) == 0 { return nil } @@ -1808,7 +1801,7 @@ func (sa *Adapter) InsertAccountsGroup(context TransactionContext, group model.A }}, } - res, err := sa.db.accounts.UpdateManyWithContext(context, filter, update, nil) + res, err := sa.db.accounts.UpdateManyWithContext(sa.context, filter, update, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeAccount, nil, err) } @@ -1817,7 +1810,7 @@ func (sa *Adapter) InsertAccountsGroup(context TransactionContext, group model.A } // RemoveAccountsGroup removes accounts from a group -func (sa *Adapter) RemoveAccountsGroup(context TransactionContext, groupID string, accountIDs []string) error { +func (sa *Adapter) RemoveAccountsGroup(groupID string, accountIDs []string) error { if len(accountIDs) == 0 { return nil } @@ -1832,7 +1825,7 @@ func (sa *Adapter) RemoveAccountsGroup(context TransactionContext, groupID strin }}, } - res, err := sa.db.accounts.UpdateManyWithContext(context, filter, update, nil) + res, err := sa.db.accounts.UpdateManyWithContext(sa.context, filter, update, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeAccount, &logutils.FieldArgs{"group_id": groupID}, err) } @@ -1845,7 +1838,7 @@ func (sa *Adapter) RemoveAccountsGroup(context TransactionContext, groupID strin } // UpdateAccountRoles updates the account roles -func (sa *Adapter) UpdateAccountRoles(context TransactionContext, accountID string, roles []model.AccountRole) error { +func (sa *Adapter) UpdateAccountRoles(accountID string, roles []model.AccountRole) error { stgRoles := accountRolesToStorage(roles) filter := bson.D{primitive.E{Key: "_id", Value: accountID}} @@ -1856,7 +1849,7 @@ func (sa *Adapter) UpdateAccountRoles(context TransactionContext, accountID stri }}, } - res, err := sa.db.accounts.UpdateOneWithContext(context, filter, update, nil) + res, err := sa.db.accounts.UpdateOneWithContext(sa.context, filter, update, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) } @@ -1868,7 +1861,7 @@ func (sa *Adapter) UpdateAccountRoles(context TransactionContext, accountID stri } // DeleteAccountRoles deletes account roles -func (sa *Adapter) DeleteAccountRoles(context TransactionContext, accountID string, roleIDs []string) error { +func (sa *Adapter) DeleteAccountRoles(accountID string, roleIDs []string) error { //filter filter := bson.D{primitive.E{Key: "_id", Value: accountID}} @@ -1882,7 +1875,7 @@ func (sa *Adapter) DeleteAccountRoles(context TransactionContext, accountID stri }}, } - res, err := sa.db.accounts.UpdateOneWithContext(context, filter, update, nil) + res, err := sa.db.accounts.UpdateOneWithContext(sa.context, filter, update, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) } @@ -1893,7 +1886,7 @@ func (sa *Adapter) DeleteAccountRoles(context TransactionContext, accountID stri } // UpdateAccountGroups updates the account groups -func (sa *Adapter) UpdateAccountGroups(context TransactionContext, accountID string, groups []model.AccountGroup) error { +func (sa *Adapter) UpdateAccountGroups(accountID string, groups []model.AccountGroup) error { stgGroups := accountGroupsToStorage(groups) filter := bson.D{primitive.E{Key: "_id", Value: accountID}} @@ -1904,7 +1897,7 @@ func (sa *Adapter) UpdateAccountGroups(context TransactionContext, accountID str }}, } - res, err := sa.db.accounts.UpdateOneWithContext(context, filter, update, nil) + res, err := sa.db.accounts.UpdateOneWithContext(sa.context, filter, update, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) } @@ -2005,7 +1998,7 @@ func (sa *Adapter) UpdateAccountAuthType(item model.AccountAuthType) error { } // DeleteAccountAuthType deletes an account auth type -func (sa *Adapter) DeleteAccountAuthType(context TransactionContext, item model.AccountAuthType) error { +func (sa *Adapter) DeleteAccountAuthType(item model.AccountAuthType) error { filter := bson.M{"_id": item.Account.ID} update := bson.D{ primitive.E{Key: "$pull", Value: bson.D{ @@ -2013,7 +2006,7 @@ func (sa *Adapter) DeleteAccountAuthType(context TransactionContext, item model. }}, } - res, err := sa.db.accounts.UpdateOneWithContext(context, filter, update, nil) + res, err := sa.db.accounts.UpdateOneWithContext(sa.context, filter, update, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionDelete, model.TypeAccountAuthType, nil, err) } @@ -2088,11 +2081,11 @@ func (sa *Adapter) CountAccountsByGroupID(groupID string) (*int64, error) { } // FindCredential finds a credential by ID -func (sa *Adapter) FindCredential(context TransactionContext, ID string) (*model.Credential, error) { +func (sa *Adapter) FindCredential(ID string) (*model.Credential, error) { filter := bson.D{primitive.E{Key: "_id", Value: ID}} var creds credential - err := sa.db.credentials.FindOneWithContext(context, filter, &creds, nil) + err := sa.db.credentials.FindOneWithContext(sa.context, filter, &creds, nil) if err != nil { if err.Error() == "mongo: no documents in result" { return nil, nil @@ -2105,14 +2098,14 @@ func (sa *Adapter) FindCredential(context TransactionContext, ID string) (*model } // InsertCredential inserts a set of credential -func (sa *Adapter) InsertCredential(context TransactionContext, creds *model.Credential) error { +func (sa *Adapter) InsertCredential(creds *model.Credential) error { storageCreds := credentialToStorage(creds) if storageCreds == nil { return errors.ErrorData(logutils.StatusInvalid, logutils.TypeArg, logutils.StringArgs(model.TypeCredential)) } - _, err := sa.db.credentials.InsertOneWithContext(context, storageCreds) + _, err := sa.db.credentials.InsertOneWithContext(sa.context, storageCreds) if err != nil { return errors.WrapErrorAction(logutils.ActionInsert, model.TypeCredential, nil, err) } @@ -2121,7 +2114,7 @@ func (sa *Adapter) InsertCredential(context TransactionContext, creds *model.Cre } // UpdateCredential updates a set of credentials -func (sa *Adapter) UpdateCredential(context TransactionContext, creds *model.Credential) error { +func (sa *Adapter) UpdateCredential(creds *model.Credential) error { storageCreds := credentialToStorage(creds) if storageCreds == nil { @@ -2129,7 +2122,7 @@ func (sa *Adapter) UpdateCredential(context TransactionContext, creds *model.Cre } filter := bson.D{primitive.E{Key: "_id", Value: storageCreds.ID}} - err := sa.db.credentials.ReplaceOneWithContext(context, filter, storageCreds, nil) + err := sa.db.credentials.ReplaceOneWithContext(sa.context, filter, storageCreds, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeCredential, &logutils.FieldArgs{"_id": storageCreds.ID}, err) } @@ -2158,10 +2151,10 @@ func (sa *Adapter) UpdateCredentialValue(ID string, value map[string]interface{} } // DeleteCredential deletes a credential -func (sa *Adapter) DeleteCredential(context TransactionContext, ID string) error { +func (sa *Adapter) DeleteCredential(ID string) error { filter := bson.D{primitive.E{Key: "_id", Value: ID}} - res, err := sa.db.credentials.DeleteOneWithContext(context, filter, nil) + res, err := sa.db.credentials.DeleteOneWithContext(sa.context, filter, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionDelete, model.TypeCredential, &logutils.FieldArgs{"_id": ID}, err) } @@ -2173,7 +2166,7 @@ func (sa *Adapter) DeleteCredential(context TransactionContext, ID string) error } // FindMFAType finds one MFA type for an account -func (sa *Adapter) FindMFAType(context TransactionContext, accountID string, identifier string, mfaType string) (*model.MFAType, error) { +func (sa *Adapter) FindMFAType(accountID string, identifier string, mfaType string) (*model.MFAType, error) { filter := bson.D{ primitive.E{Key: "_id", Value: accountID}, primitive.E{Key: "mfa_types.type", Value: mfaType}, @@ -2181,7 +2174,7 @@ func (sa *Adapter) FindMFAType(context TransactionContext, accountID string, ide } var account account - err := sa.db.accounts.FindOneWithContext(context, filter, &account, nil) + err := sa.db.accounts.FindOneWithContext(sa.context, filter, &account, nil) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeAccount, nil, err) } @@ -2210,7 +2203,7 @@ func (sa *Adapter) FindMFATypes(accountID string) ([]model.MFAType, error) { } // InsertMFAType inserts a MFA type -func (sa *Adapter) InsertMFAType(context TransactionContext, mfa *model.MFAType, accountID string) error { +func (sa *Adapter) InsertMFAType(mfa *model.MFAType, accountID string) error { if mfa == nil { return errors.ErrorData(logutils.StatusMissing, model.TypeMFAType, nil) } @@ -2233,7 +2226,7 @@ func (sa *Adapter) InsertMFAType(context TransactionContext, mfa *model.MFAType, }}, } - res, err := sa.db.accounts.UpdateOneWithContext(context, filter, update, nil) + res, err := sa.db.accounts.UpdateOneWithContext(sa.context, filter, update, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeAccount, logutils.StringArgs("inserting mfa type"), err) } @@ -2245,7 +2238,7 @@ func (sa *Adapter) InsertMFAType(context TransactionContext, mfa *model.MFAType, } // UpdateMFAType updates one MFA type -func (sa *Adapter) UpdateMFAType(context TransactionContext, mfa *model.MFAType, accountID string) error { +func (sa *Adapter) UpdateMFAType(mfa *model.MFAType, accountID string) error { if mfa.Params == nil || mfa.Params["identifier"] == nil { return errors.ErrorData(logutils.StatusMissing, "mfa identifier", nil) } @@ -2264,7 +2257,7 @@ func (sa *Adapter) UpdateMFAType(context TransactionContext, mfa *model.MFAType, }}, } - res, err := sa.db.accounts.UpdateOneWithContext(context, filter, update, nil) + res, err := sa.db.accounts.UpdateOneWithContext(sa.context, filter, update, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeAccount, logutils.StringArgs("updating mfa type"), err) } @@ -2279,7 +2272,7 @@ func (sa *Adapter) UpdateMFAType(context TransactionContext, mfa *model.MFAType, } // DeleteMFAType deletes a MFA type -func (sa *Adapter) DeleteMFAType(context TransactionContext, accountID string, identifier string, mfaType string) error { +func (sa *Adapter) DeleteMFAType(accountID string, identifier string, mfaType string) error { filter := bson.D{primitive.E{Key: "_id", Value: accountID}} update := bson.D{ primitive.E{Key: "$pull", Value: bson.D{ @@ -2290,7 +2283,7 @@ func (sa *Adapter) DeleteMFAType(context TransactionContext, accountID string, i }}, } - res, err := sa.db.accounts.UpdateOneWithContext(context, filter, update, nil) + res, err := sa.db.accounts.UpdateOneWithContext(sa.context, filter, update, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeAccount, logutils.StringArgs("deleting mfa type"), err) } @@ -2305,14 +2298,14 @@ func (sa *Adapter) DeleteMFAType(context TransactionContext, accountID string, i } // FindPermissions finds a set of permissions -func (sa *Adapter) FindPermissions(context TransactionContext, ids []string) ([]model.Permission, error) { +func (sa *Adapter) FindPermissions(ids []string) ([]model.Permission, error) { if len(ids) == 0 { return []model.Permission{}, nil } permissionsFilter := bson.D{primitive.E{Key: "_id", Value: bson.M{"$in": ids}}} var permissionsResult []model.Permission - err := sa.db.permissions.FindWithContext(context, permissionsFilter, &permissionsResult, nil) + err := sa.db.permissions.FindWithContext(sa.context, permissionsFilter, &permissionsResult, nil) if err != nil { return nil, err } @@ -2337,14 +2330,14 @@ func (sa *Adapter) FindPermissionsByServiceIDs(serviceIDs []string) ([]model.Per } // FindPermissionsByName finds a set of permissions -func (sa *Adapter) FindPermissionsByName(context TransactionContext, names []string) ([]model.Permission, error) { +func (sa *Adapter) FindPermissionsByName(names []string) ([]model.Permission, error) { if len(names) == 0 { return []model.Permission{}, nil } permissionsFilter := bson.D{primitive.E{Key: "name", Value: bson.M{"$in": names}}} var permissionsResult []model.Permission - err := sa.db.permissions.FindWithContext(context, permissionsFilter, &permissionsResult, nil) + err := sa.db.permissions.FindWithContext(sa.context, permissionsFilter, &permissionsResult, nil) if err != nil { return nil, err } @@ -2353,8 +2346,8 @@ func (sa *Adapter) FindPermissionsByName(context TransactionContext, names []str } // InsertPermission inserts a new permission -func (sa *Adapter) InsertPermission(context TransactionContext, item model.Permission) error { - _, err := sa.db.permissions.InsertOneWithContext(context, item) +func (sa *Adapter) InsertPermission(item model.Permission) error { + _, err := sa.db.permissions.InsertOneWithContext(sa.context, item) if err != nil { return errors.WrapErrorAction(logutils.ActionInsert, model.TypePermission, &logutils.FieldArgs{"_id": item.ID, "name": item.Name}, err) } @@ -2363,7 +2356,7 @@ func (sa *Adapter) InsertPermission(context TransactionContext, item model.Permi } // InsertPermissions inserts permissions -func (sa *Adapter) InsertPermissions(context TransactionContext, items []model.Permission) error { +func (sa *Adapter) InsertPermissions(items []model.Permission) error { if len(items) == 0 { return nil } @@ -2373,7 +2366,7 @@ func (sa *Adapter) InsertPermissions(context TransactionContext, items []model.P stgPermissions[i] = p } - res, err := sa.db.permissions.InsertManyWithContext(context, stgPermissions, nil) + res, err := sa.db.permissions.InsertManyWithContext(sa.context, stgPermissions, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionInsert, model.TypePermission, nil, err) } @@ -2446,14 +2439,14 @@ func (sa *Adapter) FindAppOrgRoles(appOrgID string) ([]model.AppOrgRole, error) } // FindAppOrgRolesByIDs finds a set of application organization roles for the provided IDs -func (sa *Adapter) FindAppOrgRolesByIDs(context TransactionContext, ids []string, appOrgID string) ([]model.AppOrgRole, error) { +func (sa *Adapter) FindAppOrgRolesByIDs(ids []string, appOrgID string) ([]model.AppOrgRole, error) { if len(ids) == 0 { return []model.AppOrgRole{}, nil } rolesFilter := bson.D{primitive.E{Key: "app_org_id", Value: appOrgID}, primitive.E{Key: "_id", Value: bson.M{"$in": ids}}} var rolesResult []appOrgRole - err := sa.db.applicationsOrganizationsRoles.FindWithContext(context, rolesFilter, &rolesResult, nil) + err := sa.db.applicationsOrganizationsRoles.FindWithContext(sa.context, rolesFilter, &rolesResult, nil) if err != nil { return nil, err } @@ -2496,7 +2489,7 @@ func (sa *Adapter) FindAppOrgRole(id string, appOrgID string) (*model.AppOrgRole } // InsertAppOrgRole inserts a new application organization role -func (sa *Adapter) InsertAppOrgRole(context TransactionContext, item model.AppOrgRole) error { +func (sa *Adapter) InsertAppOrgRole(item model.AppOrgRole) error { appOrg, err := sa.getCachedApplicationOrganizationByKey(item.AppOrg.ID) if err != nil { return errors.WrapErrorData(logutils.StatusMissing, model.TypeApplicationOrganization, &logutils.FieldArgs{"app_org_id": item.AppOrg.ID}, err) @@ -2506,7 +2499,7 @@ func (sa *Adapter) InsertAppOrgRole(context TransactionContext, item model.AppOr } role := appOrgRoleToStorage(item) - _, err = sa.db.applicationsOrganizationsRoles.InsertOneWithContext(context, role) + _, err = sa.db.applicationsOrganizationsRoles.InsertOneWithContext(sa.context, role) if err != nil { return errors.WrapErrorAction(logutils.ActionInsert, model.TypeAppOrgRole, nil, err) } @@ -2541,7 +2534,7 @@ func (sa *Adapter) DeleteAppOrgRole(id string) error { } // InsertAppOrgRolePermissions inserts permissions to role -func (sa *Adapter) InsertAppOrgRolePermissions(context TransactionContext, roleID string, permissions []model.Permission) error { +func (sa *Adapter) InsertAppOrgRolePermissions(roleID string, permissions []model.Permission) error { filter := bson.D{primitive.E{Key: "_id", Value: roleID}} update := bson.D{ @@ -2581,14 +2574,14 @@ func (sa *Adapter) FindAppOrgGroups(appOrgID string) ([]model.AppOrgGroup, error } // FindAppOrgGroupsByIDs finds a set of application organization groups for the provided IDs -func (sa *Adapter) FindAppOrgGroupsByIDs(context TransactionContext, ids []string, appOrgID string) ([]model.AppOrgGroup, error) { +func (sa *Adapter) FindAppOrgGroupsByIDs(ids []string, appOrgID string) ([]model.AppOrgGroup, error) { if len(ids) == 0 { return []model.AppOrgGroup{}, nil } filter := bson.D{primitive.E{Key: "app_org_id", Value: appOrgID}, primitive.E{Key: "_id", Value: bson.M{"$in": ids}}} var groupsResult []appOrgGroup - err := sa.db.applicationsOrganizationsGroups.FindWithContext(context, filter, &groupsResult, nil) + err := sa.db.applicationsOrganizationsGroups.FindWithContext(sa.context, filter, &groupsResult, nil) if err != nil { return nil, err } @@ -2607,10 +2600,10 @@ func (sa *Adapter) FindAppOrgGroupsByIDs(context TransactionContext, ids []strin } // FindAppOrgGroup finds a application organization group -func (sa *Adapter) FindAppOrgGroup(context TransactionContext, id string, appOrgID string) (*model.AppOrgGroup, error) { +func (sa *Adapter) FindAppOrgGroup(id string, appOrgID string) (*model.AppOrgGroup, error) { filter := bson.D{primitive.E{Key: "_id", Value: id}, primitive.E{Key: "app_org_id", Value: appOrgID}} var groupsResult []appOrgGroup - err := sa.db.applicationsOrganizationsGroups.FindWithContext(context, filter, &groupsResult, nil) + err := sa.db.applicationsOrganizationsGroups.FindWithContext(sa.context, filter, &groupsResult, nil) if err != nil { return nil, err } @@ -2630,10 +2623,10 @@ func (sa *Adapter) FindAppOrgGroup(context TransactionContext, id string, appOrg } // InsertAppOrgGroup inserts a new application organization group -func (sa *Adapter) InsertAppOrgGroup(context TransactionContext, item model.AppOrgGroup) error { +func (sa *Adapter) InsertAppOrgGroup(item model.AppOrgGroup) error { group := appOrgGroupToStorage(item) - _, err := sa.db.applicationsOrganizationsGroups.InsertOneWithContext(context, group) + _, err := sa.db.applicationsOrganizationsGroups.InsertOneWithContext(sa.context, group) if err != nil { return errors.WrapErrorAction(logutils.ActionInsert, model.TypeAppOrgGroup, nil, err) } @@ -2641,8 +2634,8 @@ func (sa *Adapter) InsertAppOrgGroup(context TransactionContext, item model.AppO } // UpdateAppOrgGroup updates application organization group -func (sa *Adapter) UpdateAppOrgGroup(context TransactionContext, item model.AppOrgGroup) error { - if context == nil { +func (sa *Adapter) UpdateAppOrgGroup(item model.AppOrgGroup) error { + if sa.context == nil { return errors.ErrorData(logutils.StatusMissing, "transaction context", nil) } @@ -2661,7 +2654,7 @@ func (sa *Adapter) UpdateAppOrgGroup(context TransactionContext, item model.AppO }}, } - res, err := sa.db.applicationsOrganizationsGroups.UpdateOneWithContext(context, groupFilter, groupUpdate, nil) + res, err := sa.db.applicationsOrganizationsGroups.UpdateOneWithContext(sa.context, groupFilter, groupUpdate, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeAppOrgGroup, &logutils.FieldArgs{"id": item.ID}, err) } @@ -2682,7 +2675,7 @@ func (sa *Adapter) UpdateAppOrgGroup(context TransactionContext, item model.AppO }}, } - res, err = sa.db.accounts.UpdateManyWithContext(context, accountsFilter, accountsUpdate, nil) + res, err = sa.db.accounts.UpdateManyWithContext(sa.context, accountsFilter, accountsUpdate, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeAccount, &logutils.FieldArgs{"groups.group.id": item.ID}, err) } @@ -2737,8 +2730,8 @@ func (sa *Adapter) LoadAPIKeys() ([]model.APIKey, error) { } // InsertAPIKey inserts an API key -func (sa *Adapter) InsertAPIKey(context TransactionContext, apiKey model.APIKey) (*model.APIKey, error) { - _, err := sa.db.apiKeys.InsertOneWithContext(context, apiKey) +func (sa *Adapter) InsertAPIKey(apiKey model.APIKey) (*model.APIKey, error) { + _, err := sa.db.apiKeys.InsertOneWithContext(sa.context, apiKey) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionInsert, model.TypeAPIKey, &logutils.FieldArgs{"_id": apiKey.ID}, err) } @@ -2791,7 +2784,7 @@ func (sa *Adapter) LoadIdentityProviders() ([]model.IdentityProvider, error) { } // UpdateProfile updates a profile -func (sa *Adapter) UpdateProfile(context TransactionContext, profile model.Profile) error { +func (sa *Adapter) UpdateProfile(profile model.Profile) error { filter := bson.D{primitive.E{Key: "profile.id", Value: profile.ID}} now := time.Now().UTC() @@ -2812,7 +2805,7 @@ func (sa *Adapter) UpdateProfile(context TransactionContext, profile model.Profi }}, } - res, err := sa.db.accounts.UpdateManyWithContext(context, filter, profileUpdate, nil) + res, err := sa.db.accounts.UpdateManyWithContext(sa.context, filter, profileUpdate, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeProfile, nil, err) } @@ -2848,12 +2841,12 @@ func (sa *Adapter) FindProfiles(appID string, authTypeID string, accountAuthType } // CreateGlobalConfig creates global config -func (sa *Adapter) CreateGlobalConfig(context TransactionContext, globalConfig *model.GlobalConfig) error { +func (sa *Adapter) CreateGlobalConfig(globalConfig *model.GlobalConfig) error { if globalConfig == nil { return errors.ErrorData(logutils.StatusInvalid, logutils.TypeArg, logutils.StringArgs("global_config")) } - _, err := sa.db.globalConfig.InsertOneWithContext(context, globalConfig) + _, err := sa.db.globalConfig.InsertOneWithContext(sa.context, globalConfig) if err != nil { return errors.WrapErrorAction(logutils.ActionInsert, model.TypeGlobalConfig, &logutils.FieldArgs{"setting": globalConfig.Setting}, err) } @@ -2878,9 +2871,9 @@ func (sa *Adapter) GetGlobalConfig() (*model.GlobalConfig, error) { } // DeleteGlobalConfig deletes the global configuration from storage -func (sa *Adapter) DeleteGlobalConfig(context TransactionContext) error { +func (sa *Adapter) DeleteGlobalConfig() error { delFilter := bson.D{} - _, err := sa.db.globalConfig.DeleteManyWithContext(context, delFilter, nil) + _, err := sa.db.globalConfig.DeleteManyWithContext(sa.context, delFilter, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionDelete, model.TypeGlobalConfig, nil, err) } @@ -2915,10 +2908,10 @@ func (sa *Adapter) FindOrganizations() ([]model.Organization, error) { } // InsertOrganization inserts an organization -func (sa *Adapter) InsertOrganization(context TransactionContext, organization model.Organization) (*model.Organization, error) { +func (sa *Adapter) InsertOrganization(organization model.Organization) (*model.Organization, error) { org := organizationToStorage(&organization) - _, err := sa.db.organizations.InsertOneWithContext(context, org) + _, err := sa.db.organizations.InsertOneWithContext(sa.context, org) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionInsert, model.TypeOrganization, nil, err) } @@ -2993,10 +2986,10 @@ func (sa *Adapter) loadApplications() ([]model.Application, error) { } // InsertApplication inserts an application -func (sa *Adapter) InsertApplication(context TransactionContext, application model.Application) (*model.Application, error) { +func (sa *Adapter) InsertApplication(application model.Application) (*model.Application, error) { app := applicationToStorage(&application) - _, err := sa.db.applications.InsertOneWithContext(context, app) + _, err := sa.db.applications.InsertOneWithContext(sa.context, app) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionInsert, model.TypeApplication, nil, err) } @@ -3005,11 +2998,11 @@ func (sa *Adapter) InsertApplication(context TransactionContext, application mod } // SaveApplication saves an application -func (sa *Adapter) SaveApplication(context TransactionContext, application model.Application) error { +func (sa *Adapter) SaveApplication(application model.Application) error { filter := bson.D{primitive.E{Key: "_id", Value: application.ID}} app := applicationToStorage(&application) - err := sa.db.applications.ReplaceOneWithContext(context, filter, app, nil) + err := sa.db.applications.ReplaceOneWithContext(sa.context, filter, app, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionSave, model.TypeApplication, &logutils.FieldArgs{"id": app.ID}, err) } @@ -3018,12 +3011,12 @@ func (sa *Adapter) SaveApplication(context TransactionContext, application model } // FindApplication finds application -func (sa *Adapter) FindApplication(context TransactionContext, ID string) (*model.Application, error) { - if context != nil { +func (sa *Adapter) FindApplication(ID string) (*model.Application, error) { + if sa.context != nil { filter := bson.D{primitive.E{Key: "_id", Value: ID}} var app application - err := sa.db.applications.FindOneWithContext(context, filter, &app, nil) + err := sa.db.applications.FindOneWithContext(sa.context, filter, &app, nil) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeApplication, &logutils.FieldArgs{"_id": ID}, err) } @@ -3273,10 +3266,10 @@ func (sa *Adapter) FindApplicationOrganizationByID(ID string) (*model.Applicatio } // InsertApplicationOrganization inserts an application organization -func (sa *Adapter) InsertApplicationOrganization(context TransactionContext, applicationOrganization model.ApplicationOrganization) (*model.ApplicationOrganization, error) { +func (sa *Adapter) InsertApplicationOrganization(applicationOrganization model.ApplicationOrganization) (*model.ApplicationOrganization, error) { appOrg := applicationOrganizationToStorage(applicationOrganization) - _, err := sa.db.applicationsOrganizations.InsertOneWithContext(context, appOrg) + _, err := sa.db.applicationsOrganizations.InsertOneWithContext(sa.context, appOrg) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionInsert, model.TypeApplicationOrganization, nil, err) } @@ -3285,7 +3278,7 @@ func (sa *Adapter) InsertApplicationOrganization(context TransactionContext, app } // UpdateApplicationOrganization updates an application organization -func (sa *Adapter) UpdateApplicationOrganization(context TransactionContext, applicationOrganization model.ApplicationOrganization) error { +func (sa *Adapter) UpdateApplicationOrganization(applicationOrganization model.ApplicationOrganization) error { appOrg := applicationOrganizationToStorage(applicationOrganization) now := time.Now() @@ -3300,7 +3293,7 @@ func (sa *Adapter) UpdateApplicationOrganization(context TransactionContext, app primitive.E{Key: "$set", Value: update}, } - res, err := sa.db.applicationsOrganizations.UpdateOneWithContext(context, filter, updateAppOrg, nil) + res, err := sa.db.applicationsOrganizations.UpdateOneWithContext(sa.context, filter, updateAppOrg, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionUpdate, model.TypeApplicationOrganization, nil, err) } @@ -3315,12 +3308,12 @@ func (sa *Adapter) UpdateApplicationOrganization(context TransactionContext, app } // FindDevice finds a device by device id and account id -func (sa *Adapter) FindDevice(context TransactionContext, deviceID string, accountID string) (*model.Device, error) { +func (sa *Adapter) FindDevice(deviceID string, accountID string) (*model.Device, error) { filter := bson.D{primitive.E{Key: "device_id", Value: deviceID}, primitive.E{Key: "account_id", Value: accountID}} var result []device - err := sa.db.devices.FindWithContext(context, filter, &result, nil) + err := sa.db.devices.FindWithContext(sa.context, filter, &result, nil) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeDevice, nil, err) } @@ -3335,10 +3328,10 @@ func (sa *Adapter) FindDevice(context TransactionContext, deviceID string, accou } // InsertDevice inserts a device -func (sa *Adapter) InsertDevice(context TransactionContext, device model.Device) (*model.Device, error) { +func (sa *Adapter) InsertDevice(device model.Device) (*model.Device, error) { //insert in devices storageDevice := deviceToStorage(&device) - _, err := sa.db.devices.InsertOneWithContext(context, storageDevice) + _, err := sa.db.devices.InsertOneWithContext(sa.context, storageDevice) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionInsert, model.TypeDevice, nil, err) } @@ -3350,7 +3343,7 @@ func (sa *Adapter) InsertDevice(context TransactionContext, device model.Device) primitive.E{Key: "devices", Value: storageDevice}, }}, } - res, err := sa.db.accounts.UpdateOneWithContext(context, filter, update, nil) + res, err := sa.db.accounts.UpdateOneWithContext(sa.context, filter, update, nil) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionUpdate, model.TypeAccount, logutils.StringArgs("inserting device"), err) } @@ -3362,8 +3355,8 @@ func (sa *Adapter) InsertDevice(context TransactionContext, device model.Device) } // InsertAuthType inserts an auth type -func (sa *Adapter) InsertAuthType(context TransactionContext, authType model.AuthType) (*model.AuthType, error) { - _, err := sa.db.authTypes.InsertOneWithContext(context, authType) +func (sa *Adapter) InsertAuthType(authType model.AuthType) (*model.AuthType, error) { + _, err := sa.db.authTypes.InsertOneWithContext(sa.context, authType) if err != nil { return nil, errors.WrapErrorAction(logutils.ActionInsert, model.TypeAuthType, nil, err) } @@ -3523,7 +3516,7 @@ func (sa *Adapter) DeleteServiceAuthorization(userID string, serviceID string) e } // SaveDevice saves device -func (sa *Adapter) SaveDevice(context TransactionContext, device *model.Device) error { +func (sa *Adapter) SaveDevice(device *model.Device) error { if device == nil { return errors.ErrorData(logutils.StatusInvalid, logutils.TypeArg, logutils.StringArgs("device")) } @@ -3532,7 +3525,7 @@ func (sa *Adapter) SaveDevice(context TransactionContext, device *model.Device) filter := bson.M{"_id": device.ID} opts := options.Replace().SetUpsert(true) - err := sa.db.devices.ReplaceOneWithContext(context, filter, storageDevice, opts) + err := sa.db.devices.ReplaceOneWithContext(sa.context, filter, storageDevice, opts) if err != nil { return errors.WrapErrorAction(logutils.ActionSave, model.TypeDevice, &logutils.FieldArgs{"device_id": device.ID}, nil) } @@ -3541,9 +3534,9 @@ func (sa *Adapter) SaveDevice(context TransactionContext, device *model.Device) } // DeleteDevice deletes a device -func (sa *Adapter) DeleteDevice(context TransactionContext, id string) error { +func (sa *Adapter) DeleteDevice(id string) error { filter := bson.M{"_id": id} - res, err := sa.db.devices.DeleteOneWithContext(context, filter, nil) + res, err := sa.db.devices.DeleteOneWithContext(sa.context, filter, nil) if err != nil { return errors.WrapErrorAction(logutils.ActionDelete, model.TypeDevice, nil, err) } @@ -3625,8 +3618,21 @@ func (sa *Adapter) convertID(result map[string]interface{}) { } } -func (sa *Adapter) abortTransaction(sessionContext mongo.SessionContext) { - err := sessionContext.AbortTransaction(sessionContext) +// Creates a new Adapter with provided context +func (sa *Adapter) withContext(context mongo.SessionContext) *Adapter { + return &Adapter{ + db: sa.db, context: context, logger: sa.logger, + cachedServiceRegs: sa.cachedServiceRegs, serviceRegsLock: sa.serviceRegsLock, + cachedOrganizations: sa.cachedOrganizations, organizationsLock: sa.organizationsLock, + cachedApplications: sa.cachedApplications, applicationsLock: sa.applicationsLock, + cachedApplicationsOrganizations: sa.cachedApplicationsOrganizations, applicationsOrganizationsLock: sa.applicationsOrganizationsLock, + cachedApplicationConfigs: sa.cachedApplicationConfigs, applicationConfigsLock: sa.applicationConfigsLock, + cachedAuthTypes: sa.cachedAuthTypes, authTypesLock: sa.authTypesLock, + } +} + +func (sa *Adapter) abortTransaction() { + err := sa.context.AbortTransaction(sa.context) if err != nil { sa.logger.Errorf("error aborting a transaction - %s", err) } @@ -3699,18 +3705,6 @@ func (sl *storageListener) OnApplicationConfigsUpdated() { sl.adapter.cacheApplicationConfigs() } -// Listener represents storage listener -type Listener interface { - OnAPIKeysUpdated() - OnAuthTypesUpdated() - OnIdentityProvidersUpdated() - OnServiceRegsUpdated() - OnOrganizationsUpdated() - OnApplicationsUpdated() - OnApplicationsOrganizationsUpdated() - OnApplicationConfigsUpdated() -} - // DefaultListenerImpl default listener implementation type DefaultListenerImpl struct{} @@ -3737,8 +3731,3 @@ func (d *DefaultListenerImpl) OnApplicationsOrganizationsUpdated() {} // OnApplicationConfigsUpdated notifies application configs have been updated func (d *DefaultListenerImpl) OnApplicationConfigsUpdated() {} - -// TransactionContext wraps mongo.SessionContext for use by external packages -type TransactionContext interface { - mongo.SessionContext -} diff --git a/driven/storage/database.go b/driven/storage/database.go index 549790cd9..ee7a9de7c 100644 --- a/driven/storage/database.go +++ b/driven/storage/database.go @@ -16,6 +16,7 @@ package storage import ( "context" + "core-building-block/core/interfaces" "time" "github.com/rokwire/logging-library-go/logs" @@ -54,7 +55,7 @@ type database struct { applicationConfigs *collectionWrapper permissions *collectionWrapper - listeners []Listener + listeners []interfaces.Listener } func (m *database) start() error { @@ -220,7 +221,7 @@ func (m *database) start() error { go m.applicationsOrganizations.Watch(nil, m.logger) go m.applicationConfigs.Watch(nil, m.logger) - m.listeners = []Listener{} + m.listeners = []interfaces.Listener{} return nil }