github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/internal/services/v0/developer.go (about)

     1  package v0
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	v0 "github.com/authzed/authzed-go/proto/authzed/api/v0"
     8  	"github.com/authzed/grpcutil"
     9  	"google.golang.org/grpc"
    10  	"google.golang.org/protobuf/encoding/prototext"
    11  
    12  	log "github.com/authzed/spicedb/internal/logging"
    13  	core "github.com/authzed/spicedb/pkg/proto/core/v1"
    14  	"github.com/authzed/spicedb/pkg/schemadsl/generator"
    15  )
    16  
    17  type devServer struct {
    18  	v0.UnimplementedDeveloperServiceServer
    19  	grpcutil.IgnoreAuthMixin
    20  
    21  	shareStore ShareStore
    22  }
    23  
    24  // RegisterDeveloperServer adds the Developer Server to a grpc service registrar
    25  // This is preferred over manually registering the service; it will add required middleware
    26  func RegisterDeveloperServer(r grpc.ServiceRegistrar, s v0.DeveloperServiceServer) *grpc.ServiceDesc {
    27  	r.RegisterService(grpcutil.WrapMethods(v0.DeveloperService_ServiceDesc, grpcutil.DefaultUnaryMiddleware...), s)
    28  	return &v0.DeveloperService_ServiceDesc
    29  }
    30  
    31  // NewDeveloperServer creates an instance of the developer server.
    32  func NewDeveloperServer(store ShareStore) v0.DeveloperServiceServer {
    33  	return &devServer{
    34  		shareStore: store,
    35  	}
    36  }
    37  
    38  func (ds *devServer) UpgradeSchema(_ context.Context, req *v0.UpgradeSchemaRequest) (*v0.UpgradeSchemaResponse, error) {
    39  	upgraded, err := upgradeSchema(req.NamespaceConfigs)
    40  	if err != nil {
    41  		return &v0.UpgradeSchemaResponse{
    42  			Error: &v0.DeveloperError{
    43  				Message: err.Error(),
    44  			},
    45  		}, nil
    46  	}
    47  
    48  	return &v0.UpgradeSchemaResponse{
    49  		UpgradedSchema: upgraded,
    50  	}, nil
    51  }
    52  
    53  func (ds *devServer) Share(_ context.Context, req *v0.ShareRequest) (*v0.ShareResponse, error) {
    54  	reference, err := ds.shareStore.StoreShared(SharedDataV2{
    55  		Version:           sharedDataVersion,
    56  		Schema:            req.Schema,
    57  		RelationshipsYaml: req.RelationshipsYaml,
    58  		ValidationYaml:    req.ValidationYaml,
    59  		AssertionsYaml:    req.AssertionsYaml,
    60  	})
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  
    65  	return &v0.ShareResponse{
    66  		ShareReference: reference,
    67  	}, nil
    68  }
    69  
    70  func (ds *devServer) LookupShared(ctx context.Context, req *v0.LookupShareRequest) (*v0.LookupShareResponse, error) {
    71  	shared, status, err := ds.shareStore.LookupSharedByReference(req.ShareReference)
    72  	if err != nil {
    73  		log.Ctx(ctx).Debug().Str("id", req.ShareReference).Err(err).Msg("Lookup Shared Error")
    74  		return &v0.LookupShareResponse{
    75  			Status: v0.LookupShareResponse_FAILED_TO_LOOKUP,
    76  		}, nil
    77  	}
    78  
    79  	if status == LookupNotFound {
    80  		log.Ctx(ctx).Debug().Str("id", req.ShareReference).Msg("Lookup Shared Not Found")
    81  		return &v0.LookupShareResponse{
    82  			Status: v0.LookupShareResponse_UNKNOWN_REFERENCE,
    83  		}, nil
    84  	}
    85  
    86  	if status == LookupConverted {
    87  		return &v0.LookupShareResponse{
    88  			Status:            v0.LookupShareResponse_UPGRADED_REFERENCE,
    89  			Schema:            shared.Schema,
    90  			RelationshipsYaml: shared.RelationshipsYaml,
    91  			ValidationYaml:    shared.ValidationYaml,
    92  			AssertionsYaml:    shared.AssertionsYaml,
    93  		}, nil
    94  	}
    95  
    96  	return &v0.LookupShareResponse{
    97  		Status:            v0.LookupShareResponse_VALID_REFERENCE,
    98  		Schema:            shared.Schema,
    99  		RelationshipsYaml: shared.RelationshipsYaml,
   100  		ValidationYaml:    shared.ValidationYaml,
   101  		AssertionsYaml:    shared.AssertionsYaml,
   102  	}, nil
   103  }
   104  
   105  func (ds *devServer) EditCheck(_ context.Context, _ *v0.EditCheckRequest) (*v0.EditCheckResponse, error) {
   106  	return nil, fmt.Errorf("no longer implemented. Please use the WebAssembly development package")
   107  }
   108  
   109  func (ds *devServer) Validate(_ context.Context, _ *v0.ValidateRequest) (*v0.ValidateResponse, error) {
   110  	return nil, fmt.Errorf("no longer implemented. Please use the WebAssembly development package")
   111  }
   112  
   113  func (ds *devServer) FormatSchema(_ context.Context, _ *v0.FormatSchemaRequest) (*v0.FormatSchemaResponse, error) {
   114  	return nil, fmt.Errorf("no longer implemented. Please use the WebAssembly development package")
   115  }
   116  
   117  func upgradeSchema(configs []string) (string, error) {
   118  	schema := ""
   119  	for _, config := range configs {
   120  		nsDef := core.NamespaceDefinition{}
   121  		nerr := prototext.Unmarshal([]byte(config), &nsDef)
   122  		if nerr != nil {
   123  			return "", fmt.Errorf("could not upgrade schema due to parse error: %w", nerr)
   124  		}
   125  
   126  		generated, _, err := generator.GenerateSource(&nsDef)
   127  		if err != nil {
   128  			return "", err
   129  		}
   130  
   131  		schema += generated
   132  		schema += "\n\n"
   133  	}
   134  
   135  	return schema, nil
   136  }