From a21e114272a15a2a6fb0694f70fcb25f3d2b8eab Mon Sep 17 00:00:00 2001 From: dkanney Date: Wed, 11 Feb 2026 00:06:18 -0500 Subject: [PATCH] chore(apptoken): Call LookupAppToken() after creating a new app token Performs a fresh lookup to get all current values in the DB after insert --- internal/apptoken/repository.go | 70 ++++++++++++++++----------------- 1 file changed, 34 insertions(+), 36 deletions(-) diff --git a/internal/apptoken/repository.go b/internal/apptoken/repository.go index 72511a89a0..91f4bdbb53 100644 --- a/internal/apptoken/repository.go +++ b/internal/apptoken/repository.go @@ -254,20 +254,19 @@ func (r *Repository) CreateAppToken(ctx context.Context, token *AppToken) (*AppT // each inner slice contains items of the same type (appTokenPermissionGlobal, for example) // to be batch inserted using CreateItems var dbInserts []interface{} - var createdToken appTokenSubtype switch { case strings.HasPrefix(token.GetScopeId(), globals.GlobalPrefix): - createdToken, dbInserts, err = createAppTokenGlobal(ctx, token) + dbInserts, err = createAppTokenGlobal(ctx, token) if err != nil { return nil, errors.Wrap(ctx, err, op) } case strings.HasPrefix(token.GetScopeId(), globals.OrgPrefix): - createdToken, dbInserts, err = createAppTokenOrg(ctx, token) + dbInserts, err = createAppTokenOrg(ctx, token) if err != nil { return nil, errors.Wrap(ctx, err, op) } case strings.HasPrefix(token.GetScopeId(), globals.ProjectPrefix): - createdToken, dbInserts, err = createAppTokenProject(ctx, token) + dbInserts, err = createAppTokenProject(ctx, token) if err != nil { return nil, errors.Wrap(ctx, err, op) } @@ -295,34 +294,33 @@ func (r *Repository) CreateAppToken(ctx context.Context, token *AppToken) (*AppT dbInserts = append(dbInserts, []*appTokenCipher{atc}) // batch write all collected inserts + var newAppToken *AppToken _, err = r.writer.DoTx( ctx, db.StdRetryCnt, db.ExpBackoff{}, - func(_ db.Reader, w db.Writer) error { + func(reader db.Reader, writer db.Writer) error { for _, appTokenItems := range dbInserts { - if err := w.CreateItems(ctx, appTokenItems); err != nil { + if err := writer.CreateItems(ctx, appTokenItems); err != nil { return err } } + // Do a fresh lookup to get all return values + newAppToken, err = r.LookupAppToken(ctx, id, WithReaderWriter(reader, writer)) + if err != nil { + return errors.Wrap(ctx, err, op) + } + return nil }, ) if err != nil { return nil, errors.Wrap(ctx, err, op, errors.WithMsg("creating app token in database")) } - - newAppToken := createdToken.toAppToken() - if newAppToken == nil { - return nil, errors.New(ctx, errors.Internal, op, "failed to convert created app token to domain object") - } - newAppToken.Token = cipherToken - newAppToken.Permissions = token.Permissions - return newAppToken, nil } -func createAppTokenGlobal(ctx context.Context, token *AppToken) (*appTokenGlobal, []interface{}, error) { +func createAppTokenGlobal(ctx context.Context, token *AppToken) ([]interface{}, error) { const op = "apptoken.(Repository).createAppTokenGlobal" var globalInserts []interface{} // we collect inserts in their own slices so that we can use w.CreateItems above @@ -350,25 +348,25 @@ func createAppTokenGlobal(ctx context.Context, token *AppToken) (*appTokenGlobal // they're a composite key in the app_token_permission_grant table for _, perm := range token.Permissions { if slices.Contains(perm.GrantedScopes, globals.GrantScopeDescendants) && slices.Contains(perm.GrantedScopes, globals.GrantScopeChildren) { - return nil, nil, errors.New(ctx, errors.InvalidParameter, op, "only one of descendants or children grant scope can be specified") + return nil, errors.New(ctx, errors.InvalidParameter, op, "only one of descendants or children grant scope can be specified") } // perm.GrantedScopes cannot contain globals.GrantScopeDescendants and also contain an individual project or org scope if slices.Contains(perm.GrantedScopes, globals.GrantScopeDescendants) && slices.ContainsFunc(perm.GrantedScopes, func(s string) bool { return strings.HasPrefix(s, globals.ProjectPrefix) || strings.HasPrefix(s, globals.OrgPrefix) }) { - return nil, nil, errors.New(ctx, errors.InvalidParameter, op, "descendants grant scope cannot be combined with individual project grant scopes") + return nil, errors.New(ctx, errors.InvalidParameter, op, "descendants grant scope cannot be combined with individual project grant scopes") } // perm.GrantedScopes cannot contain globals.GrantScopeChildren and also contain an individual org scope if slices.Contains(perm.GrantedScopes, globals.GrantScopeChildren) && slices.ContainsFunc(perm.GrantedScopes, func(s string) bool { return strings.HasPrefix(s, globals.OrgPrefix) }) { - return nil, nil, errors.New(ctx, errors.InvalidParameter, op, "children grant scope cannot be combined with individual org grant scopes") + return nil, errors.New(ctx, errors.InvalidParameter, op, "children grant scope cannot be combined with individual org grant scopes") } // generate new permission ID permId, err := newAppTokenPermissionId(ctx) if err != nil { - return nil, nil, errors.Wrap(ctx, err, op) + return nil, errors.Wrap(ctx, err, op) } grantThisScope := slices.Contains(perm.GrantedScopes, globals.GrantScopeThis) || slices.Contains(perm.GrantedScopes, globals.GlobalPrefix) @@ -386,7 +384,7 @@ func createAppTokenGlobal(ctx context.Context, token *AppToken) (*appTokenGlobal grantInserts, err := processPermissionGrants(ctx, permId, perm.Grants) if err != nil { - return nil, nil, errors.Wrap(ctx, err, op) + return nil, errors.Wrap(ctx, err, op) } permissionGrantInserts = append(permissionGrantInserts, grantInserts...) @@ -420,7 +418,7 @@ func createAppTokenGlobal(ctx context.Context, token *AppToken) (*appTokenGlobal } individualProjInserts = append(individualProjInserts, individualProjGlobalPermToCreate) default: - return nil, nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("invalid grant scope %s", gs)) + return nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("invalid grant scope %s", gs)) } } } @@ -438,10 +436,10 @@ func createAppTokenGlobal(ctx context.Context, token *AppToken) (*appTokenGlobal globalInserts = append(globalInserts, individualProjInserts) } - return tokenToCreate, globalInserts, nil + return globalInserts, nil } -func createAppTokenOrg(ctx context.Context, token *AppToken) (*appTokenOrg, []interface{}, error) { +func createAppTokenOrg(ctx context.Context, token *AppToken) ([]interface{}, error) { const op = "apptoken.(Repository).createAppTokenOrg" var orgInserts []interface{} // we collect inserts in their own slices so that we can use w.CreateItems above @@ -467,20 +465,20 @@ func createAppTokenOrg(ctx context.Context, token *AppToken) (*appTokenOrg, []in for _, perm := range token.Permissions { if slices.Contains(perm.GrantedScopes, globals.GlobalPrefix) { - return nil, nil, errors.New(ctx, errors.InvalidParameter, op, "org cannot have global grant scope") + return nil, errors.New(ctx, errors.InvalidParameter, op, "org cannot have global grant scope") } if slices.Contains(perm.GrantedScopes, globals.GrantScopeDescendants) { - return nil, nil, errors.New(ctx, errors.InvalidParameter, op, "org cannot have descendants grant scope") + return nil, errors.New(ctx, errors.InvalidParameter, op, "org cannot have descendants grant scope") } if slices.Contains(perm.GrantedScopes, globals.GrantScopeChildren) && slices.ContainsFunc(perm.GrantedScopes, func(s string) bool { return strings.HasPrefix(s, globals.ProjectPrefix) }) { - return nil, nil, errors.New(ctx, errors.InvalidParameter, op, "children grant scope cannot be combined with individual project grant scopes") + return nil, errors.New(ctx, errors.InvalidParameter, op, "children grant scope cannot be combined with individual project grant scopes") } permId, err := newAppTokenPermissionId(ctx) if err != nil { - return nil, nil, errors.Wrap(ctx, err, op) + return nil, errors.Wrap(ctx, err, op) } grantThisScope := slices.Contains(perm.GrantedScopes, globals.GrantScopeThis) || slices.Contains(perm.GrantedScopes, token.GetScopeId()) @@ -500,7 +498,7 @@ func createAppTokenOrg(ctx context.Context, token *AppToken) (*appTokenOrg, []in grantInserts, err := processPermissionGrants(ctx, permId, perm.Grants) if err != nil { - return nil, nil, errors.Wrap(ctx, err, op) + return nil, errors.Wrap(ctx, err, op) } permissionGrantInserts = append(permissionGrantInserts, grantInserts...) @@ -523,7 +521,7 @@ func createAppTokenOrg(ctx context.Context, token *AppToken) (*appTokenOrg, []in } individualProjInserts = append(individualProjInserts, individualProjOrgPermToCreate) } else { - return nil, nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("invalid grant scope %s", gs)) + return nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("invalid grant scope %s", gs)) } } } @@ -538,10 +536,10 @@ func createAppTokenOrg(ctx context.Context, token *AppToken) (*appTokenOrg, []in orgInserts = append(orgInserts, individualProjInserts) } - return tokenToCreate, orgInserts, nil + return orgInserts, nil } -func createAppTokenProject(ctx context.Context, token *AppToken) (*appTokenProject, []interface{}, error) { +func createAppTokenProject(ctx context.Context, token *AppToken) ([]interface{}, error) { const op = "apptoken.(Repository).createAppTokenProject" var projectInserts []interface{} // we collect inserts in their own slices so that we can use w.CreateItems above @@ -569,17 +567,17 @@ func createAppTokenProject(ctx context.Context, token *AppToken) (*appTokenProje slices.Contains(perm.GrantedScopes, globals.GrantScopeChildren) || slices.Contains(perm.GrantedScopes, globals.GlobalPrefix) || slices.ContainsFunc(perm.GrantedScopes, func(s string) bool { return strings.HasPrefix(s, globals.OrgPrefix) }) { - return nil, nil, errors.New(ctx, errors.InvalidParameter, op, "project can only contain individual project grant scopes") + return nil, errors.New(ctx, errors.InvalidParameter, op, "project can only contain individual project grant scopes") } if slices.ContainsFunc(perm.GrantedScopes, func(s string) bool { return strings.HasPrefix(s, globals.ProjectPrefix) && s != token.GetScopeId() }) { - return nil, nil, errors.New(ctx, errors.InvalidParameter, op, "project cannot contain individual grant scopes for other projects") + return nil, errors.New(ctx, errors.InvalidParameter, op, "project cannot contain individual grant scopes for other projects") } permId, err := newAppTokenPermissionId(ctx) if err != nil { - return nil, nil, errors.Wrap(ctx, err, op) + return nil, errors.Wrap(ctx, err, op) } // true if slices contains only the individual project scope that matches the token's scope ID or `this` @@ -598,7 +596,7 @@ func createAppTokenProject(ctx context.Context, token *AppToken) (*appTokenProje grantInserts, err := processPermissionGrants(ctx, permId, perm.Grants) if err != nil { - return nil, nil, errors.Wrap(ctx, err, op) + return nil, errors.Wrap(ctx, err, op) } permissionGrantInserts = append(permissionGrantInserts, grantInserts...) } @@ -609,7 +607,7 @@ func createAppTokenProject(ctx context.Context, token *AppToken) (*appTokenProje projectInserts = append(projectInserts, permissionGrantInserts) } - return tokenToCreate, projectInserts, nil + return projectInserts, nil } // processPermissionGrants validates grants and creates grant objects for insertion