mirror of
https://github.com/holos-run/holos.git
synced 2026-03-20 01:04:59 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ce88bf491 | ||
|
|
b05571a595 | ||
|
|
4edfc71d68 | ||
|
|
3049694a0a | ||
|
|
5860c5747b | ||
|
|
d3c2d55706 |
3
.github/workflows/release.yaml
vendored
3
.github/workflows/release.yaml
vendored
@@ -54,6 +54,9 @@ jobs:
|
||||
- name: List keys
|
||||
run: gpg -K
|
||||
|
||||
- name: Git diff
|
||||
run: git diff
|
||||
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v5
|
||||
with:
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -6,3 +6,4 @@ coverage.out
|
||||
*.hold/
|
||||
/deploy/
|
||||
.vscode/
|
||||
tmp/
|
||||
|
||||
@@ -34,7 +34,7 @@ let OBJECTS = #APIObjects & {
|
||||
containers: [
|
||||
{
|
||||
name: Holos
|
||||
image: "271053619184.dkr.ecr.us-east-2.amazonaws.com/holos-run/holos-server/holos:0.74.0"
|
||||
image: "271053619184.dkr.ecr.us-east-2.amazonaws.com/holos-run/holos-server/holos:v0.76.0"
|
||||
imagePullPolicy: "Always"
|
||||
env: [
|
||||
{
|
||||
|
||||
4
go.mod
4
go.mod
@@ -6,6 +6,7 @@ require (
|
||||
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.33.0-20240401165935-b983156c5e99.1
|
||||
connectrpc.com/connect v1.16.0
|
||||
connectrpc.com/grpcreflect v1.2.0
|
||||
connectrpc.com/otelconnect v0.7.0
|
||||
connectrpc.com/validate v0.1.0
|
||||
cuelang.org/go v0.8.0
|
||||
entgo.io/ent v0.13.1
|
||||
@@ -30,6 +31,7 @@ require (
|
||||
github.com/stretchr/testify v1.9.0
|
||||
golang.org/x/net v0.24.0
|
||||
golang.org/x/tools v0.20.0
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240325203815-454cdb8f5daa
|
||||
google.golang.org/protobuf v1.33.1-0.20240408130810-98873a205002
|
||||
honnef.co/go/tools v0.4.7
|
||||
k8s.io/api v0.29.2
|
||||
@@ -44,7 +46,6 @@ require (
|
||||
ariga.io/atlas v0.19.1-0.20240203083654-5948b60a8e43 // indirect
|
||||
cloud.google.com/go/compute v1.23.3 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
connectrpc.com/otelconnect v0.7.0 // indirect
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20240314152124-224736b49f2e // indirect
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
|
||||
@@ -248,7 +249,6 @@ require (
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240325203815-454cdb8f5daa // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240325203815-454cdb8f5daa // indirect
|
||||
google.golang.org/grpc v1.62.1 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
|
||||
43
internal/cli/generate/generate.go
Normal file
43
internal/cli/generate/generate.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/holos-run/holos/internal/cli/command"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/generate"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// New returns a new generate command.
|
||||
func New(cfg *holos.Config) *cobra.Command {
|
||||
cmd := command.New("generate")
|
||||
cmd.Aliases = []string{"gen"}
|
||||
cmd.Short = "generate local resources"
|
||||
cmd.Args = cobra.NoArgs
|
||||
|
||||
cmd.AddCommand(NewPlatform(cfg))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewPlatform(cfg *holos.Config) *cobra.Command {
|
||||
cmd := command.New("platform")
|
||||
cmd.Use = "platform [flags] PLATFORM"
|
||||
cmd.Short = "generate a platform from an embedded schematic"
|
||||
cmd.Long = fmt.Sprintf("Embedded platforms available to generate:\n\n %s", strings.Join(generate.Platforms(), "\n "))
|
||||
cmd.Args = cobra.ExactArgs(1)
|
||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Root().Context()
|
||||
for _, name := range args {
|
||||
if err := generate.GeneratePlatform(ctx, name); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
@@ -5,9 +5,11 @@ import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
cue "cuelang.org/go/cue/errors"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"google.golang.org/genproto/googleapis/rpc/errdetails"
|
||||
)
|
||||
|
||||
// MakeMain makes a main function for the cli or tests.
|
||||
@@ -25,7 +27,8 @@ func MakeMain(options ...holos.Option) func() int {
|
||||
|
||||
// HandleError is the top level error handler that unwraps and logs errors.
|
||||
func HandleError(ctx context.Context, err error, hc *holos.Config) (exitCode int) {
|
||||
log := hc.NewTopLevelLogger()
|
||||
// Connect errors have codes, log them.
|
||||
log := hc.NewTopLevelLogger().With("code", connect.CodeOf(err))
|
||||
var cueErr cue.Error
|
||||
var errAt *errors.ErrorAt
|
||||
const msg = "could not execute"
|
||||
@@ -39,5 +42,24 @@ func HandleError(ctx context.Context, err error, hc *holos.Config) (exitCode int
|
||||
msg := cue.Details(cueErr, nil)
|
||||
_, _ = fmt.Fprint(hc.Stderr(), msg)
|
||||
}
|
||||
// connect errors have details and codes.
|
||||
// Refer to https://connectrpc.com/docs/go/errors
|
||||
if connectErr := new(connect.Error); errors.As(err, &connectErr) {
|
||||
for _, detail := range connectErr.Details() {
|
||||
msg, valueErr := detail.Value()
|
||||
if valueErr != nil {
|
||||
log.WarnContext(ctx, "could not decode error detail", "err", err, "type", detail.Type(), "note", "this usually means we don't have the schema for the protobuf message type")
|
||||
continue
|
||||
}
|
||||
if info, ok := msg.(*errdetails.ErrorInfo); ok {
|
||||
logDetail := log.With("reason", info.GetReason(), "domain", info.GetDomain())
|
||||
for k, v := range info.GetMetadata() {
|
||||
logDetail = logDetail.With(k, v)
|
||||
}
|
||||
logDetail.ErrorContext(ctx, info.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
34
internal/cli/register/register.go
Normal file
34
internal/cli/register/register.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package register
|
||||
|
||||
import (
|
||||
"github.com/holos-run/holos/internal/cli/command"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"github.com/holos-run/holos/internal/register"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// New returns a new register command.
|
||||
func New(cfg *holos.Config) *cobra.Command {
|
||||
cmd := command.New("register")
|
||||
cmd.Short = "register with holos server"
|
||||
cmd.Args = cobra.NoArgs
|
||||
|
||||
config := register.NewConfig(cfg)
|
||||
cmd.PersistentFlags().AddGoFlagSet(config.ClientFlagSet())
|
||||
cmd.PersistentFlags().AddGoFlagSet(config.TokenFlagSet())
|
||||
|
||||
cmd.AddCommand(NewUser(config))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// NewUser returns a command to register a user with holos server.
|
||||
func NewUser(cfg *register.Config) *cobra.Command {
|
||||
cmd := command.New("user")
|
||||
cmd.Short = "user registration workflow"
|
||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Root().Context()
|
||||
return register.User(ctx, cfg)
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
@@ -5,23 +5,26 @@ import (
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/holos-run/holos/version"
|
||||
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"github.com/holos-run/holos/internal/logger"
|
||||
"github.com/holos-run/holos/internal/server"
|
||||
|
||||
"github.com/holos-run/holos/internal/cli/build"
|
||||
"github.com/holos-run/holos/internal/cli/controller"
|
||||
"github.com/holos-run/holos/internal/cli/create"
|
||||
"github.com/holos-run/holos/internal/cli/generate"
|
||||
"github.com/holos-run/holos/internal/cli/get"
|
||||
"github.com/holos-run/holos/internal/cli/kv"
|
||||
"github.com/holos-run/holos/internal/cli/login"
|
||||
"github.com/holos-run/holos/internal/cli/logout"
|
||||
"github.com/holos-run/holos/internal/cli/preflight"
|
||||
"github.com/holos-run/holos/internal/cli/register"
|
||||
"github.com/holos-run/holos/internal/cli/render"
|
||||
"github.com/holos-run/holos/internal/cli/rpc"
|
||||
"github.com/holos-run/holos/internal/cli/token"
|
||||
"github.com/holos-run/holos/internal/cli/txtar"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"github.com/holos-run/holos/internal/logger"
|
||||
"github.com/holos-run/holos/version"
|
||||
)
|
||||
|
||||
// New returns a new root *cobra.Command for command line execution.
|
||||
@@ -41,7 +44,7 @@ func New(cfg *holos.Config) *cobra.Command {
|
||||
return err
|
||||
}
|
||||
log := cfg.Logger()
|
||||
c.SetContext(logger.NewContext(c.Context(), log))
|
||||
c.Root().SetContext(logger.NewContext(c.Context(), log))
|
||||
// Set the default logger after flag parsing.
|
||||
slog.SetDefault(log)
|
||||
return nil
|
||||
@@ -65,6 +68,8 @@ func New(cfg *holos.Config) *cobra.Command {
|
||||
rootCmd.AddCommand(logout.New(cfg))
|
||||
rootCmd.AddCommand(token.New(cfg))
|
||||
rootCmd.AddCommand(rpc.New(cfg))
|
||||
rootCmd.AddCommand(generate.New(cfg))
|
||||
rootCmd.AddCommand(register.New(cfg))
|
||||
|
||||
// Maybe not needed?
|
||||
rootCmd.AddCommand(txtar.New(cfg))
|
||||
|
||||
@@ -45,7 +45,7 @@ func NewPlatformModel(cfg *Config) *cobra.Command {
|
||||
cmd := command.New("platform-model")
|
||||
cmd.Short = "get the platform model"
|
||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
ctx := cmd.Root().Context()
|
||||
log := logger.FromContext(ctx)
|
||||
// client := platformconnect.NewPlatformServiceClient(token.NewClient(cfg.token), cfg.client.Server())
|
||||
client := platformconnect.NewPlatformServiceClient(token.NewClient(cfg.token), cfg.client.Server())
|
||||
|
||||
2027
internal/frontend/holos/package-lock.json
generated
2027
internal/frontend/holos/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -40,7 +40,7 @@
|
||||
"@angular-eslint/template-parser": "17.3.0",
|
||||
"@angular/cli": "^17.3.4",
|
||||
"@angular/compiler-cli": "^17.3.0",
|
||||
"@bufbuild/buf": "^1.31.0",
|
||||
"@bufbuild/buf": "^1.32.0",
|
||||
"@bufbuild/protoc-gen-es": "^1.9.0",
|
||||
"@connectrpc/protoc-gen-connect-es": "^1.4.0",
|
||||
"@connectrpc/protoc-gen-connect-query": "^1.4.0",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { CreateUserRequest, CreateUserResponse, GetUserRequest, GetUserResponse } from "./user_service_pb.js";
|
||||
import { CreateUserRequest, CreateUserResponse, GetUserRequest, GetUserResponse, RegisterUserRequest, RegisterUserResponse } from "./user_service_pb.js";
|
||||
import { MethodKind } from "@bufbuild/protobuf";
|
||||
|
||||
/**
|
||||
@@ -36,6 +36,17 @@ export const UserService = {
|
||||
O: GetUserResponse,
|
||||
kind: MethodKind.Unary,
|
||||
},
|
||||
/**
|
||||
* Register an user and initialize an organization, bare platform, and reference platform.
|
||||
*
|
||||
* @generated from rpc holos.user.v1alpha1.UserService.RegisterUser
|
||||
*/
|
||||
registerUser: {
|
||||
name: "RegisterUser",
|
||||
I: RegisterUserRequest,
|
||||
O: RegisterUserResponse,
|
||||
kind: MethodKind.Unary,
|
||||
},
|
||||
}
|
||||
} as const;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialM
|
||||
import { FieldMask, Message, proto3 } from "@bufbuild/protobuf";
|
||||
import { User } from "./user_pb.js";
|
||||
import { UserRef } from "../../object/v1alpha1/object_pb.js";
|
||||
import { Organization } from "../../organization/v1alpha1/organization_pb.js";
|
||||
|
||||
/**
|
||||
* Create a User from the oidc id token claims or the provided user. Each one
|
||||
@@ -172,3 +173,118 @@ export class GetUserResponse extends Message<GetUserResponse> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a User from the oidc id token claims or the provided user. Each one
|
||||
* of subject, email, and user id must be globally unique.
|
||||
*
|
||||
* @generated from message holos.user.v1alpha1.RegisterUserRequest
|
||||
*/
|
||||
export class RegisterUserRequest extends Message<RegisterUserRequest> {
|
||||
/**
|
||||
* User resource to create. If absent, the server populates User fields with
|
||||
* the oidc id token claims of the authenticated request.
|
||||
* NOTE: The server may ignore this request field and register the user solely
|
||||
* from authenticated identity claims.
|
||||
*
|
||||
* @generated from field: optional holos.user.v1alpha1.User user = 1;
|
||||
*/
|
||||
user?: User;
|
||||
|
||||
/**
|
||||
* Mask of the user fields to include in the response.
|
||||
*
|
||||
* @generated from field: optional google.protobuf.FieldMask user_mask = 2;
|
||||
*/
|
||||
userMask?: FieldMask;
|
||||
|
||||
/**
|
||||
* Organization resource to create. If absent, the server generates an
|
||||
* organization based on the user fields.
|
||||
* NOTE: The server may ignore this request field and register the
|
||||
* organization solely from authenticated identity claims.
|
||||
*
|
||||
* @generated from field: optional holos.organization.v1alpha1.Organization organization = 3;
|
||||
*/
|
||||
organization?: Organization;
|
||||
|
||||
/**
|
||||
* Mask of the organization fields to include in the response.
|
||||
*
|
||||
* @generated from field: optional google.protobuf.FieldMask organization_mask = 4;
|
||||
*/
|
||||
organizationMask?: FieldMask;
|
||||
|
||||
constructor(data?: PartialMessage<RegisterUserRequest>) {
|
||||
super();
|
||||
proto3.util.initPartial(data, this);
|
||||
}
|
||||
|
||||
static readonly runtime: typeof proto3 = proto3;
|
||||
static readonly typeName = "holos.user.v1alpha1.RegisterUserRequest";
|
||||
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
||||
{ no: 1, name: "user", kind: "message", T: User, opt: true },
|
||||
{ no: 2, name: "user_mask", kind: "message", T: FieldMask, opt: true },
|
||||
{ no: 3, name: "organization", kind: "message", T: Organization, opt: true },
|
||||
{ no: 4, name: "organization_mask", kind: "message", T: FieldMask, opt: true },
|
||||
]);
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): RegisterUserRequest {
|
||||
return new RegisterUserRequest().fromBinary(bytes, options);
|
||||
}
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): RegisterUserRequest {
|
||||
return new RegisterUserRequest().fromJson(jsonValue, options);
|
||||
}
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): RegisterUserRequest {
|
||||
return new RegisterUserRequest().fromJsonString(jsonString, options);
|
||||
}
|
||||
|
||||
static equals(a: RegisterUserRequest | PlainMessage<RegisterUserRequest> | undefined, b: RegisterUserRequest | PlainMessage<RegisterUserRequest> | undefined): boolean {
|
||||
return proto3.util.equals(RegisterUserRequest, a, b);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message holos.user.v1alpha1.RegisterUserResponse
|
||||
*/
|
||||
export class RegisterUserResponse extends Message<RegisterUserResponse> {
|
||||
/**
|
||||
* @generated from field: holos.user.v1alpha1.User user = 1;
|
||||
*/
|
||||
user?: User;
|
||||
|
||||
/**
|
||||
* @generated from field: holos.organization.v1alpha1.Organization organization = 2;
|
||||
*/
|
||||
organization?: Organization;
|
||||
|
||||
constructor(data?: PartialMessage<RegisterUserResponse>) {
|
||||
super();
|
||||
proto3.util.initPartial(data, this);
|
||||
}
|
||||
|
||||
static readonly runtime: typeof proto3 = proto3;
|
||||
static readonly typeName = "holos.user.v1alpha1.RegisterUserResponse";
|
||||
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
||||
{ no: 1, name: "user", kind: "message", T: User },
|
||||
{ no: 2, name: "organization", kind: "message", T: Organization },
|
||||
]);
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): RegisterUserResponse {
|
||||
return new RegisterUserResponse().fromBinary(bytes, options);
|
||||
}
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): RegisterUserResponse {
|
||||
return new RegisterUserResponse().fromJson(jsonValue, options);
|
||||
}
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): RegisterUserResponse {
|
||||
return new RegisterUserResponse().fromJsonString(jsonString, options);
|
||||
}
|
||||
|
||||
static equals(a: RegisterUserResponse | PlainMessage<RegisterUserResponse> | undefined, b: RegisterUserResponse | PlainMessage<RegisterUserResponse> | undefined): boolean {
|
||||
return proto3.util.equals(RegisterUserResponse, a, b);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
97
internal/generate/generate.go
Normal file
97
internal/generate/generate.go
Normal file
@@ -0,0 +1,97 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"embed"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/server/middleware/logger"
|
||||
)
|
||||
|
||||
//go:embed all:platforms
|
||||
var platforms embed.FS
|
||||
|
||||
// root is the root path to copy platform cue code from.
|
||||
const root = "platforms"
|
||||
|
||||
// Platforms returns a slice of embedded platforms or nil if there are none.
|
||||
func Platforms() []string {
|
||||
entries, err := fs.ReadDir(platforms, root)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
dirs := make([]string, 0, len(entries))
|
||||
for _, entry := range entries {
|
||||
if entry.IsDir() && entry.Name() != "cue.mod" {
|
||||
dirs = append(dirs, entry.Name())
|
||||
}
|
||||
}
|
||||
return dirs
|
||||
}
|
||||
|
||||
// GeneratePlatform writes the cue code for a platform to the local working
|
||||
// directory.
|
||||
func GeneratePlatform(ctx context.Context, name string) error {
|
||||
// Check for a valid platform
|
||||
platformPath := filepath.Join(root, name)
|
||||
if !dirExists(platforms, platformPath) {
|
||||
return errors.Wrap(fmt.Errorf("cannot generate: have: [%s] want: %+v", name, Platforms()))
|
||||
}
|
||||
|
||||
// Copy the cue.mod directory
|
||||
if err := copyEmbedFS(ctx, platforms, filepath.Join(root, "cue.mod"), "cue.mod"); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
// Copy the named platform
|
||||
if err := copyEmbedFS(ctx, platforms, platformPath, "."); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func dirExists(srcFS embed.FS, path string) bool {
|
||||
entries, err := fs.ReadDir(srcFS, path)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return len(entries) > 0
|
||||
}
|
||||
|
||||
func copyEmbedFS(ctx context.Context, srcFS embed.FS, srcPath, dstPath string) error {
|
||||
log := logger.FromContext(ctx)
|
||||
return fs.WalkDir(srcFS, srcPath, func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
relPath, err := filepath.Rel(srcPath, path)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
dstFullPath := filepath.Join(dstPath, relPath)
|
||||
|
||||
if d.IsDir() {
|
||||
if err := os.MkdirAll(dstFullPath, os.ModePerm); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
log.DebugContext(ctx, "created", "directory", dstFullPath)
|
||||
} else {
|
||||
data, err := srcFS.ReadFile(path)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
if err := os.WriteFile(dstFullPath, data, os.ModePerm); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
log.DebugContext(ctx, "wrote", "file", dstFullPath)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
70
internal/holos/clientcontext.go
Normal file
70
internal/holos/clientcontext.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package holos
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/holos-run/holos/internal/logger"
|
||||
"k8s.io/client-go/util/homedir"
|
||||
)
|
||||
|
||||
// ClientContext represents the context the holos api is working in. Used to
|
||||
// store and recall values from the filesystem.
|
||||
type ClientContext struct {
|
||||
// OrgID is the organization id of the current context.
|
||||
OrgID string `json:"org_id"`
|
||||
// UserID is the user id of the current context.
|
||||
UserID string `json:"user_id"`
|
||||
}
|
||||
|
||||
func (cc *ClientContext) Save(ctx context.Context) error {
|
||||
log := logger.FromContext(ctx)
|
||||
config := cc.configFile()
|
||||
data, err := json.MarshalIndent(cc, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.WriteFile(config, data, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
log.DebugContext(ctx, "saved", "path", config, "bytes", len(data))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cc *ClientContext) Load(ctx context.Context) error {
|
||||
log := logger.FromContext(ctx)
|
||||
config := cc.configFile()
|
||||
data, err := os.ReadFile(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, cc); err != nil {
|
||||
return err
|
||||
}
|
||||
log.DebugContext(ctx, "loaded", "path", config, "bytes", len(data))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Exists returns true if the client context file exists.
|
||||
func (cc *ClientContext) Exists() bool {
|
||||
_, err := os.Stat(cc.configFile())
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func (cc *ClientContext) configFile() string {
|
||||
config := "client-context.json"
|
||||
if home := homedir.HomeDir(); home != "" {
|
||||
dir := filepath.Join(home, ".holos")
|
||||
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
|
||||
slog.Warn("could not mkdir", "path", dir, "err", err)
|
||||
}
|
||||
config = filepath.Join(home, ".holos", config)
|
||||
}
|
||||
return config
|
||||
}
|
||||
134
internal/register/register.go
Normal file
134
internal/register/register.go
Normal file
@@ -0,0 +1,134 @@
|
||||
package register
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"github.com/holos-run/holos/internal/server/middleware/logger"
|
||||
"github.com/holos-run/holos/internal/token"
|
||||
org "github.com/holos-run/holos/service/gen/holos/organization/v1alpha1"
|
||||
"github.com/holos-run/holos/service/gen/holos/organization/v1alpha1/organizationconnect"
|
||||
user "github.com/holos-run/holos/service/gen/holos/user/v1alpha1"
|
||||
"github.com/holos-run/holos/service/gen/holos/user/v1alpha1/userconnect"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
holos *holos.Config
|
||||
client *holos.ClientConfig
|
||||
token *token.Config
|
||||
}
|
||||
|
||||
func (c *Config) ClientFlagSet() *flag.FlagSet {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.client.FlagSet()
|
||||
}
|
||||
|
||||
func (c *Config) TokenFlagSet() *flag.FlagSet {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.token.FlagSet()
|
||||
}
|
||||
|
||||
func NewConfig(cfg *holos.Config) *Config {
|
||||
return &Config{
|
||||
holos: cfg,
|
||||
client: holos.NewClientConfig(),
|
||||
token: token.NewConfig(),
|
||||
}
|
||||
}
|
||||
|
||||
// User registers the user with the holos server.
|
||||
func User(ctx context.Context, cfg *Config) error {
|
||||
log := logger.FromContext(ctx)
|
||||
client := userconnect.NewUserServiceClient(token.NewClient(cfg.token), cfg.client.Server())
|
||||
|
||||
var err error
|
||||
var u *user.User
|
||||
var o *org.Organization
|
||||
cc := &holos.ClientContext{}
|
||||
|
||||
u, err = getUser(ctx, client)
|
||||
if err != nil {
|
||||
if connect.CodeOf(err) != connect.CodeNotFound {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
if u, o, err = registerUser(ctx, client); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
// Save the registration context
|
||||
cc.OrgID = o.GetOrgId()
|
||||
cc.UserID = u.GetId()
|
||||
if err := cc.Save(ctx); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
log.InfoContext(ctx, "created user", "email", u.GetEmail(), "id", u.GetId())
|
||||
}
|
||||
|
||||
if cc.Exists() {
|
||||
if err := cc.Load(ctx); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the current user id gets saved.
|
||||
cc.UserID = u.GetId()
|
||||
|
||||
// Ensure an org ID gets saved.
|
||||
if cc.OrgID == "" {
|
||||
org, err := getOrg(ctx, cfg)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
cc.OrgID = org.GetOrgId()
|
||||
}
|
||||
|
||||
// One last save, we know we have the user id and org id at this point.
|
||||
if err := cc.Save(ctx); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
log.InfoContext(ctx, "user", "email", u.GetEmail(), "user_id", cc.UserID, "org_id", cc.OrgID)
|
||||
return nil
|
||||
}
|
||||
|
||||
func getUser(ctx context.Context, client userconnect.UserServiceClient) (*user.User, error) {
|
||||
req := connect.NewRequest(&user.GetUserRequest{})
|
||||
resp, err := client.GetUser(ctx, req)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
return resp.Msg.GetUser(), nil
|
||||
}
|
||||
|
||||
// getOrg returns the first organization returned from the ListOrganizations rpc
|
||||
// method.
|
||||
func getOrg(ctx context.Context, cfg *Config) (*org.Organization, error) {
|
||||
client := organizationconnect.NewOrganizationServiceClient(token.NewClient(cfg.token), cfg.client.Server())
|
||||
req := connect.NewRequest(&org.ListOrganizationsRequest{})
|
||||
resp, err := client.ListOrganizations(ctx, req)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
orgs := resp.Msg.GetOrganizations()
|
||||
if len(orgs) == 0 {
|
||||
return nil, nil
|
||||
} else {
|
||||
return orgs[0], nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func registerUser(ctx context.Context, client userconnect.UserServiceClient) (*user.User, *org.Organization, error) {
|
||||
req := connect.NewRequest(&user.RegisterUserRequest{})
|
||||
resp, err := client.RegisterUser(ctx, req)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err)
|
||||
}
|
||||
return resp.Msg.GetUser(), resp.Msg.GetOrganization(), nil
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
@@ -20,7 +21,7 @@ import (
|
||||
fieldmask_utils "github.com/mennanov/fieldmask-utils"
|
||||
)
|
||||
|
||||
const AdminEmail = "jeff@openinfrastructure.co"
|
||||
var adminEmails = []string{"jeff@openinfrastructure.co", "jeff@ois.run"}
|
||||
|
||||
// NewSystemHandler returns a new SystemService implementation.
|
||||
func NewSystemHandler(db *ent.Client) *SystemHandler {
|
||||
@@ -37,8 +38,8 @@ func (h *SystemHandler) checkAdmin(ctx context.Context) error {
|
||||
if err != nil {
|
||||
return connect.NewError(connect.CodePermissionDenied, errors.Wrap(err))
|
||||
}
|
||||
if authnID.Email() != AdminEmail {
|
||||
err := fmt.Errorf("not an admin:\n\thave (%+v)\n\twant (%+v)", authnID.Email(), AdminEmail)
|
||||
if !slices.Contains(adminEmails, authnID.Email()) {
|
||||
err := fmt.Errorf("not an admin:\n\thave (%+v)\n\twant (%+v)", authnID.Email(), strings.Join(adminEmails, ","))
|
||||
return connect.NewError(connect.CodePermissionDenied, errors.Wrap(err))
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -1,18 +1,26 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/holos-run/holos/internal/ent"
|
||||
"github.com/holos-run/holos/internal/ent/user"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/logger"
|
||||
"github.com/holos-run/holos/internal/server/middleware/authn"
|
||||
"github.com/holos-run/holos/internal/strings"
|
||||
object "github.com/holos-run/holos/service/gen/holos/object/v1alpha1"
|
||||
org "github.com/holos-run/holos/service/gen/holos/organization/v1alpha1"
|
||||
storage "github.com/holos-run/holos/service/gen/holos/storage/v1alpha1"
|
||||
holos "github.com/holos-run/holos/service/gen/holos/user/v1alpha1"
|
||||
fieldmask_utils "github.com/mennanov/fieldmask-utils"
|
||||
"google.golang.org/genproto/googleapis/rpc/errdetails"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
)
|
||||
|
||||
@@ -50,8 +58,12 @@ func (h *UserHandler) GetUser(ctx context.Context, req *connect.Request[holos.Ge
|
||||
}
|
||||
|
||||
func (h *UserHandler) CreateUser(ctx context.Context, req *connect.Request[holos.CreateUserRequest]) (*connect.Response[holos.CreateUserResponse], error) {
|
||||
_, err := authn.FromContext(ctx)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodePermissionDenied, errors.Wrap(err))
|
||||
}
|
||||
|
||||
var createdUser *ent.User
|
||||
var err error
|
||||
if rpcUser := req.Msg.GetUser(); rpcUser != nil {
|
||||
createdUser, err = h.createUser(ctx, h.db, rpcUser)
|
||||
} else {
|
||||
@@ -67,6 +79,145 @@ func (h *UserHandler) CreateUser(ctx context.Context, req *connect.Request[holos
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (h *UserHandler) RegisterUser(ctx context.Context, req *connect.Request[holos.RegisterUserRequest]) (*connect.Response[holos.RegisterUserResponse], error) {
|
||||
authnID, err := authn.FromContext(ctx)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodePermissionDenied, errors.Wrap(err))
|
||||
}
|
||||
|
||||
var dbUser *ent.User
|
||||
var dbOrg *ent.Organization
|
||||
var rpcUser holos.User
|
||||
var rpcOrg org.Organization
|
||||
|
||||
userMask, err := fieldmask_utils.MaskFromProtoFieldMask(req.Msg.GetUserMask(), strings.PascalCase)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInvalidArgument, errors.Wrap(err))
|
||||
}
|
||||
orgMask, err := fieldmask_utils.MaskFromProtoFieldMask(req.Msg.GetOrganizationMask(), strings.PascalCase)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInvalidArgument, errors.Wrap(err))
|
||||
}
|
||||
|
||||
// Server assigns IDs.
|
||||
userID, err := uuid.NewV7()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(connect.NewError(connect.CodeInternal, err))
|
||||
}
|
||||
orgID, err := uuid.NewV7()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(connect.NewError(connect.CodeInternal, err))
|
||||
}
|
||||
bareID, err := uuid.NewV7()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(connect.NewError(connect.CodeInternal, err))
|
||||
}
|
||||
refID, err := uuid.NewV7()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(connect.NewError(connect.CodeInternal, err))
|
||||
}
|
||||
|
||||
// Perform registration in a single transaction.
|
||||
if err := WithTx(ctx, h.db, func(tx *ent.Tx) (err error) {
|
||||
// Create the user
|
||||
dbUser, err = tx.User.Create().
|
||||
SetID(userID).
|
||||
SetEmail(authnID.Email()).
|
||||
SetIss(authnID.Issuer()).
|
||||
SetSub(authnID.Subject()).
|
||||
SetName(authnID.Name()).
|
||||
Save(ctx)
|
||||
if err != nil {
|
||||
if ent.IsConstraintError(err) {
|
||||
rpcErr := connect.NewError(connect.CodeAlreadyExists, errors.New("user already registered"))
|
||||
errInfo := &errdetails.ErrorInfo{
|
||||
Reason: "USER_EXISTS",
|
||||
Domain: "user.holos.run",
|
||||
Metadata: map[string]string{"email": authnID.Email()},
|
||||
}
|
||||
if detail, detailErr := connect.NewErrorDetail(errInfo); detailErr != nil {
|
||||
logger.FromContext(ctx).ErrorContext(ctx, detailErr.Error(), "err", detailErr)
|
||||
} else {
|
||||
rpcErr.AddDetail(detail)
|
||||
}
|
||||
return errors.Wrap(rpcErr)
|
||||
}
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
// Create the org
|
||||
dbOrg, err = tx.Organization.Create().
|
||||
SetID(orgID).
|
||||
SetName(cleanAndAppendRandom(authnID.Name())).
|
||||
SetDisplayName(authnID.GivenName() + "'s Org").
|
||||
SetCreatorID(userID).
|
||||
SetEditorID(userID).
|
||||
AddUserIDs(userID).
|
||||
Save(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
// Create the platforms.
|
||||
decoder := json.NewDecoder(bytes.NewReader([]byte(BareForm)))
|
||||
decoder.DisallowUnknownFields()
|
||||
var form storage.Form
|
||||
if err := decoder.Decode(&form); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
decoder = json.NewDecoder(bytes.NewReader([]byte(Model)))
|
||||
decoder.DisallowUnknownFields()
|
||||
var model storage.Model
|
||||
if err := decoder.Decode(&model); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
// Add the platforms.
|
||||
err = tx.Platform.Create().
|
||||
SetID(bareID).
|
||||
SetName("bare").
|
||||
SetDisplayName("Bare Platform").
|
||||
SetForm(&form).
|
||||
SetModel(&model).
|
||||
SetCreatorID(userID).
|
||||
SetEditorID(userID).
|
||||
SetOrgID(orgID).
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
err = tx.Platform.Create().
|
||||
SetID(refID).
|
||||
SetName("reference").
|
||||
SetDisplayName("Holos Reference Platform").
|
||||
SetForm(&form).
|
||||
SetModel(&model).
|
||||
SetCreatorID(userID).
|
||||
SetEditorID(userID).
|
||||
SetOrgID(orgID).
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, errors.Wrap(connect.NewError(connect.CodeFailedPrecondition, err))
|
||||
}
|
||||
|
||||
if err = fieldmask_utils.StructToStruct(userMask, UserToRPC(dbUser), &rpcUser); err != nil {
|
||||
return nil, connect.NewError(connect.CodeInvalidArgument, errors.Wrap(err))
|
||||
}
|
||||
if err = fieldmask_utils.StructToStruct(orgMask, OrganizationToRPC(dbOrg), &rpcOrg); err != nil {
|
||||
return nil, connect.NewError(connect.CodeInvalidArgument, errors.Wrap(err))
|
||||
}
|
||||
|
||||
msg := holos.RegisterUserResponse{
|
||||
User: &rpcUser,
|
||||
Organization: &rpcOrg,
|
||||
}
|
||||
|
||||
return connect.NewResponse(&msg), nil
|
||||
}
|
||||
|
||||
// UserToRPC returns an *holos.User adapted from *ent.User u.
|
||||
func UserToRPC(entity *ent.User) *holos.User {
|
||||
uid := entity.ID.String()
|
||||
|
||||
33
internal/server/interceptor/logger.go
Normal file
33
internal/server/interceptor/logger.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package interceptor
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"github.com/holos-run/holos/internal/server/middleware/logger"
|
||||
)
|
||||
|
||||
func NewLogger() connect.UnaryInterceptorFunc {
|
||||
interceptor := func(next connect.UnaryFunc) connect.UnaryFunc {
|
||||
return connect.UnaryFunc(func(ctx context.Context, req connect.AnyRequest) (connect.AnyResponse, error) {
|
||||
start := time.Now()
|
||||
rpcLogger := logger.FromContext(ctx).With("procedure", req.Spec().Procedure)
|
||||
ctx = logger.NewContext(ctx, rpcLogger)
|
||||
resp, err := next(ctx, req)
|
||||
go emitLog(ctx, start, err)
|
||||
return resp, err
|
||||
})
|
||||
}
|
||||
return connect.UnaryInterceptorFunc(interceptor)
|
||||
}
|
||||
|
||||
func emitLog(ctx context.Context, start time.Time, err error) {
|
||||
log := logger.FromContext(ctx)
|
||||
if err == nil {
|
||||
log = log.With("ok", true)
|
||||
} else {
|
||||
log = log.With("ok", false, "code", connect.CodeOf(err), "err", err)
|
||||
}
|
||||
log.InfoContext(ctx, "response", "duration", time.Since(start))
|
||||
}
|
||||
@@ -9,12 +9,14 @@ import (
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"connectrpc.com/grpcreflect"
|
||||
"connectrpc.com/otelconnect"
|
||||
"connectrpc.com/validate"
|
||||
"github.com/holos-run/holos/internal/ent"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/frontend"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"github.com/holos-run/holos/internal/server/handler"
|
||||
"github.com/holos-run/holos/internal/server/interceptor"
|
||||
"github.com/holos-run/holos/internal/server/middleware/authn"
|
||||
"github.com/holos-run/holos/internal/server/middleware/logger"
|
||||
"github.com/holos-run/holos/service/gen/holos/organization/v1alpha1/organizationconnect"
|
||||
@@ -113,7 +115,12 @@ func (s *Server) registerConnectRpc() error {
|
||||
return errors.Wrap(fmt.Errorf("could not initialize proto validation interceptor: %w", err))
|
||||
}
|
||||
|
||||
opts := connect.WithInterceptors(validator)
|
||||
otel, err := otelconnect.NewInterceptor()
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
opts := connect.WithInterceptors(interceptor.NewLogger(), otel, validator)
|
||||
|
||||
s.handle(userconnect.NewUserServiceHandler(handler.NewUserHandler(s.db), opts))
|
||||
s.handle(organizationconnect.NewOrganizationServiceHandler(handler.NewOrganizationHandler(s.db), opts))
|
||||
|
||||
@@ -8,6 +8,7 @@ package user
|
||||
|
||||
import (
|
||||
v1alpha1 "github.com/holos-run/holos/service/gen/holos/object/v1alpha1"
|
||||
v1alpha11 "github.com/holos-run/holos/service/gen/holos/organization/v1alpha1"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb"
|
||||
@@ -224,6 +225,144 @@ func (x *GetUserResponse) GetUser() *User {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Register a User from the oidc id token claims or the provided user. Each one
|
||||
// of subject, email, and user id must be globally unique.
|
||||
type RegisterUserRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// User resource to create. If absent, the server populates User fields with
|
||||
// the oidc id token claims of the authenticated request.
|
||||
// NOTE: The server may ignore this request field and register the user solely
|
||||
// from authenticated identity claims.
|
||||
User *User `protobuf:"bytes,1,opt,name=user,proto3,oneof" json:"user,omitempty"`
|
||||
// Mask of the user fields to include in the response.
|
||||
UserMask *fieldmaskpb.FieldMask `protobuf:"bytes,2,opt,name=user_mask,json=userMask,proto3,oneof" json:"user_mask,omitempty"`
|
||||
// Organization resource to create. If absent, the server generates an
|
||||
// organization based on the user fields.
|
||||
// NOTE: The server may ignore this request field and register the
|
||||
// organization solely from authenticated identity claims.
|
||||
Organization *v1alpha11.Organization `protobuf:"bytes,3,opt,name=organization,proto3,oneof" json:"organization,omitempty"`
|
||||
// Mask of the organization fields to include in the response.
|
||||
OrganizationMask *fieldmaskpb.FieldMask `protobuf:"bytes,4,opt,name=organization_mask,json=organizationMask,proto3,oneof" json:"organization_mask,omitempty"`
|
||||
}
|
||||
|
||||
func (x *RegisterUserRequest) Reset() {
|
||||
*x = RegisterUserRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_holos_user_v1alpha1_user_service_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *RegisterUserRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RegisterUserRequest) ProtoMessage() {}
|
||||
|
||||
func (x *RegisterUserRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_holos_user_v1alpha1_user_service_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RegisterUserRequest.ProtoReflect.Descriptor instead.
|
||||
func (*RegisterUserRequest) Descriptor() ([]byte, []int) {
|
||||
return file_holos_user_v1alpha1_user_service_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *RegisterUserRequest) GetUser() *User {
|
||||
if x != nil {
|
||||
return x.User
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *RegisterUserRequest) GetUserMask() *fieldmaskpb.FieldMask {
|
||||
if x != nil {
|
||||
return x.UserMask
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *RegisterUserRequest) GetOrganization() *v1alpha11.Organization {
|
||||
if x != nil {
|
||||
return x.Organization
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *RegisterUserRequest) GetOrganizationMask() *fieldmaskpb.FieldMask {
|
||||
if x != nil {
|
||||
return x.OrganizationMask
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type RegisterUserResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"`
|
||||
Organization *v1alpha11.Organization `protobuf:"bytes,2,opt,name=organization,proto3" json:"organization,omitempty"`
|
||||
}
|
||||
|
||||
func (x *RegisterUserResponse) Reset() {
|
||||
*x = RegisterUserResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_holos_user_v1alpha1_user_service_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *RegisterUserResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RegisterUserResponse) ProtoMessage() {}
|
||||
|
||||
func (x *RegisterUserResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_holos_user_v1alpha1_user_service_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RegisterUserResponse.ProtoReflect.Descriptor instead.
|
||||
func (*RegisterUserResponse) Descriptor() ([]byte, []int) {
|
||||
return file_holos_user_v1alpha1_user_service_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *RegisterUserResponse) GetUser() *User {
|
||||
if x != nil {
|
||||
return x.User
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *RegisterUserResponse) GetOrganization() *v1alpha11.Organization {
|
||||
if x != nil {
|
||||
return x.Organization
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_holos_user_v1alpha1_user_service_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_holos_user_v1alpha1_user_service_proto_rawDesc = []byte{
|
||||
@@ -232,7 +371,10 @@ var file_holos_user_v1alpha1_user_service_proto_rawDesc = []byte{
|
||||
0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e,
|
||||
0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x1e, 0x68,
|
||||
0x6f, 0x6c, 0x6f, 0x73, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
|
||||
0x61, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67,
|
||||
0x61, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2e, 0x68,
|
||||
0x6f, 0x6c, 0x6f, 0x73, 0x2f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x61, 0x6e,
|
||||
0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67,
|
||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66,
|
||||
0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
|
||||
0x22, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2f, 0x76, 0x31,
|
||||
@@ -260,24 +402,62 @@ var file_holos_user_v1alpha1_user_service_proto_rawDesc = []byte{
|
||||
0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x19, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76,
|
||||
0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73,
|
||||
0x65, 0x72, 0x32, 0xc6, 0x01, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69,
|
||||
0x63, 0x65, 0x12, 0x5f, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72,
|
||||
0x12, 0x26, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31,
|
||||
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65,
|
||||
0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73,
|
||||
0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43,
|
||||
0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x23,
|
||||
0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x61, 0x6c,
|
||||
0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x75, 0x73, 0x65, 0x72,
|
||||
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65,
|
||||
0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x41, 0x5a, 0x3f, 0x67,
|
||||
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2d,
|
||||
0x72, 0x75, 0x6e, 0x2f, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||
0x65, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2f, 0x75, 0x73, 0x65, 0x72,
|
||||
0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x75, 0x73, 0x65, 0x72, 0x62, 0x06,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x65, 0x72, 0x22, 0xe7, 0x02, 0x0a, 0x13, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x55,
|
||||
0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x75, 0x73,
|
||||
0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73,
|
||||
0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55,
|
||||
0x73, 0x65, 0x72, 0x48, 0x00, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x3c,
|
||||
0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x48, 0x01, 0x52,
|
||||
0x08, 0x75, 0x73, 0x65, 0x72, 0x4d, 0x61, 0x73, 0x6b, 0x88, 0x01, 0x01, 0x12, 0x52, 0x0a, 0x0c,
|
||||
0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x29, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x6f, 0x72, 0x67, 0x61, 0x6e,
|
||||
0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
|
||||
0x2e, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x02, 0x52,
|
||||
0x0c, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01,
|
||||
0x12, 0x4c, 0x0a, 0x11, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69,
|
||||
0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x48, 0x03, 0x52, 0x10, 0x6f, 0x72, 0x67, 0x61, 0x6e,
|
||||
0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x73, 0x6b, 0x88, 0x01, 0x01, 0x42, 0x07,
|
||||
0x0a, 0x05, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x75, 0x73, 0x65, 0x72,
|
||||
0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69,
|
||||
0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x6f, 0x72, 0x67, 0x61, 0x6e,
|
||||
0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x22, 0x94, 0x01, 0x0a,
|
||||
0x14, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x75, 0x73, 0x65, 0x72,
|
||||
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04,
|
||||
0x75, 0x73, 0x65, 0x72, 0x12, 0x4d, 0x0a, 0x0c, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x68, 0x6f, 0x6c,
|
||||
0x6f, 0x73, 0x2e, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
|
||||
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x32, 0xad, 0x02, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76,
|
||||
0x69, 0x63, 0x65, 0x12, 0x5f, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65,
|
||||
0x72, 0x12, 0x26, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76,
|
||||
0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73,
|
||||
0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x68, 0x6f, 0x6c, 0x6f,
|
||||
0x73, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
|
||||
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12,
|
||||
0x23, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x61,
|
||||
0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x75, 0x73, 0x65,
|
||||
0x72, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73,
|
||||
0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x65, 0x0a, 0x0c,
|
||||
0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x12, 0x28, 0x2e, 0x68,
|
||||
0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
|
||||
0x61, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x75,
|
||||
0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x67,
|
||||
0x69, 0x73, 0x74, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x00, 0x42, 0x41, 0x5a, 0x3f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
|
||||
0x6d, 0x2f, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2d, 0x72, 0x75, 0x6e, 0x2f, 0x68, 0x6f, 0x6c, 0x6f,
|
||||
0x73, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x68, 0x6f,
|
||||
0x6c, 0x6f, 0x73, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
|
||||
0x31, 0x3b, 0x75, 0x73, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -292,31 +472,42 @@ func file_holos_user_v1alpha1_user_service_proto_rawDescGZIP() []byte {
|
||||
return file_holos_user_v1alpha1_user_service_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_holos_user_v1alpha1_user_service_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_holos_user_v1alpha1_user_service_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
||||
var file_holos_user_v1alpha1_user_service_proto_goTypes = []interface{}{
|
||||
(*CreateUserRequest)(nil), // 0: holos.user.v1alpha1.CreateUserRequest
|
||||
(*CreateUserResponse)(nil), // 1: holos.user.v1alpha1.CreateUserResponse
|
||||
(*GetUserRequest)(nil), // 2: holos.user.v1alpha1.GetUserRequest
|
||||
(*GetUserResponse)(nil), // 3: holos.user.v1alpha1.GetUserResponse
|
||||
(*User)(nil), // 4: holos.user.v1alpha1.User
|
||||
(*v1alpha1.UserRef)(nil), // 5: holos.object.v1alpha1.UserRef
|
||||
(*fieldmaskpb.FieldMask)(nil), // 6: google.protobuf.FieldMask
|
||||
(*CreateUserRequest)(nil), // 0: holos.user.v1alpha1.CreateUserRequest
|
||||
(*CreateUserResponse)(nil), // 1: holos.user.v1alpha1.CreateUserResponse
|
||||
(*GetUserRequest)(nil), // 2: holos.user.v1alpha1.GetUserRequest
|
||||
(*GetUserResponse)(nil), // 3: holos.user.v1alpha1.GetUserResponse
|
||||
(*RegisterUserRequest)(nil), // 4: holos.user.v1alpha1.RegisterUserRequest
|
||||
(*RegisterUserResponse)(nil), // 5: holos.user.v1alpha1.RegisterUserResponse
|
||||
(*User)(nil), // 6: holos.user.v1alpha1.User
|
||||
(*v1alpha1.UserRef)(nil), // 7: holos.object.v1alpha1.UserRef
|
||||
(*fieldmaskpb.FieldMask)(nil), // 8: google.protobuf.FieldMask
|
||||
(*v1alpha11.Organization)(nil), // 9: holos.organization.v1alpha1.Organization
|
||||
}
|
||||
var file_holos_user_v1alpha1_user_service_proto_depIdxs = []int32{
|
||||
4, // 0: holos.user.v1alpha1.CreateUserRequest.user:type_name -> holos.user.v1alpha1.User
|
||||
4, // 1: holos.user.v1alpha1.CreateUserResponse.user:type_name -> holos.user.v1alpha1.User
|
||||
5, // 2: holos.user.v1alpha1.GetUserRequest.user:type_name -> holos.object.v1alpha1.UserRef
|
||||
6, // 3: holos.user.v1alpha1.GetUserRequest.field_mask:type_name -> google.protobuf.FieldMask
|
||||
4, // 4: holos.user.v1alpha1.GetUserResponse.user:type_name -> holos.user.v1alpha1.User
|
||||
0, // 5: holos.user.v1alpha1.UserService.CreateUser:input_type -> holos.user.v1alpha1.CreateUserRequest
|
||||
2, // 6: holos.user.v1alpha1.UserService.GetUser:input_type -> holos.user.v1alpha1.GetUserRequest
|
||||
1, // 7: holos.user.v1alpha1.UserService.CreateUser:output_type -> holos.user.v1alpha1.CreateUserResponse
|
||||
3, // 8: holos.user.v1alpha1.UserService.GetUser:output_type -> holos.user.v1alpha1.GetUserResponse
|
||||
7, // [7:9] is the sub-list for method output_type
|
||||
5, // [5:7] is the sub-list for method input_type
|
||||
5, // [5:5] is the sub-list for extension type_name
|
||||
5, // [5:5] is the sub-list for extension extendee
|
||||
0, // [0:5] is the sub-list for field type_name
|
||||
6, // 0: holos.user.v1alpha1.CreateUserRequest.user:type_name -> holos.user.v1alpha1.User
|
||||
6, // 1: holos.user.v1alpha1.CreateUserResponse.user:type_name -> holos.user.v1alpha1.User
|
||||
7, // 2: holos.user.v1alpha1.GetUserRequest.user:type_name -> holos.object.v1alpha1.UserRef
|
||||
8, // 3: holos.user.v1alpha1.GetUserRequest.field_mask:type_name -> google.protobuf.FieldMask
|
||||
6, // 4: holos.user.v1alpha1.GetUserResponse.user:type_name -> holos.user.v1alpha1.User
|
||||
6, // 5: holos.user.v1alpha1.RegisterUserRequest.user:type_name -> holos.user.v1alpha1.User
|
||||
8, // 6: holos.user.v1alpha1.RegisterUserRequest.user_mask:type_name -> google.protobuf.FieldMask
|
||||
9, // 7: holos.user.v1alpha1.RegisterUserRequest.organization:type_name -> holos.organization.v1alpha1.Organization
|
||||
8, // 8: holos.user.v1alpha1.RegisterUserRequest.organization_mask:type_name -> google.protobuf.FieldMask
|
||||
6, // 9: holos.user.v1alpha1.RegisterUserResponse.user:type_name -> holos.user.v1alpha1.User
|
||||
9, // 10: holos.user.v1alpha1.RegisterUserResponse.organization:type_name -> holos.organization.v1alpha1.Organization
|
||||
0, // 11: holos.user.v1alpha1.UserService.CreateUser:input_type -> holos.user.v1alpha1.CreateUserRequest
|
||||
2, // 12: holos.user.v1alpha1.UserService.GetUser:input_type -> holos.user.v1alpha1.GetUserRequest
|
||||
4, // 13: holos.user.v1alpha1.UserService.RegisterUser:input_type -> holos.user.v1alpha1.RegisterUserRequest
|
||||
1, // 14: holos.user.v1alpha1.UserService.CreateUser:output_type -> holos.user.v1alpha1.CreateUserResponse
|
||||
3, // 15: holos.user.v1alpha1.UserService.GetUser:output_type -> holos.user.v1alpha1.GetUserResponse
|
||||
5, // 16: holos.user.v1alpha1.UserService.RegisterUser:output_type -> holos.user.v1alpha1.RegisterUserResponse
|
||||
14, // [14:17] is the sub-list for method output_type
|
||||
11, // [11:14] is the sub-list for method input_type
|
||||
11, // [11:11] is the sub-list for extension type_name
|
||||
11, // [11:11] is the sub-list for extension extendee
|
||||
0, // [0:11] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_holos_user_v1alpha1_user_service_proto_init() }
|
||||
@@ -374,16 +565,41 @@ func file_holos_user_v1alpha1_user_service_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_holos_user_v1alpha1_user_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RegisterUserRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_holos_user_v1alpha1_user_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RegisterUserResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
file_holos_user_v1alpha1_user_service_proto_msgTypes[0].OneofWrappers = []interface{}{}
|
||||
file_holos_user_v1alpha1_user_service_proto_msgTypes[2].OneofWrappers = []interface{}{}
|
||||
file_holos_user_v1alpha1_user_service_proto_msgTypes[4].OneofWrappers = []interface{}{}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_holos_user_v1alpha1_user_service_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 4,
|
||||
NumMessages: 6,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
||||
@@ -37,13 +37,17 @@ const (
|
||||
UserServiceCreateUserProcedure = "/holos.user.v1alpha1.UserService/CreateUser"
|
||||
// UserServiceGetUserProcedure is the fully-qualified name of the UserService's GetUser RPC.
|
||||
UserServiceGetUserProcedure = "/holos.user.v1alpha1.UserService/GetUser"
|
||||
// UserServiceRegisterUserProcedure is the fully-qualified name of the UserService's RegisterUser
|
||||
// RPC.
|
||||
UserServiceRegisterUserProcedure = "/holos.user.v1alpha1.UserService/RegisterUser"
|
||||
)
|
||||
|
||||
// These variables are the protoreflect.Descriptor objects for the RPCs defined in this package.
|
||||
var (
|
||||
userServiceServiceDescriptor = v1alpha1.File_holos_user_v1alpha1_user_service_proto.Services().ByName("UserService")
|
||||
userServiceCreateUserMethodDescriptor = userServiceServiceDescriptor.Methods().ByName("CreateUser")
|
||||
userServiceGetUserMethodDescriptor = userServiceServiceDescriptor.Methods().ByName("GetUser")
|
||||
userServiceServiceDescriptor = v1alpha1.File_holos_user_v1alpha1_user_service_proto.Services().ByName("UserService")
|
||||
userServiceCreateUserMethodDescriptor = userServiceServiceDescriptor.Methods().ByName("CreateUser")
|
||||
userServiceGetUserMethodDescriptor = userServiceServiceDescriptor.Methods().ByName("GetUser")
|
||||
userServiceRegisterUserMethodDescriptor = userServiceServiceDescriptor.Methods().ByName("RegisterUser")
|
||||
)
|
||||
|
||||
// UserServiceClient is a client for the holos.user.v1alpha1.UserService service.
|
||||
@@ -52,6 +56,8 @@ type UserServiceClient interface {
|
||||
CreateUser(context.Context, *connect.Request[v1alpha1.CreateUserRequest]) (*connect.Response[v1alpha1.CreateUserResponse], error)
|
||||
// Get an existing user by id, email, or subject.
|
||||
GetUser(context.Context, *connect.Request[v1alpha1.GetUserRequest]) (*connect.Response[v1alpha1.GetUserResponse], error)
|
||||
// Register an user and initialize an organization, bare platform, and reference platform.
|
||||
RegisterUser(context.Context, *connect.Request[v1alpha1.RegisterUserRequest]) (*connect.Response[v1alpha1.RegisterUserResponse], error)
|
||||
}
|
||||
|
||||
// NewUserServiceClient constructs a client for the holos.user.v1alpha1.UserService service. By
|
||||
@@ -76,13 +82,20 @@ func NewUserServiceClient(httpClient connect.HTTPClient, baseURL string, opts ..
|
||||
connect.WithSchema(userServiceGetUserMethodDescriptor),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
registerUser: connect.NewClient[v1alpha1.RegisterUserRequest, v1alpha1.RegisterUserResponse](
|
||||
httpClient,
|
||||
baseURL+UserServiceRegisterUserProcedure,
|
||||
connect.WithSchema(userServiceRegisterUserMethodDescriptor),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// userServiceClient implements UserServiceClient.
|
||||
type userServiceClient struct {
|
||||
createUser *connect.Client[v1alpha1.CreateUserRequest, v1alpha1.CreateUserResponse]
|
||||
getUser *connect.Client[v1alpha1.GetUserRequest, v1alpha1.GetUserResponse]
|
||||
createUser *connect.Client[v1alpha1.CreateUserRequest, v1alpha1.CreateUserResponse]
|
||||
getUser *connect.Client[v1alpha1.GetUserRequest, v1alpha1.GetUserResponse]
|
||||
registerUser *connect.Client[v1alpha1.RegisterUserRequest, v1alpha1.RegisterUserResponse]
|
||||
}
|
||||
|
||||
// CreateUser calls holos.user.v1alpha1.UserService.CreateUser.
|
||||
@@ -95,12 +108,19 @@ func (c *userServiceClient) GetUser(ctx context.Context, req *connect.Request[v1
|
||||
return c.getUser.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// RegisterUser calls holos.user.v1alpha1.UserService.RegisterUser.
|
||||
func (c *userServiceClient) RegisterUser(ctx context.Context, req *connect.Request[v1alpha1.RegisterUserRequest]) (*connect.Response[v1alpha1.RegisterUserResponse], error) {
|
||||
return c.registerUser.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// UserServiceHandler is an implementation of the holos.user.v1alpha1.UserService service.
|
||||
type UserServiceHandler interface {
|
||||
// Create a new user from authenticated claims or the provided User resource.
|
||||
CreateUser(context.Context, *connect.Request[v1alpha1.CreateUserRequest]) (*connect.Response[v1alpha1.CreateUserResponse], error)
|
||||
// Get an existing user by id, email, or subject.
|
||||
GetUser(context.Context, *connect.Request[v1alpha1.GetUserRequest]) (*connect.Response[v1alpha1.GetUserResponse], error)
|
||||
// Register an user and initialize an organization, bare platform, and reference platform.
|
||||
RegisterUser(context.Context, *connect.Request[v1alpha1.RegisterUserRequest]) (*connect.Response[v1alpha1.RegisterUserResponse], error)
|
||||
}
|
||||
|
||||
// NewUserServiceHandler builds an HTTP handler from the service implementation. It returns the path
|
||||
@@ -121,12 +141,20 @@ func NewUserServiceHandler(svc UserServiceHandler, opts ...connect.HandlerOption
|
||||
connect.WithSchema(userServiceGetUserMethodDescriptor),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceRegisterUserHandler := connect.NewUnaryHandler(
|
||||
UserServiceRegisterUserProcedure,
|
||||
svc.RegisterUser,
|
||||
connect.WithSchema(userServiceRegisterUserMethodDescriptor),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
return "/holos.user.v1alpha1.UserService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case UserServiceCreateUserProcedure:
|
||||
userServiceCreateUserHandler.ServeHTTP(w, r)
|
||||
case UserServiceGetUserProcedure:
|
||||
userServiceGetUserHandler.ServeHTTP(w, r)
|
||||
case UserServiceRegisterUserProcedure:
|
||||
userServiceRegisterUserHandler.ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
@@ -143,3 +171,7 @@ func (UnimplementedUserServiceHandler) CreateUser(context.Context, *connect.Requ
|
||||
func (UnimplementedUserServiceHandler) GetUser(context.Context, *connect.Request[v1alpha1.GetUserRequest]) (*connect.Response[v1alpha1.GetUserResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("holos.user.v1alpha1.UserService.GetUser is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) RegisterUser(context.Context, *connect.Request[v1alpha1.RegisterUserRequest]) (*connect.Response[v1alpha1.RegisterUserResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("holos.user.v1alpha1.UserService.RegisterUser is not implemented"))
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ option go_package = "github.com/holos-run/holos/service/gen/holos/user/v1alpha1;
|
||||
|
||||
// git clone https://github.com/bufbuild/protovalidate then add <parent>/protovalidate/proto/protovalidate to your editor proto search path
|
||||
import "holos/user/v1alpha1/user.proto";
|
||||
import "holos/organization/v1alpha1/organization.proto";
|
||||
import "google/protobuf/field_mask.proto";
|
||||
import "holos/object/v1alpha1/object.proto";
|
||||
|
||||
@@ -33,10 +34,36 @@ message GetUserResponse {
|
||||
User user = 1;
|
||||
}
|
||||
|
||||
// Register a User from the oidc id token claims or the provided user. Each one
|
||||
// of subject, email, and user id must be globally unique.
|
||||
message RegisterUserRequest {
|
||||
// User resource to create. If absent, the server populates User fields with
|
||||
// the oidc id token claims of the authenticated request.
|
||||
// NOTE: The server may ignore this request field and register the user solely
|
||||
// from authenticated identity claims.
|
||||
optional User user = 1;
|
||||
// Mask of the user fields to include in the response.
|
||||
optional google.protobuf.FieldMask user_mask = 2;
|
||||
// Organization resource to create. If absent, the server generates an
|
||||
// organization based on the user fields.
|
||||
// NOTE: The server may ignore this request field and register the
|
||||
// organization solely from authenticated identity claims.
|
||||
optional holos.organization.v1alpha1.Organization organization = 3;
|
||||
// Mask of the organization fields to include in the response.
|
||||
optional google.protobuf.FieldMask organization_mask = 4;
|
||||
}
|
||||
|
||||
message RegisterUserResponse {
|
||||
User user = 1;
|
||||
holos.organization.v1alpha1.Organization organization = 2;
|
||||
}
|
||||
|
||||
// UserService provides CRUD methods for User resources in the system.
|
||||
service UserService {
|
||||
// Create a new user from authenticated claims or the provided User resource.
|
||||
rpc CreateUser(CreateUserRequest) returns (CreateUserResponse) {}
|
||||
// Get an existing user by id, email, or subject.
|
||||
rpc GetUser(GetUserRequest) returns (GetUserResponse) {}
|
||||
// Register an user and initialize an organization, bare platform, and reference platform.
|
||||
rpc RegisterUser(RegisterUserRequest) returns (RegisterUserResponse) {}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
76
|
||||
77
|
||||
|
||||
Reference in New Issue
Block a user