Files
softplayer-backend/api/v1/tokens.go
Nikolai Rodionov ee2aa77ceb
All checks were successful
ci/woodpecker/push/build Pipeline was successful
Update the migration
Signed-off-by: Nikolai Rodionov <iam@allanger.xyz>
2026-05-14 15:09:21 +02:00

139 lines
4.6 KiB
Go

package v1
import (
"context"
"errors"
"gitea.badhouseplants.net/softplayer/softplayer-backend/internal/controllers"
tokens "gitea.badhouseplants.net/softplayer/softplayer-go-proto/pkg/tokens/v1"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/emptypb"
"google.golang.org/protobuf/types/known/timestamppb"
)
// var _ tokens.TokensServiceServer = (*TokensServer)(nil)
type TokensServer struct {
tokens.UnimplementedTokensServiceServer
tokenCtrl *controllers.TokenController
authorizationCtrl *controllers.AuthController
}
func NewTokensServer(
tokenCtrl *controllers.TokenController,
authorizationCtrl *controllers.AuthController,
) *TokensServer {
return &TokensServer{
tokenCtrl: tokenCtrl,
authorizationCtrl: authorizationCtrl,
}
}
// CreateToken implements [v1.TokensServiceServer].
func (srv *TokensServer) CreateToken(ctx context.Context, in *tokens.CreateTokenRequest) (*tokens.CreateTokenResponse, error) {
claims, err := srv.authorizationCtrl.ClaimsFromContext(ctx)
if err != nil {
return nil, status.Error(codes.Aborted, "Context is invalid")
}
if claims.UserID == "" {
return nil, status.Error(codes.Aborted, "Context is invalid")
}
if in.TokenPermissions == nil {
return nil, status.Error(codes.InvalidArgument, "Permissions must be set")
}
permissions := map[string][]string{}
for service, methods := range in.TokenPermissions.Permissions {
permissions[service] = methods.GetMethods()
}
tokenData := &controllers.TokenData{
Name: in.TokenMetadata.GetName(),
UserID: claims.UserID,
Scopes: permissions,
}
token, err := srv.tokenCtrl.Create(ctx, tokenData)
if err != nil {
if errors.Is(err, controllers.ErrServerError) {
return nil, status.Error(codes.Internal, "Something is broken on our side")
}
return nil, status.Error(codes.Aborted, "Couldn't create a token")
}
return &tokens.CreateTokenResponse{
TokenValue: &tokens.TokenValue{Token: token},
}, nil
}
// ForceTokenExpiration implements [v1.TokensServiceServer].
func (t *TokensServer) ForceTokenExpiration(context.Context, *tokens.ForceTokenExpirationRequest) (*emptypb.Empty, error) {
return nil, status.Error(codes.Unimplemented, "Method is not implemented")
}
// GetToken implements [v1.TokensServiceServer].
func (t *TokensServer) GetToken(context.Context, *tokens.GetTokenRequest) (*tokens.GetTokenResponse, error) {
return nil, status.Error(codes.Unimplemented, "Method is not implemented")
}
// ListTokens implements [v1.TokensServiceServer].
func (srv *TokensServer) ListTokens(in *emptypb.Empty, stream grpc.ServerStreamingServer[tokens.ListTokensResponse]) error {
claims, err := srv.authorizationCtrl.ClaimsFromContext(stream.Context())
if err != nil {
return status.Error(codes.Aborted, "Context is invalid")
}
if claims.UserID == "" {
return status.Error(codes.Aborted, "Context is invalid")
}
tokensRes, err := srv.tokenCtrl.List(stream.Context(), claims.UserID)
if err != nil {
if errors.Is(err, controllers.ErrServerError) {
return status.Error(codes.Internal, "Something is broken on our side")
}
return status.Error(codes.Aborted, "Couldn't create a token")
}
for _, tokenRes := range tokensRes {
stream.Send(&tokens.ListTokensResponse{
TokenUuid: &tokens.TokenUUID{
Uuid: tokenRes.UUID,
},
TokenMetadata: &tokens.TokenMetadata{
Name: tokenRes.Name,
ExpiresAt: timestamppb.New(tokenRes.ExpiresAt),
},
})
}
return status.Error(codes.Unimplemented, "Method is not implemented")
}
// RegenerateToken implements [v1.TokensServiceServer].
func (t *TokensServer) RegenerateToken(context.Context, *tokens.RegenerateTokenRequest) (*tokens.RegenerateTokenResponse, error) {
return nil, status.Error(codes.Unimplemented, "Method is not implemented")
}
// UpdateToken implements [v1.TokensServiceServer].
func (t *TokensServer) UpdateToken(context.Context, *tokens.UpdateTokenRequest) (*tokens.UpdateTokenResponse, error) {
return nil, status.Error(codes.Unimplemented, "Method is not implemented")
}
// ListPermissions implements [v1.TokensServiceServer].
func (srv *TokensServer) ListPermissions(in *emptypb.Empty, stream grpc.ServerStreamingServer[tokens.ListPermissionsResponse]) error {
data := srv.tokenCtrl.ListPermissions(stream.Context())
for key, data := range data {
result := &tokens.ListPermissionsResponse{
Permissions: &tokens.TokenPermissions{
Permissions: map[string]*tokens.MethodList{
key: {Methods: data},
},
},
}
if err := stream.Send(result); err != nil {
return status.Error(codes.Aborted, "Couldn't send data to the client")
}
}
return nil
}