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>
121 lines
4.0 KiB
Go
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 }
|