Files
probo/pkg/server/api/connect/v1/oauth2_access_token_resolvers.go
Ludovic Vielle c93932f026 Introduce oauth2scope registry with freeze lifecycle
Replace pkg/iam/scopeset with pkg/iam/oauth2scope.Registry, a shared
OAuth2 scope→action registry used by the authorizer, OAuth2 service,
and Connect API. Registration stays open until probod calls Freeze();
read paths (RegisteredScopes, Allows, ValidateScopes) panic before
that.

Drop the leaky APIScopes surface and AllowedAPIScopes on manual
access-token creation in favor of registry.ValidateScopes. Metadata,
protected-resource metadata, and CIMD scope lists are built from
RegisteredScopes() via helpers in pkg/iam/oauth2/scopes.go. Expose
oauth2ScopesSupported as an OAuth2Scope GraphQL scalar.

Signed-off-by: Ludovic Vielle <ludovic@probo.com>
2026-06-22 11:22:19 +02:00

121 lines
4.0 KiB
Go

package connect_v1
// This file will be automatically regenerated based on the schema, any resolver
// implementations
// will be copied through when generating and any unknown code will be moved to the end.
// Code generated by github.com/99designs/gqlgen version v0.17.90
import (
"context"
"errors"
"strings"
"go.gearno.de/kit/log"
"go.probo.inc/probo/pkg/coredata"
"go.probo.inc/probo/pkg/iam"
"go.probo.inc/probo/pkg/iam/oauth2"
"go.probo.inc/probo/pkg/server/api/authn"
"go.probo.inc/probo/pkg/server/api/connect/v1/schema"
"go.probo.inc/probo/pkg/server/api/connect/v1/types"
"go.probo.inc/probo/pkg/server/gqlutils"
)
// CreateOAuth2AccessToken is the resolver for the createOAuth2AccessToken field.
func (r *mutationResolver) CreateOAuth2AccessToken(ctx context.Context, input types.CreateOAuth2AccessTokenInput) (*types.CreateOAuth2AccessTokenPayload, error) {
identity := authn.IdentityFromContext(ctx)
if _, err := r.authorize(ctx, identity.ID, iam.ActionOAuth2AccessTokenCreate); err != nil {
return nil, err
}
scopes, err := input.ParsedScopes()
if err != nil {
return nil, gqlutils.Invalid(ctx, err)
}
tokenValue, accessToken, err := r.iam.OAuth2ServerService.CreateManualAccessToken(
ctx,
&oauth2.CreateManualAccessTokenRequest{
IdentityID: identity.ID,
Name: strings.TrimSpace(input.Name),
ExpiresAt: input.ExpiresAt,
Scopes: scopes,
},
)
if err != nil {
if oauth2Err, ok := errors.AsType[*oauth2.OAuth2Error](err); ok {
return nil, gqlutils.Invalid(ctx, oauth2Err)
}
r.logger.ErrorCtx(ctx, "cannot create oauth2 access token", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &types.CreateOAuth2AccessTokenPayload{
Oauth2AccessTokenEdge: types.NewOAuth2AccessTokenEdge(
accessToken,
coredata.OAuth2AccessTokenOrderFieldCreatedAt,
),
Token: tokenValue,
}, nil
}
// RevokeOAuth2AccessToken is the resolver for the revokeOAuth2AccessToken field.
func (r *mutationResolver) RevokeOAuth2AccessToken(ctx context.Context, input types.RevokeOAuth2AccessTokenInput) (*types.RevokeOAuth2AccessTokenPayload, error) {
if _, err := r.authorize(ctx, input.Oauth2AccessTokenID, iam.ActionOAuth2AccessTokenDelete); err != nil {
return nil, err
}
if err := r.iam.OAuth2ServerService.RevokeAccessToken(ctx, input.Oauth2AccessTokenID); err != nil {
r.logger.ErrorCtx(ctx, "cannot revoke oauth2 access token", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &types.RevokeOAuth2AccessTokenPayload{
Oauth2AccessTokenID: input.Oauth2AccessTokenID,
}, nil
}
// Permission is the resolver for the permission field.
func (r *oAuth2AccessTokenResolver) Permission(ctx context.Context, obj *types.OAuth2AccessToken, action string) (bool, error) {
return r.Resolver.Permission(ctx, obj, action)
}
// TotalCount is the resolver for the totalCount field.
func (r *oAuth2AccessTokenConnectionResolver) TotalCount(ctx context.Context, obj *types.OAuth2AccessTokenConnection) (*int, error) {
switch obj.Resolver.(type) {
case *identityResolver:
if _, err := r.authorize(ctx, obj.ParentID, iam.ActionOAuth2AccessTokenList); err != nil {
return nil, err
}
count, err := r.iam.OAuth2ServerService.CountAccessTokensByIdentityID(ctx, obj.ParentID)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot count oauth2 access tokens", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &count, nil
}
r.logger.ErrorCtx(ctx, "unsupported resolver", log.Any("resolver", obj.Resolver))
return nil, gqlutils.Internal(ctx)
}
// OAuth2AccessToken returns schema.OAuth2AccessTokenResolver implementation.
func (r *Resolver) OAuth2AccessToken() schema.OAuth2AccessTokenResolver {
return &oAuth2AccessTokenResolver{r}
}
// OAuth2AccessTokenConnection returns schema.OAuth2AccessTokenConnectionResolver implementation.
func (r *Resolver) OAuth2AccessTokenConnection() schema.OAuth2AccessTokenConnectionResolver {
return &oAuth2AccessTokenConnectionResolver{r}
}
type oAuth2AccessTokenResolver struct{ *Resolver }
type oAuth2AccessTokenConnectionResolver struct{ *Resolver }