mirror of
https://github.com/sonr-io/sonr.git
synced 2026-08-02 17:31:39 +00:00
Regular → Executable
+276
-10
@@ -2,12 +2,28 @@ package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
"github.com/sonr-io/snrd/x/svc/types"
|
||||
apiv1 "github.com/sonr-io/sonr/api/svc/v1"
|
||||
"github.com/sonr-io/sonr/x/svc/types"
|
||||
)
|
||||
|
||||
// convertV1ServiceToTypes converts a v1.Service to types.Service
|
||||
func convertV1ServiceToTypes(v1Service *apiv1.Service) *types.Service {
|
||||
return &types.Service{
|
||||
Id: v1Service.Id,
|
||||
Domain: v1Service.Domain,
|
||||
Owner: v1Service.Owner,
|
||||
RootCapabilityCid: v1Service.RootCapabilityCid,
|
||||
Permissions: v1Service.Permissions,
|
||||
Status: types.ServiceStatus(v1Service.Status),
|
||||
CreatedAt: v1Service.CreatedAt,
|
||||
UpdatedAt: v1Service.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
var _ types.QueryServer = Querier{}
|
||||
|
||||
type Querier struct {
|
||||
@@ -18,7 +34,10 @@ func NewQuerier(keeper Keeper) Querier {
|
||||
return Querier{Keeper: keeper}
|
||||
}
|
||||
|
||||
func (k Querier) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
|
||||
func (k Querier) Params(
|
||||
c context.Context,
|
||||
req *types.QueryParamsRequest,
|
||||
) (*types.QueryParamsResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
p, err := k.Keeper.Params.Get(ctx)
|
||||
@@ -29,14 +48,261 @@ func (k Querier) Params(c context.Context, req *types.QueryParamsRequest) (*type
|
||||
return &types.QueryParamsResponse{Params: &p}, nil
|
||||
}
|
||||
|
||||
// OriginExists implements types.QueryServer.
|
||||
func (k Querier) OriginExists(goCtx context.Context, req *types.QueryOriginExistsRequest) (*types.QueryOriginExistsResponse, error) {
|
||||
// ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
return &types.QueryOriginExistsResponse{}, nil
|
||||
// DomainVerification implements types.QueryServer.
|
||||
func (k Querier) DomainVerification(
|
||||
goCtx context.Context,
|
||||
req *types.QueryDomainVerificationRequest,
|
||||
) (*types.QueryDomainVerificationResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
|
||||
if req.Domain == "" {
|
||||
return nil, fmt.Errorf("domain cannot be empty")
|
||||
}
|
||||
|
||||
// Get domain verification from ORM
|
||||
verification, err := k.Keeper.OrmDB.DomainVerificationTable().Get(ctx, req.Domain)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("domain verification not found: %w", err)
|
||||
}
|
||||
|
||||
// Convert v1.DomainVerification to types.DomainVerification
|
||||
typesVerification := &types.DomainVerification{
|
||||
Domain: verification.Domain,
|
||||
Owner: verification.Owner,
|
||||
VerificationToken: verification.VerificationToken,
|
||||
Status: types.DomainVerificationStatus(verification.Status),
|
||||
ExpiresAt: verification.ExpiresAt,
|
||||
}
|
||||
|
||||
return &types.QueryDomainVerificationResponse{
|
||||
DomainVerification: typesVerification,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ResolveOrigin implements types.QueryServer.
|
||||
func (k Querier) ResolveOrigin(goCtx context.Context, req *types.QueryResolveOriginRequest) (*types.QueryResolveOriginResponse, error) {
|
||||
// ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
return &types.QueryResolveOriginResponse{}, nil
|
||||
// Service implements types.QueryServer.
|
||||
func (k Querier) Service(
|
||||
goCtx context.Context,
|
||||
req *types.QueryServiceRequest,
|
||||
) (*types.QueryServiceResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
|
||||
if req.ServiceId == "" {
|
||||
return nil, fmt.Errorf("service_id cannot be empty")
|
||||
}
|
||||
|
||||
// Get service from ORM
|
||||
service, err := k.Keeper.OrmDB.ServiceTable().Get(ctx, req.ServiceId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("service not found: %w", err)
|
||||
}
|
||||
|
||||
return &types.QueryServiceResponse{
|
||||
Service: convertV1ServiceToTypes(service),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ServicesByOwner implements types.QueryServer.
|
||||
func (k Querier) ServicesByOwner(
|
||||
goCtx context.Context,
|
||||
req *types.QueryServicesByOwnerRequest,
|
||||
) (*types.QueryServicesByOwnerResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
|
||||
if req.Owner == "" {
|
||||
return nil, fmt.Errorf("owner cannot be empty")
|
||||
}
|
||||
|
||||
// Create index key for owner
|
||||
ownerKey := apiv1.ServiceOwnerIndexKey{}.WithOwner(req.Owner)
|
||||
|
||||
// List services by owner
|
||||
iter, err := k.Keeper.OrmDB.ServiceTable().List(ctx, ownerKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list services by owner: %w", err)
|
||||
}
|
||||
defer iter.Close()
|
||||
|
||||
var services []*types.Service
|
||||
for iter.Next() {
|
||||
service, err := iter.Value()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get service value: %w", err)
|
||||
}
|
||||
services = append(services, convertV1ServiceToTypes(service))
|
||||
}
|
||||
|
||||
return &types.QueryServicesByOwnerResponse{
|
||||
Services: services,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ServicesByDomain implements types.QueryServer.
|
||||
func (k Querier) ServicesByDomain(
|
||||
goCtx context.Context,
|
||||
req *types.QueryServicesByDomainRequest,
|
||||
) (*types.QueryServicesByDomainResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
|
||||
if req.Domain == "" {
|
||||
return nil, fmt.Errorf("domain cannot be empty")
|
||||
}
|
||||
|
||||
// Create index key for domain
|
||||
domainKey := apiv1.ServiceDomainIndexKey{}.WithDomain(req.Domain)
|
||||
|
||||
// List services by domain
|
||||
iter, err := k.Keeper.OrmDB.ServiceTable().List(ctx, domainKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list services by domain: %w", err)
|
||||
}
|
||||
defer iter.Close()
|
||||
|
||||
var services []*types.Service
|
||||
for iter.Next() {
|
||||
service, err := iter.Value()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get service value: %w", err)
|
||||
}
|
||||
services = append(services, convertV1ServiceToTypes(service))
|
||||
}
|
||||
|
||||
return &types.QueryServicesByDomainResponse{
|
||||
Services: services,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ServiceOIDCDiscovery implements types.QueryServer.
|
||||
func (k Querier) ServiceOIDCDiscovery(goCtx context.Context, req *types.QueryServiceOIDCDiscoveryRequest) (*types.QueryServiceOIDCDiscoveryResponse, error) {
|
||||
if req == nil || req.ServiceId == "" {
|
||||
return nil, types.ErrInvalidServiceID
|
||||
}
|
||||
|
||||
// Get service to verify it exists and is active
|
||||
service, err := k.Keeper.OrmDB.ServiceTable().Get(goCtx, req.ServiceId)
|
||||
if err != nil {
|
||||
return nil, types.ErrServiceNotFound
|
||||
}
|
||||
|
||||
if service.Status != apiv1.ServiceStatus_SERVICE_STATUS_ACTIVE {
|
||||
return nil, types.ErrServiceNotActive
|
||||
}
|
||||
|
||||
// Get OIDC config
|
||||
config, err := k.Keeper.GetServiceOIDCConfig(goCtx, req.ServiceId)
|
||||
if err != nil {
|
||||
// If no config exists, create default based on verified domain
|
||||
config, err = k.Keeper.CreateDefaultOIDCConfig(goCtx, req.ServiceId, service.Domain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Build OIDC discovery response according to spec
|
||||
return &types.QueryServiceOIDCDiscoveryResponse{
|
||||
Issuer: config.Issuer,
|
||||
AuthorizationEndpoint: config.AuthorizationEndpoint,
|
||||
TokenEndpoint: config.TokenEndpoint,
|
||||
JwksUri: config.JwksUri,
|
||||
UserinfoEndpoint: config.UserinfoEndpoint,
|
||||
RegistrationEndpoint: fmt.Sprintf("https://%s/oauth/register", service.Domain),
|
||||
ScopesSupported: config.ScopesSupported,
|
||||
ResponseTypesSupported: config.ResponseTypesSupported,
|
||||
GrantTypesSupported: config.GrantTypesSupported,
|
||||
IdTokenSigningAlgValuesSupported: config.IdTokenSigningAlgValuesSupported,
|
||||
SubjectTypesSupported: config.SubjectTypesSupported,
|
||||
TokenEndpointAuthMethodsSupported: config.TokenEndpointAuthMethodsSupported,
|
||||
ClaimsSupported: config.ClaimsSupported,
|
||||
ResponseModesSupported: config.ResponseModesSupported,
|
||||
ServiceDocumentation: fmt.Sprintf("https://%s/docs", service.Domain),
|
||||
UiLocalesSupported: []string{"en-US"},
|
||||
ClaimsLocalesSupported: []string{"en-US"},
|
||||
RequestParameterSupported: true,
|
||||
RequestUriParameterSupported: true,
|
||||
RequireRequestUriRegistration: false,
|
||||
OpPolicyUri: fmt.Sprintf("https://%s/policy", service.Domain),
|
||||
OpTosUri: fmt.Sprintf("https://%s/terms", service.Domain),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ServiceOIDCJWKS implements types.QueryServer.
|
||||
func (k Querier) ServiceOIDCJWKS(goCtx context.Context, req *types.QueryServiceOIDCJWKSRequest) (*types.QueryServiceOIDCJWKSResponse, error) {
|
||||
if req == nil || req.ServiceId == "" {
|
||||
return nil, types.ErrInvalidServiceID
|
||||
}
|
||||
|
||||
// Get service to verify it exists
|
||||
service, err := k.Keeper.OrmDB.ServiceTable().Get(goCtx, req.ServiceId)
|
||||
if err != nil {
|
||||
return nil, types.ErrServiceNotFound
|
||||
}
|
||||
|
||||
if service.Status != apiv1.ServiceStatus_SERVICE_STATUS_ACTIVE {
|
||||
return nil, types.ErrServiceNotActive
|
||||
}
|
||||
|
||||
// Get JWKS
|
||||
jwks, err := k.Keeper.GetServiceJWKS(goCtx, req.ServiceId)
|
||||
if err != nil {
|
||||
// If no JWKS exists, create default
|
||||
jwks, err = k.Keeper.CreateDefaultJWKS(goCtx, req.ServiceId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Return JWKS response
|
||||
return &types.QueryServiceOIDCJWKSResponse{
|
||||
Keys: jwks.Keys,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ServiceOIDCMetadata implements types.QueryServer.
|
||||
func (k Querier) ServiceOIDCMetadata(goCtx context.Context, req *types.QueryServiceOIDCMetadataRequest) (*types.QueryServiceOIDCMetadataResponse, error) {
|
||||
if req == nil || req.ServiceId == "" {
|
||||
return nil, types.ErrInvalidServiceID
|
||||
}
|
||||
|
||||
// Get service
|
||||
service, err := k.Keeper.OrmDB.ServiceTable().Get(goCtx, req.ServiceId)
|
||||
if err != nil {
|
||||
return nil, types.ErrServiceNotFound
|
||||
}
|
||||
|
||||
// Get OIDC config
|
||||
config, err := k.Keeper.GetServiceOIDCConfig(goCtx, req.ServiceId)
|
||||
if err != nil {
|
||||
// If no config exists, create default based on verified domain
|
||||
config, err = k.Keeper.CreateDefaultOIDCConfig(goCtx, req.ServiceId, service.Domain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Convert service status
|
||||
var serviceStatus types.ServiceStatus
|
||||
switch service.Status {
|
||||
case apiv1.ServiceStatus_SERVICE_STATUS_ACTIVE:
|
||||
serviceStatus = types.ServiceStatus_SERVICE_STATUS_ACTIVE
|
||||
case apiv1.ServiceStatus_SERVICE_STATUS_SUSPENDED:
|
||||
serviceStatus = types.ServiceStatus_SERVICE_STATUS_SUSPENDED
|
||||
case apiv1.ServiceStatus_SERVICE_STATUS_REVOKED:
|
||||
serviceStatus = types.ServiceStatus_SERVICE_STATUS_REVOKED
|
||||
default:
|
||||
serviceStatus = types.ServiceStatus_SERVICE_STATUS_ACTIVE
|
||||
}
|
||||
|
||||
// Build metadata response
|
||||
return &types.QueryServiceOIDCMetadataResponse{
|
||||
Config: config,
|
||||
VerifiedDomain: service.Domain,
|
||||
ServiceStatus: serviceStatus,
|
||||
Metadata: map[string]string{
|
||||
"service_id": service.Id,
|
||||
"owner": service.Owner,
|
||||
"created_at": fmt.Sprintf("%d", service.CreatedAt),
|
||||
"updated_at": fmt.Sprintf("%d", service.UpdatedAt),
|
||||
"ucan_root_cid": service.RootCapabilityCid,
|
||||
"oidc_enabled": "true",
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user