From 4f3c1dcc777a8593d20beb5152dd60576cc263d0 Mon Sep 17 00:00:00 2001 From: Alisha Date: Mon, 6 Nov 2023 17:51:02 -0800 Subject: [PATCH 1/5] create team account --- backend/gen/go/db/mock_Querier.go | 110 +++++++ backend/gen/go/db/querier.go | 2 + backend/gen/go/db/users.sql.go | 57 ++++ .../mock_UserAccountServiceClient.go | 55 ++++ .../user_account.connect.go | 27 ++ .../protos/mgmt/v1alpha1/user_account.pb.go | 308 +++++++++++++----- .../mgmt/v1alpha1/user_account.pb.validate.go | 208 ++++++++++++ backend/internal/nucleusdb/db.go | 2 - backend/internal/nucleusdb/users.go | 40 +++ .../protos/mgmt/v1alpha1/user_account.proto | 8 + .../mgmt/v1alpha1/job-service/jobs.go | 1 - .../v1alpha1/user-account-service/users.go | 23 ++ backend/sql/postgresql/users.sql | 14 + frontend/components/AccountSwitcher.tsx | 286 +++++++++++----- frontend/components/SiteHeader.tsx | 4 +- .../mgmt/v1alpha1/user_account_connect.ts | 11 +- .../mgmt/v1alpha1/user_account_pb.ts | 74 +++++ 17 files changed, 1050 insertions(+), 180 deletions(-) diff --git a/backend/gen/go/db/mock_Querier.go b/backend/gen/go/db/mock_Querier.go index c025d91fac..d9df262f68 100644 --- a/backend/gen/go/db/mock_Querier.go +++ b/backend/gen/go/db/mock_Querier.go @@ -456,6 +456,60 @@ func (_c *MockQuerier_CreatePersonalAccount_Call) RunAndReturn(run func(context. return _c } +// CreateTeamAccount provides a mock function with given fields: ctx, db, accountSlug +func (_m *MockQuerier) CreateTeamAccount(ctx context.Context, db DBTX, accountSlug string) (NeosyncApiAccount, error) { + ret := _m.Called(ctx, db, accountSlug) + + var r0 NeosyncApiAccount + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, DBTX, string) (NeosyncApiAccount, error)); ok { + return rf(ctx, db, accountSlug) + } + if rf, ok := ret.Get(0).(func(context.Context, DBTX, string) NeosyncApiAccount); ok { + r0 = rf(ctx, db, accountSlug) + } else { + r0 = ret.Get(0).(NeosyncApiAccount) + } + + if rf, ok := ret.Get(1).(func(context.Context, DBTX, string) error); ok { + r1 = rf(ctx, db, accountSlug) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockQuerier_CreateTeamAccount_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateTeamAccount' +type MockQuerier_CreateTeamAccount_Call struct { + *mock.Call +} + +// CreateTeamAccount is a helper method to define mock.On call +// - ctx context.Context +// - db DBTX +// - accountSlug string +func (_e *MockQuerier_Expecter) CreateTeamAccount(ctx interface{}, db interface{}, accountSlug interface{}) *MockQuerier_CreateTeamAccount_Call { + return &MockQuerier_CreateTeamAccount_Call{Call: _e.mock.On("CreateTeamAccount", ctx, db, accountSlug)} +} + +func (_c *MockQuerier_CreateTeamAccount_Call) Run(run func(ctx context.Context, db DBTX, accountSlug string)) *MockQuerier_CreateTeamAccount_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(DBTX), args[2].(string)) + }) + return _c +} + +func (_c *MockQuerier_CreateTeamAccount_Call) Return(_a0 NeosyncApiAccount, _a1 error) *MockQuerier_CreateTeamAccount_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockQuerier_CreateTeamAccount_Call) RunAndReturn(run func(context.Context, DBTX, string) (NeosyncApiAccount, error)) *MockQuerier_CreateTeamAccount_Call { + _c.Call.Return(run) + return _c +} + // CreateUser provides a mock function with given fields: ctx, db func (_m *MockQuerier) CreateUser(ctx context.Context, db DBTX) (NeosyncApiUser, error) { ret := _m.Called(ctx, db) @@ -1472,6 +1526,62 @@ func (_c *MockQuerier_GetPersonalAccountByUserId_Call) RunAndReturn(run func(con return _c } +// GetTeamAccountsByUserId provides a mock function with given fields: ctx, db, userid +func (_m *MockQuerier) GetTeamAccountsByUserId(ctx context.Context, db DBTX, userid pgtype.UUID) ([]NeosyncApiAccount, error) { + ret := _m.Called(ctx, db, userid) + + var r0 []NeosyncApiAccount + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, DBTX, pgtype.UUID) ([]NeosyncApiAccount, error)); ok { + return rf(ctx, db, userid) + } + if rf, ok := ret.Get(0).(func(context.Context, DBTX, pgtype.UUID) []NeosyncApiAccount); ok { + r0 = rf(ctx, db, userid) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]NeosyncApiAccount) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, DBTX, pgtype.UUID) error); ok { + r1 = rf(ctx, db, userid) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockQuerier_GetTeamAccountsByUserId_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTeamAccountsByUserId' +type MockQuerier_GetTeamAccountsByUserId_Call struct { + *mock.Call +} + +// GetTeamAccountsByUserId is a helper method to define mock.On call +// - ctx context.Context +// - db DBTX +// - userid pgtype.UUID +func (_e *MockQuerier_Expecter) GetTeamAccountsByUserId(ctx interface{}, db interface{}, userid interface{}) *MockQuerier_GetTeamAccountsByUserId_Call { + return &MockQuerier_GetTeamAccountsByUserId_Call{Call: _e.mock.On("GetTeamAccountsByUserId", ctx, db, userid)} +} + +func (_c *MockQuerier_GetTeamAccountsByUserId_Call) Run(run func(ctx context.Context, db DBTX, userid pgtype.UUID)) *MockQuerier_GetTeamAccountsByUserId_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(DBTX), args[2].(pgtype.UUID)) + }) + return _c +} + +func (_c *MockQuerier_GetTeamAccountsByUserId_Call) Return(_a0 []NeosyncApiAccount, _a1 error) *MockQuerier_GetTeamAccountsByUserId_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockQuerier_GetTeamAccountsByUserId_Call) RunAndReturn(run func(context.Context, DBTX, pgtype.UUID) ([]NeosyncApiAccount, error)) *MockQuerier_GetTeamAccountsByUserId_Call { + _c.Call.Return(run) + return _c +} + // GetTemporalConfigByAccount provides a mock function with given fields: ctx, db, id func (_m *MockQuerier) GetTemporalConfigByAccount(ctx context.Context, db DBTX, id pgtype.UUID) (*jsonmodels.TemporalConfig, error) { ret := _m.Called(ctx, db, id) diff --git a/backend/gen/go/db/querier.go b/backend/gen/go/db/querier.go index cccc3de362..2a78e7f6a7 100644 --- a/backend/gen/go/db/querier.go +++ b/backend/gen/go/db/querier.go @@ -20,6 +20,7 @@ type Querier interface { CreateJobConnectionDestination(ctx context.Context, db DBTX, arg CreateJobConnectionDestinationParams) (NeosyncApiJobDestinationConnectionAssociation, error) CreateJobConnectionDestinations(ctx context.Context, db DBTX, arg []CreateJobConnectionDestinationsParams) (int64, error) CreatePersonalAccount(ctx context.Context, db DBTX, accountSlug string) (NeosyncApiAccount, error) + CreateTeamAccount(ctx context.Context, db DBTX, accountSlug string) (NeosyncApiAccount, error) CreateUser(ctx context.Context, db DBTX) (NeosyncApiUser, error) DeleteCustomTransformerById(ctx context.Context, db DBTX, id pgtype.UUID) error DeleteJob(ctx context.Context, db DBTX, id pgtype.UUID) error @@ -39,6 +40,7 @@ type Querier interface { GetJobConnectionDestinationsByJobIds(ctx context.Context, db DBTX, jobids []pgtype.UUID) ([]NeosyncApiJobDestinationConnectionAssociation, error) GetJobsByAccount(ctx context.Context, db DBTX, accountid pgtype.UUID) ([]NeosyncApiJob, error) GetPersonalAccountByUserId(ctx context.Context, db DBTX, userid pgtype.UUID) (NeosyncApiAccount, error) + GetTeamAccountsByUserId(ctx context.Context, db DBTX, userid pgtype.UUID) ([]NeosyncApiAccount, error) GetTemporalConfigByAccount(ctx context.Context, db DBTX, id pgtype.UUID) (*jsonmodels.TemporalConfig, error) GetTemporalConfigByUserAccount(ctx context.Context, db DBTX, arg GetTemporalConfigByUserAccountParams) (*jsonmodels.TemporalConfig, error) GetUser(ctx context.Context, db DBTX, id pgtype.UUID) (NeosyncApiUser, error) diff --git a/backend/gen/go/db/users.sql.go b/backend/gen/go/db/users.sql.go index 3719d5d2bc..a9af5bae28 100644 --- a/backend/gen/go/db/users.sql.go +++ b/backend/gen/go/db/users.sql.go @@ -89,6 +89,29 @@ func (q *Queries) CreatePersonalAccount(ctx context.Context, db DBTX, accountSlu return i, err } +const createTeamAccount = `-- name: CreateTeamAccount :one +INSERT INTO neosync_api.accounts ( + account_type, account_slug +) VALUES ( + 1, $1 +) +RETURNING id, created_at, updated_at, account_type, account_slug, temporal_config +` + +func (q *Queries) CreateTeamAccount(ctx context.Context, db DBTX, accountSlug string) (NeosyncApiAccount, error) { + row := db.QueryRow(ctx, createTeamAccount, accountSlug) + var i NeosyncApiAccount + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.AccountType, + &i.AccountSlug, + &i.TemporalConfig, + ) + return i, err +} + const createUser = `-- name: CreateUser :one INSERT INTO neosync_api.users ( id, created_at, updated_at @@ -216,6 +239,40 @@ func (q *Queries) GetPersonalAccountByUserId(ctx context.Context, db DBTX, useri return i, err } +const getTeamAccountsByUserId = `-- name: GetTeamAccountsByUserId :many +SELECT a.id, a.created_at, a.updated_at, a.account_type, a.account_slug, a.temporal_config from neosync_api.accounts a +INNER JOIN neosync_api.account_user_associations aua ON aua.account_id = a.id +INNER JOIN neosync_api.users u ON u.id = aua.user_id +WHERE u.id = $1 AND a.account_type = 1 +` + +func (q *Queries) GetTeamAccountsByUserId(ctx context.Context, db DBTX, userid pgtype.UUID) ([]NeosyncApiAccount, error) { + rows, err := db.Query(ctx, getTeamAccountsByUserId, userid) + if err != nil { + return nil, err + } + defer rows.Close() + var items []NeosyncApiAccount + for rows.Next() { + var i NeosyncApiAccount + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.AccountType, + &i.AccountSlug, + &i.TemporalConfig, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + const getTemporalConfigByAccount = `-- name: GetTemporalConfigByAccount :one SELECT temporal_config FROM neosync_api.accounts diff --git a/backend/gen/go/protos/mgmt/v1alpha1/mgmtv1alpha1connect/mock_UserAccountServiceClient.go b/backend/gen/go/protos/mgmt/v1alpha1/mgmtv1alpha1connect/mock_UserAccountServiceClient.go index ced24de172..0f8689042f 100644 --- a/backend/gen/go/protos/mgmt/v1alpha1/mgmtv1alpha1connect/mock_UserAccountServiceClient.go +++ b/backend/gen/go/protos/mgmt/v1alpha1/mgmtv1alpha1connect/mock_UserAccountServiceClient.go @@ -79,6 +79,61 @@ func (_c *MockUserAccountServiceClient_ConvertPersonalToTeamAccount_Call) RunAnd return _c } +// CreateTeamAccount provides a mock function with given fields: _a0, _a1 +func (_m *MockUserAccountServiceClient) CreateTeamAccount(_a0 context.Context, _a1 *connect.Request[mgmtv1alpha1.CreateTeamAccountRequest]) (*connect.Response[mgmtv1alpha1.CreateTeamAccountResponse], error) { + ret := _m.Called(_a0, _a1) + + var r0 *connect.Response[mgmtv1alpha1.CreateTeamAccountResponse] + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *connect.Request[mgmtv1alpha1.CreateTeamAccountRequest]) (*connect.Response[mgmtv1alpha1.CreateTeamAccountResponse], error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *connect.Request[mgmtv1alpha1.CreateTeamAccountRequest]) *connect.Response[mgmtv1alpha1.CreateTeamAccountResponse]); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*connect.Response[mgmtv1alpha1.CreateTeamAccountResponse]) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *connect.Request[mgmtv1alpha1.CreateTeamAccountRequest]) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockUserAccountServiceClient_CreateTeamAccount_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateTeamAccount' +type MockUserAccountServiceClient_CreateTeamAccount_Call struct { + *mock.Call +} + +// CreateTeamAccount is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 *connect.Request[mgmtv1alpha1.CreateTeamAccountRequest] +func (_e *MockUserAccountServiceClient_Expecter) CreateTeamAccount(_a0 interface{}, _a1 interface{}) *MockUserAccountServiceClient_CreateTeamAccount_Call { + return &MockUserAccountServiceClient_CreateTeamAccount_Call{Call: _e.mock.On("CreateTeamAccount", _a0, _a1)} +} + +func (_c *MockUserAccountServiceClient_CreateTeamAccount_Call) Run(run func(_a0 context.Context, _a1 *connect.Request[mgmtv1alpha1.CreateTeamAccountRequest])) *MockUserAccountServiceClient_CreateTeamAccount_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*connect.Request[mgmtv1alpha1.CreateTeamAccountRequest])) + }) + return _c +} + +func (_c *MockUserAccountServiceClient_CreateTeamAccount_Call) Return(_a0 *connect.Response[mgmtv1alpha1.CreateTeamAccountResponse], _a1 error) *MockUserAccountServiceClient_CreateTeamAccount_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockUserAccountServiceClient_CreateTeamAccount_Call) RunAndReturn(run func(context.Context, *connect.Request[mgmtv1alpha1.CreateTeamAccountRequest]) (*connect.Response[mgmtv1alpha1.CreateTeamAccountResponse], error)) *MockUserAccountServiceClient_CreateTeamAccount_Call { + _c.Call.Return(run) + return _c +} + // GetAccountTemporalConfig provides a mock function with given fields: _a0, _a1 func (_m *MockUserAccountServiceClient) GetAccountTemporalConfig(_a0 context.Context, _a1 *connect.Request[mgmtv1alpha1.GetAccountTemporalConfigRequest]) (*connect.Response[mgmtv1alpha1.GetAccountTemporalConfigResponse], error) { ret := _m.Called(_a0, _a1) diff --git a/backend/gen/go/protos/mgmt/v1alpha1/mgmtv1alpha1connect/user_account.connect.go b/backend/gen/go/protos/mgmt/v1alpha1/mgmtv1alpha1connect/user_account.connect.go index 2fadb8d960..41f73bc13a 100644 --- a/backend/gen/go/protos/mgmt/v1alpha1/mgmtv1alpha1connect/user_account.connect.go +++ b/backend/gen/go/protos/mgmt/v1alpha1/mgmtv1alpha1connect/user_account.connect.go @@ -48,6 +48,9 @@ const ( // UserAccountServiceConvertPersonalToTeamAccountProcedure is the fully-qualified name of the // UserAccountService's ConvertPersonalToTeamAccount RPC. UserAccountServiceConvertPersonalToTeamAccountProcedure = "/mgmt.v1alpha1.UserAccountService/ConvertPersonalToTeamAccount" + // UserAccountServiceCreateTeamAccountProcedure is the fully-qualified name of the + // UserAccountService's CreateTeamAccount RPC. + UserAccountServiceCreateTeamAccountProcedure = "/mgmt.v1alpha1.UserAccountService/CreateTeamAccount" // UserAccountServiceIsUserInAccountProcedure is the fully-qualified name of the // UserAccountService's IsUserInAccount RPC. UserAccountServiceIsUserInAccountProcedure = "/mgmt.v1alpha1.UserAccountService/IsUserInAccount" @@ -66,6 +69,7 @@ type UserAccountServiceClient interface { GetUserAccounts(context.Context, *connect.Request[v1alpha1.GetUserAccountsRequest]) (*connect.Response[v1alpha1.GetUserAccountsResponse], error) SetPersonalAccount(context.Context, *connect.Request[v1alpha1.SetPersonalAccountRequest]) (*connect.Response[v1alpha1.SetPersonalAccountResponse], error) ConvertPersonalToTeamAccount(context.Context, *connect.Request[v1alpha1.ConvertPersonalToTeamAccountRequest]) (*connect.Response[v1alpha1.ConvertPersonalToTeamAccountResponse], error) + CreateTeamAccount(context.Context, *connect.Request[v1alpha1.CreateTeamAccountRequest]) (*connect.Response[v1alpha1.CreateTeamAccountResponse], error) IsUserInAccount(context.Context, *connect.Request[v1alpha1.IsUserInAccountRequest]) (*connect.Response[v1alpha1.IsUserInAccountResponse], error) GetAccountTemporalConfig(context.Context, *connect.Request[v1alpha1.GetAccountTemporalConfigRequest]) (*connect.Response[v1alpha1.GetAccountTemporalConfigResponse], error) SetAccountTemporalConfig(context.Context, *connect.Request[v1alpha1.SetAccountTemporalConfigRequest]) (*connect.Response[v1alpha1.SetAccountTemporalConfigResponse], error) @@ -106,6 +110,11 @@ func NewUserAccountServiceClient(httpClient connect.HTTPClient, baseURL string, baseURL+UserAccountServiceConvertPersonalToTeamAccountProcedure, opts..., ), + createTeamAccount: connect.NewClient[v1alpha1.CreateTeamAccountRequest, v1alpha1.CreateTeamAccountResponse]( + httpClient, + baseURL+UserAccountServiceCreateTeamAccountProcedure, + opts..., + ), isUserInAccount: connect.NewClient[v1alpha1.IsUserInAccountRequest, v1alpha1.IsUserInAccountResponse]( httpClient, baseURL+UserAccountServiceIsUserInAccountProcedure, @@ -131,6 +140,7 @@ type userAccountServiceClient struct { getUserAccounts *connect.Client[v1alpha1.GetUserAccountsRequest, v1alpha1.GetUserAccountsResponse] setPersonalAccount *connect.Client[v1alpha1.SetPersonalAccountRequest, v1alpha1.SetPersonalAccountResponse] convertPersonalToTeamAccount *connect.Client[v1alpha1.ConvertPersonalToTeamAccountRequest, v1alpha1.ConvertPersonalToTeamAccountResponse] + createTeamAccount *connect.Client[v1alpha1.CreateTeamAccountRequest, v1alpha1.CreateTeamAccountResponse] isUserInAccount *connect.Client[v1alpha1.IsUserInAccountRequest, v1alpha1.IsUserInAccountResponse] getAccountTemporalConfig *connect.Client[v1alpha1.GetAccountTemporalConfigRequest, v1alpha1.GetAccountTemporalConfigResponse] setAccountTemporalConfig *connect.Client[v1alpha1.SetAccountTemporalConfigRequest, v1alpha1.SetAccountTemporalConfigResponse] @@ -161,6 +171,11 @@ func (c *userAccountServiceClient) ConvertPersonalToTeamAccount(ctx context.Cont return c.convertPersonalToTeamAccount.CallUnary(ctx, req) } +// CreateTeamAccount calls mgmt.v1alpha1.UserAccountService.CreateTeamAccount. +func (c *userAccountServiceClient) CreateTeamAccount(ctx context.Context, req *connect.Request[v1alpha1.CreateTeamAccountRequest]) (*connect.Response[v1alpha1.CreateTeamAccountResponse], error) { + return c.createTeamAccount.CallUnary(ctx, req) +} + // IsUserInAccount calls mgmt.v1alpha1.UserAccountService.IsUserInAccount. func (c *userAccountServiceClient) IsUserInAccount(ctx context.Context, req *connect.Request[v1alpha1.IsUserInAccountRequest]) (*connect.Response[v1alpha1.IsUserInAccountResponse], error) { return c.isUserInAccount.CallUnary(ctx, req) @@ -183,6 +198,7 @@ type UserAccountServiceHandler interface { GetUserAccounts(context.Context, *connect.Request[v1alpha1.GetUserAccountsRequest]) (*connect.Response[v1alpha1.GetUserAccountsResponse], error) SetPersonalAccount(context.Context, *connect.Request[v1alpha1.SetPersonalAccountRequest]) (*connect.Response[v1alpha1.SetPersonalAccountResponse], error) ConvertPersonalToTeamAccount(context.Context, *connect.Request[v1alpha1.ConvertPersonalToTeamAccountRequest]) (*connect.Response[v1alpha1.ConvertPersonalToTeamAccountResponse], error) + CreateTeamAccount(context.Context, *connect.Request[v1alpha1.CreateTeamAccountRequest]) (*connect.Response[v1alpha1.CreateTeamAccountResponse], error) IsUserInAccount(context.Context, *connect.Request[v1alpha1.IsUserInAccountRequest]) (*connect.Response[v1alpha1.IsUserInAccountResponse], error) GetAccountTemporalConfig(context.Context, *connect.Request[v1alpha1.GetAccountTemporalConfigRequest]) (*connect.Response[v1alpha1.GetAccountTemporalConfigResponse], error) SetAccountTemporalConfig(context.Context, *connect.Request[v1alpha1.SetAccountTemporalConfigRequest]) (*connect.Response[v1alpha1.SetAccountTemporalConfigResponse], error) @@ -219,6 +235,11 @@ func NewUserAccountServiceHandler(svc UserAccountServiceHandler, opts ...connect svc.ConvertPersonalToTeamAccount, opts..., ) + userAccountServiceCreateTeamAccountHandler := connect.NewUnaryHandler( + UserAccountServiceCreateTeamAccountProcedure, + svc.CreateTeamAccount, + opts..., + ) userAccountServiceIsUserInAccountHandler := connect.NewUnaryHandler( UserAccountServiceIsUserInAccountProcedure, svc.IsUserInAccount, @@ -246,6 +267,8 @@ func NewUserAccountServiceHandler(svc UserAccountServiceHandler, opts ...connect userAccountServiceSetPersonalAccountHandler.ServeHTTP(w, r) case UserAccountServiceConvertPersonalToTeamAccountProcedure: userAccountServiceConvertPersonalToTeamAccountHandler.ServeHTTP(w, r) + case UserAccountServiceCreateTeamAccountProcedure: + userAccountServiceCreateTeamAccountHandler.ServeHTTP(w, r) case UserAccountServiceIsUserInAccountProcedure: userAccountServiceIsUserInAccountHandler.ServeHTTP(w, r) case UserAccountServiceGetAccountTemporalConfigProcedure: @@ -281,6 +304,10 @@ func (UnimplementedUserAccountServiceHandler) ConvertPersonalToTeamAccount(conte return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mgmt.v1alpha1.UserAccountService.ConvertPersonalToTeamAccount is not implemented")) } +func (UnimplementedUserAccountServiceHandler) CreateTeamAccount(context.Context, *connect.Request[v1alpha1.CreateTeamAccountRequest]) (*connect.Response[v1alpha1.CreateTeamAccountResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mgmt.v1alpha1.UserAccountService.CreateTeamAccount is not implemented")) +} + func (UnimplementedUserAccountServiceHandler) IsUserInAccount(context.Context, *connect.Request[v1alpha1.IsUserInAccountRequest]) (*connect.Response[v1alpha1.IsUserInAccountResponse], error) { return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mgmt.v1alpha1.UserAccountService.IsUserInAccount is not implemented")) } diff --git a/backend/gen/go/protos/mgmt/v1alpha1/user_account.pb.go b/backend/gen/go/protos/mgmt/v1alpha1/user_account.pb.go index f5fdada13d..6fa735e196 100644 --- a/backend/gen/go/protos/mgmt/v1alpha1/user_account.pb.go +++ b/backend/gen/go/protos/mgmt/v1alpha1/user_account.pb.go @@ -902,6 +902,100 @@ func (x *AccountTemporalConfig) GetSyncJobQueueName() string { return "" } +type CreateTeamAccountRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *CreateTeamAccountRequest) Reset() { + *x = CreateTeamAccountRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_mgmt_v1alpha1_user_account_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateTeamAccountRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateTeamAccountRequest) ProtoMessage() {} + +func (x *CreateTeamAccountRequest) ProtoReflect() protoreflect.Message { + mi := &file_mgmt_v1alpha1_user_account_proto_msgTypes[18] + 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 CreateTeamAccountRequest.ProtoReflect.Descriptor instead. +func (*CreateTeamAccountRequest) Descriptor() ([]byte, []int) { + return file_mgmt_v1alpha1_user_account_proto_rawDescGZIP(), []int{18} +} + +func (x *CreateTeamAccountRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type CreateTeamAccountResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AccountId string `protobuf:"bytes,1,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"` +} + +func (x *CreateTeamAccountResponse) Reset() { + *x = CreateTeamAccountResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_mgmt_v1alpha1_user_account_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateTeamAccountResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateTeamAccountResponse) ProtoMessage() {} + +func (x *CreateTeamAccountResponse) ProtoReflect() protoreflect.Message { + mi := &file_mgmt_v1alpha1_user_account_proto_msgTypes[19] + 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 CreateTeamAccountResponse.ProtoReflect.Descriptor instead. +func (*CreateTeamAccountResponse) Descriptor() ([]byte, []int) { + return file_mgmt_v1alpha1_user_account_proto_rawDescGZIP(), []int{19} +} + +func (x *CreateTeamAccountResponse) GetAccountId() string { + if x != nil { + return x.AccountId + } + return "" +} + var File_mgmt_v1alpha1_user_account_proto protoreflect.FileDescriptor var file_mgmt_v1alpha1_user_account_proto_rawDesc = []byte{ @@ -983,82 +1077,96 @@ var file_mgmt_v1alpha1_user_account_proto_rawDesc = []byte{ 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x6a, 0x6f, 0x62, 0x5f, 0x71, 0x75, 0x65, 0x75, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x10, 0x73, 0x79, 0x6e, 0x63, 0x4a, 0x6f, 0x62, 0x51, 0x75, 0x65, 0x75, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x2a, 0x70, 0x0a, 0x0f, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x1d, 0x55, 0x53, 0x45, 0x52, 0x5f, - 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, - 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x55, 0x53, - 0x45, 0x52, 0x5f, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x50, 0x45, 0x52, 0x53, 0x4f, 0x4e, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x55, 0x53, - 0x45, 0x52, 0x5f, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x54, 0x45, 0x41, 0x4d, 0x10, 0x02, 0x32, 0xeb, 0x06, 0x0a, 0x12, 0x55, 0x73, 0x65, 0x72, 0x41, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4a, 0x0a, - 0x07, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1d, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 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, 0x1e, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 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, 0x4a, 0x0a, 0x07, 0x53, 0x65, 0x74, - 0x55, 0x73, 0x65, 0x72, 0x12, 0x1d, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x62, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x25, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x26, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, - 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6b, 0x0a, 0x12, 0x53, 0x65, 0x74, - 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, - 0x28, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, - 0x53, 0x65, 0x74, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x6d, 0x67, 0x6d, 0x74, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x50, 0x65, 0x72, - 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x89, 0x01, 0x0a, 0x1c, 0x43, 0x6f, 0x6e, 0x76, 0x65, - 0x72, 0x74, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x54, 0x6f, 0x54, 0x65, 0x61, 0x6d, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x32, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x50, - 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x54, 0x6f, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x6d, 0x67, - 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x76, - 0x65, 0x72, 0x74, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x54, 0x6f, 0x54, 0x65, 0x61, - 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x62, 0x0a, 0x0f, 0x49, 0x73, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x41, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x25, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x49, 0x73, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x41, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x6d, - 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x49, 0x73, 0x55, - 0x73, 0x65, 0x72, 0x49, 0x6e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7d, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x12, 0x2e, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x6d, - 0x70, 0x6f, 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x6d, - 0x70, 0x6f, 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7d, 0x0a, 0x18, 0x53, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, + 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x37, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, + 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, + 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3a, 0x0a, + 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x2a, 0x70, 0x0a, 0x0f, 0x55, 0x73, 0x65, + 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x1d, + 0x55, 0x53, 0x45, 0x52, 0x5f, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x1e, 0x0a, 0x1a, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x45, 0x52, 0x53, 0x4f, 0x4e, 0x41, 0x4c, 0x10, 0x01, 0x12, + 0x1a, 0x0a, 0x16, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x54, 0x45, 0x41, 0x4d, 0x10, 0x02, 0x32, 0xd5, 0x07, 0x0a, 0x12, + 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x4a, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1d, 0x2e, + 0x6d, 0x67, 0x6d, 0x74, 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, 0x1e, 0x2e, 0x6d, + 0x67, 0x6d, 0x74, 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, 0x4a, + 0x0a, 0x07, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1d, 0x2e, 0x6d, 0x67, 0x6d, 0x74, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x62, 0x0a, 0x0f, 0x47, 0x65, + 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x25, 0x2e, + 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, + 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6b, + 0x0a, 0x12, 0x53, 0x65, 0x74, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x28, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, + 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, + 0x65, 0x74, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x89, 0x01, 0x0a, 0x1c, + 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x54, + 0x6f, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x32, 0x2e, 0x6d, + 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x74, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x54, 0x6f, 0x54, 0x65, + 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x33, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, + 0x54, 0x6f, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x68, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x27, 0x2e, 0x6d, + 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x61, 0x6d, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x62, 0x0a, 0x0f, 0x49, 0x73, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x41, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x25, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x49, 0x73, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x41, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x6d, 0x67, + 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x49, 0x73, 0x55, 0x73, + 0x65, 0x72, 0x49, 0x6e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7d, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2e, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x6d, 0x70, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x6d, 0x70, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x42, 0xcc, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x67, 0x6d, - 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x10, 0x55, 0x73, 0x65, 0x72, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x50, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6e, 0x75, 0x63, 0x6c, 0x65, - 0x75, 0x73, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6e, 0x65, 0x6f, 0x73, 0x79, 0x6e, 0x63, 0x2f, - 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x6d, 0x67, 0x6d, 0x74, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x31, 0x3b, 0x6d, 0x67, 0x6d, 0x74, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0xa2, 0x02, 0x03, 0x4d, 0x58, 0x58, 0xaa, 0x02, 0x0d, 0x4d, 0x67, 0x6d, 0x74, 0x2e, 0x56, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x0d, 0x4d, 0x67, 0x6d, 0x74, 0x5c, 0x56, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x19, 0x4d, 0x67, 0x6d, 0x74, 0x5c, 0x56, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x67, 0x6d, 0x74, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x7d, 0x0a, 0x18, 0x53, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x2e, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x53, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6f, + 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2f, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x53, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6f, + 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x42, 0xcc, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x67, 0x6d, 0x74, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x10, 0x55, 0x73, 0x65, 0x72, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x50, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6e, 0x75, 0x63, 0x6c, 0x65, 0x75, + 0x73, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6e, 0x65, 0x6f, 0x73, 0x79, 0x6e, 0x63, 0x2f, 0x62, + 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x6d, 0x67, 0x6d, 0x74, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x3b, 0x6d, 0x67, 0x6d, 0x74, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, + 0x02, 0x03, 0x4d, 0x58, 0x58, 0xaa, 0x02, 0x0d, 0x4d, 0x67, 0x6d, 0x74, 0x2e, 0x56, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x0d, 0x4d, 0x67, 0x6d, 0x74, 0x5c, 0x56, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x19, 0x4d, 0x67, 0x6d, 0x74, 0x5c, 0x56, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x67, 0x6d, 0x74, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1074,7 +1182,7 @@ func file_mgmt_v1alpha1_user_account_proto_rawDescGZIP() []byte { } var file_mgmt_v1alpha1_user_account_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_mgmt_v1alpha1_user_account_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_mgmt_v1alpha1_user_account_proto_msgTypes = make([]protoimpl.MessageInfo, 20) var file_mgmt_v1alpha1_user_account_proto_goTypes = []interface{}{ (UserAccountType)(0), // 0: mgmt.v1alpha1.UserAccountType (*GetUserRequest)(nil), // 1: mgmt.v1alpha1.GetUserRequest @@ -1095,6 +1203,8 @@ var file_mgmt_v1alpha1_user_account_proto_goTypes = []interface{}{ (*SetAccountTemporalConfigRequest)(nil), // 16: mgmt.v1alpha1.SetAccountTemporalConfigRequest (*SetAccountTemporalConfigResponse)(nil), // 17: mgmt.v1alpha1.SetAccountTemporalConfigResponse (*AccountTemporalConfig)(nil), // 18: mgmt.v1alpha1.AccountTemporalConfig + (*CreateTeamAccountRequest)(nil), // 19: mgmt.v1alpha1.CreateTeamAccountRequest + (*CreateTeamAccountResponse)(nil), // 20: mgmt.v1alpha1.CreateTeamAccountResponse } var file_mgmt_v1alpha1_user_account_proto_depIdxs = []int32{ 7, // 0: mgmt.v1alpha1.GetUserAccountsResponse.accounts:type_name -> mgmt.v1alpha1.UserAccount @@ -1107,19 +1217,21 @@ var file_mgmt_v1alpha1_user_account_proto_depIdxs = []int32{ 5, // 7: mgmt.v1alpha1.UserAccountService.GetUserAccounts:input_type -> mgmt.v1alpha1.GetUserAccountsRequest 10, // 8: mgmt.v1alpha1.UserAccountService.SetPersonalAccount:input_type -> mgmt.v1alpha1.SetPersonalAccountRequest 8, // 9: mgmt.v1alpha1.UserAccountService.ConvertPersonalToTeamAccount:input_type -> mgmt.v1alpha1.ConvertPersonalToTeamAccountRequest - 12, // 10: mgmt.v1alpha1.UserAccountService.IsUserInAccount:input_type -> mgmt.v1alpha1.IsUserInAccountRequest - 14, // 11: mgmt.v1alpha1.UserAccountService.GetAccountTemporalConfig:input_type -> mgmt.v1alpha1.GetAccountTemporalConfigRequest - 16, // 12: mgmt.v1alpha1.UserAccountService.SetAccountTemporalConfig:input_type -> mgmt.v1alpha1.SetAccountTemporalConfigRequest - 2, // 13: mgmt.v1alpha1.UserAccountService.GetUser:output_type -> mgmt.v1alpha1.GetUserResponse - 4, // 14: mgmt.v1alpha1.UserAccountService.SetUser:output_type -> mgmt.v1alpha1.SetUserResponse - 6, // 15: mgmt.v1alpha1.UserAccountService.GetUserAccounts:output_type -> mgmt.v1alpha1.GetUserAccountsResponse - 11, // 16: mgmt.v1alpha1.UserAccountService.SetPersonalAccount:output_type -> mgmt.v1alpha1.SetPersonalAccountResponse - 9, // 17: mgmt.v1alpha1.UserAccountService.ConvertPersonalToTeamAccount:output_type -> mgmt.v1alpha1.ConvertPersonalToTeamAccountResponse - 13, // 18: mgmt.v1alpha1.UserAccountService.IsUserInAccount:output_type -> mgmt.v1alpha1.IsUserInAccountResponse - 15, // 19: mgmt.v1alpha1.UserAccountService.GetAccountTemporalConfig:output_type -> mgmt.v1alpha1.GetAccountTemporalConfigResponse - 17, // 20: mgmt.v1alpha1.UserAccountService.SetAccountTemporalConfig:output_type -> mgmt.v1alpha1.SetAccountTemporalConfigResponse - 13, // [13:21] is the sub-list for method output_type - 5, // [5:13] is the sub-list for method input_type + 19, // 10: mgmt.v1alpha1.UserAccountService.CreateTeamAccount:input_type -> mgmt.v1alpha1.CreateTeamAccountRequest + 12, // 11: mgmt.v1alpha1.UserAccountService.IsUserInAccount:input_type -> mgmt.v1alpha1.IsUserInAccountRequest + 14, // 12: mgmt.v1alpha1.UserAccountService.GetAccountTemporalConfig:input_type -> mgmt.v1alpha1.GetAccountTemporalConfigRequest + 16, // 13: mgmt.v1alpha1.UserAccountService.SetAccountTemporalConfig:input_type -> mgmt.v1alpha1.SetAccountTemporalConfigRequest + 2, // 14: mgmt.v1alpha1.UserAccountService.GetUser:output_type -> mgmt.v1alpha1.GetUserResponse + 4, // 15: mgmt.v1alpha1.UserAccountService.SetUser:output_type -> mgmt.v1alpha1.SetUserResponse + 6, // 16: mgmt.v1alpha1.UserAccountService.GetUserAccounts:output_type -> mgmt.v1alpha1.GetUserAccountsResponse + 11, // 17: mgmt.v1alpha1.UserAccountService.SetPersonalAccount:output_type -> mgmt.v1alpha1.SetPersonalAccountResponse + 9, // 18: mgmt.v1alpha1.UserAccountService.ConvertPersonalToTeamAccount:output_type -> mgmt.v1alpha1.ConvertPersonalToTeamAccountResponse + 20, // 19: mgmt.v1alpha1.UserAccountService.CreateTeamAccount:output_type -> mgmt.v1alpha1.CreateTeamAccountResponse + 13, // 20: mgmt.v1alpha1.UserAccountService.IsUserInAccount:output_type -> mgmt.v1alpha1.IsUserInAccountResponse + 15, // 21: mgmt.v1alpha1.UserAccountService.GetAccountTemporalConfig:output_type -> mgmt.v1alpha1.GetAccountTemporalConfigResponse + 17, // 22: mgmt.v1alpha1.UserAccountService.SetAccountTemporalConfig:output_type -> mgmt.v1alpha1.SetAccountTemporalConfigResponse + 14, // [14:23] is the sub-list for method output_type + 5, // [5:14] 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 @@ -1347,6 +1459,30 @@ func file_mgmt_v1alpha1_user_account_proto_init() { return nil } } + file_mgmt_v1alpha1_user_account_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateTeamAccountRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mgmt_v1alpha1_user_account_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateTeamAccountResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -1354,7 +1490,7 @@ func file_mgmt_v1alpha1_user_account_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_mgmt_v1alpha1_user_account_proto_rawDesc, NumEnums: 1, - NumMessages: 18, + NumMessages: 20, NumExtensions: 0, NumServices: 1, }, diff --git a/backend/gen/go/protos/mgmt/v1alpha1/user_account.pb.validate.go b/backend/gen/go/protos/mgmt/v1alpha1/user_account.pb.validate.go index 8d04f9d217..42d0978fc8 100644 --- a/backend/gen/go/protos/mgmt/v1alpha1/user_account.pb.validate.go +++ b/backend/gen/go/protos/mgmt/v1alpha1/user_account.pb.validate.go @@ -2020,3 +2020,211 @@ var _ interface { Cause() error ErrorName() string } = AccountTemporalConfigValidationError{} + +// Validate checks the field values on CreateTeamAccountRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *CreateTeamAccountRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on CreateTeamAccountRequest with the +// rules defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// CreateTeamAccountRequestMultiError, or nil if none found. +func (m *CreateTeamAccountRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *CreateTeamAccountRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Name + + if len(errors) > 0 { + return CreateTeamAccountRequestMultiError(errors) + } + + return nil +} + +// CreateTeamAccountRequestMultiError is an error wrapping multiple validation +// errors returned by CreateTeamAccountRequest.ValidateAll() if the designated +// constraints aren't met. +type CreateTeamAccountRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m CreateTeamAccountRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m CreateTeamAccountRequestMultiError) AllErrors() []error { return m } + +// CreateTeamAccountRequestValidationError is the validation error returned by +// CreateTeamAccountRequest.Validate if the designated constraints aren't met. +type CreateTeamAccountRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e CreateTeamAccountRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e CreateTeamAccountRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e CreateTeamAccountRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e CreateTeamAccountRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e CreateTeamAccountRequestValidationError) ErrorName() string { + return "CreateTeamAccountRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e CreateTeamAccountRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sCreateTeamAccountRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = CreateTeamAccountRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = CreateTeamAccountRequestValidationError{} + +// Validate checks the field values on CreateTeamAccountResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *CreateTeamAccountResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on CreateTeamAccountResponse with the +// rules defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// CreateTeamAccountResponseMultiError, or nil if none found. +func (m *CreateTeamAccountResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *CreateTeamAccountResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for AccountId + + if len(errors) > 0 { + return CreateTeamAccountResponseMultiError(errors) + } + + return nil +} + +// CreateTeamAccountResponseMultiError is an error wrapping multiple validation +// errors returned by CreateTeamAccountResponse.ValidateAll() if the +// designated constraints aren't met. +type CreateTeamAccountResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m CreateTeamAccountResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m CreateTeamAccountResponseMultiError) AllErrors() []error { return m } + +// CreateTeamAccountResponseValidationError is the validation error returned by +// CreateTeamAccountResponse.Validate if the designated constraints aren't met. +type CreateTeamAccountResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e CreateTeamAccountResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e CreateTeamAccountResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e CreateTeamAccountResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e CreateTeamAccountResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e CreateTeamAccountResponseValidationError) ErrorName() string { + return "CreateTeamAccountResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e CreateTeamAccountResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sCreateTeamAccountResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = CreateTeamAccountResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = CreateTeamAccountResponseValidationError{} diff --git a/backend/internal/nucleusdb/db.go b/backend/internal/nucleusdb/db.go index f470022293..873914e8b3 100644 --- a/backend/internal/nucleusdb/db.go +++ b/backend/internal/nucleusdb/db.go @@ -2,7 +2,6 @@ package nucleusdb import ( "context" - "fmt" "log/slog" "github.com/jackc/pgx/v5" @@ -107,7 +106,6 @@ func HandleSqlRollback( tx SqlRollbackInterface, logger *slog.Logger, ) { - fmt.Println("HERE") if err := tx.Rollback(); err != nil && !isTxDone(err) { logger.Error(err.Error()) } diff --git a/backend/internal/nucleusdb/users.go b/backend/internal/nucleusdb/users.go index 4ea7c719e3..be7ea1f9c9 100644 --- a/backend/internal/nucleusdb/users.go +++ b/backend/internal/nucleusdb/users.go @@ -2,9 +2,12 @@ package nucleusdb import ( "context" + "fmt" + "strings" "github.com/jackc/pgx/v5/pgtype" db_queries "github.com/nucleuscloud/neosync/backend/gen/go/db" + nucleuserrors "github.com/nucleuscloud/neosync/backend/internal/errors" ) func (d *NucleusDb) SetUserByAuth0Id( @@ -103,3 +106,40 @@ func (d *NucleusDb) SetPersonalAccount( } return personalAccount, nil } + +func (d *NucleusDb) CreateTeamAccount( + ctx context.Context, + userId pgtype.UUID, + teamName string, +) (*db_queries.NeosyncApiAccount, error) { + var teamAccount *db_queries.NeosyncApiAccount + if err := d.WithTx(ctx, nil, func(dbtx BaseDBTX) error { + accounts, err := d.Q.GetTeamAccountsByUserId(ctx, dbtx, userId) + if err != nil && !IsNoRows(err) { + return err + } else if err != nil && IsNoRows(err) { + accounts = []db_queries.NeosyncApiAccount{} + } + for _, account := range accounts { + if strings.EqualFold(account.AccountSlug, teamName) { + return nucleuserrors.NewAlreadyExists(fmt.Sprintf("team account with the name %s already exists", teamName)) + } + } + account, err := d.Q.CreateTeamAccount(ctx, dbtx, teamName) + if err != nil { + return err + } + teamAccount = &account + _, err = d.Q.CreateAccountUserAssociation(ctx, dbtx, db_queries.CreateAccountUserAssociationParams{ + AccountID: account.ID, + UserID: userId, + }) + if err != nil { + return err + } + return nil + }); err != nil { + return nil, err + } + return teamAccount, nil +} diff --git a/backend/protos/mgmt/v1alpha1/user_account.proto b/backend/protos/mgmt/v1alpha1/user_account.proto index 526cadfa6e..4b2e3cfaf7 100644 --- a/backend/protos/mgmt/v1alpha1/user_account.proto +++ b/backend/protos/mgmt/v1alpha1/user_account.proto @@ -67,6 +67,13 @@ message AccountTemporalConfig { string sync_job_queue_name = 3 [(buf.validate.field).string.min_len = 1]; } +message CreateTeamAccountRequest { + string name = 1 [(buf.validate.field).string.min_len = 1]; +} +message CreateTeamAccountResponse { + string account_id = 1; +} + service UserAccountService { rpc GetUser(GetUserRequest) returns (GetUserResponse) {} rpc SetUser(SetUserRequest) returns (SetUserResponse) {} @@ -76,6 +83,7 @@ service UserAccountService { rpc SetPersonalAccount(SetPersonalAccountRequest) returns (SetPersonalAccountResponse) {} rpc ConvertPersonalToTeamAccount(ConvertPersonalToTeamAccountRequest) returns (ConvertPersonalToTeamAccountResponse) {} + rpc CreateTeamAccount(CreateTeamAccountRequest) returns (CreateTeamAccountResponse) {} rpc IsUserInAccount(IsUserInAccountRequest) returns (IsUserInAccountResponse) {} diff --git a/backend/services/mgmt/v1alpha1/job-service/jobs.go b/backend/services/mgmt/v1alpha1/job-service/jobs.go index e7c6cb75c4..4fbd1ff7b1 100644 --- a/backend/services/mgmt/v1alpha1/job-service/jobs.go +++ b/backend/services/mgmt/v1alpha1/job-service/jobs.go @@ -410,7 +410,6 @@ func (s *Service) CreateJob( hasNs, err := s.doesAccountHaveTemporalNamespace(ctx, *accountUuid, logger) if err != nil { - fmt.Println("account doesn't have namespace") return nil, err } if !hasNs { diff --git a/backend/services/mgmt/v1alpha1/user-account-service/users.go b/backend/services/mgmt/v1alpha1/user-account-service/users.go index e02c261f15..4dfabc0aa9 100644 --- a/backend/services/mgmt/v1alpha1/user-account-service/users.go +++ b/backend/services/mgmt/v1alpha1/user-account-service/users.go @@ -168,3 +168,26 @@ func (s *Service) IsUserInAccount( Ok: count > 0, }), nil } + +func (s *Service) CreateTeamAccount( + ctx context.Context, + req *connect.Request[mgmtv1alpha1.CreateTeamAccountRequest], +) (*connect.Response[mgmtv1alpha1.CreateTeamAccountResponse], error) { + user, err := s.GetUser(ctx, connect.NewRequest(&mgmtv1alpha1.GetUserRequest{})) + if err != nil { + return nil, err + } + userId, err := nucleusdb.ToUuid(user.Msg.UserId) + if err != nil { + return nil, err + } + + account, err := s.db.CreateTeamAccount(ctx, userId, req.Msg.Name) + if err != nil { + return nil, err + } + + return connect.NewResponse(&mgmtv1alpha1.CreateTeamAccountResponse{ + AccountId: nucleusdb.UUIDString(account.ID), + }), nil +} diff --git a/backend/sql/postgresql/users.sql b/backend/sql/postgresql/users.sql index 78ffb88fdb..627aa51ef5 100644 --- a/backend/sql/postgresql/users.sql +++ b/backend/sql/postgresql/users.sql @@ -37,6 +37,12 @@ INNER JOIN neosync_api.account_user_associations aua ON aua.account_id = a.id INNER JOIN neosync_api.users u ON u.id = aua.user_id WHERE u.id = sqlc.arg('userId') AND a.account_type = 0; +-- name: GetTeamAccountsByUserId :many +SELECT a.* from neosync_api.accounts a +INNER JOIN neosync_api.account_user_associations aua ON aua.account_id = a.id +INNER JOIN neosync_api.users u ON u.id = aua.user_id +WHERE u.id = sqlc.arg('userId') AND a.account_type = 1; + -- name: CreatePersonalAccount :one INSERT INTO neosync_api.accounts ( account_type, account_slug @@ -45,6 +51,14 @@ INSERT INTO neosync_api.accounts ( ) RETURNING *; +-- name: CreateTeamAccount :one +INSERT INTO neosync_api.accounts ( + account_type, account_slug +) VALUES ( + 1, $1 +) +RETURNING *; + -- name: GetAccountsByUser :many SELECT a.* from neosync_api.accounts a INNER JOIN neosync_api.account_user_associations aua ON aua.account_id = a.id diff --git a/frontend/components/AccountSwitcher.tsx b/frontend/components/AccountSwitcher.tsx index 4172902f20..304bcf8c7f 100644 --- a/frontend/components/AccountSwitcher.tsx +++ b/frontend/components/AccountSwitcher.tsx @@ -1,13 +1,20 @@ 'use client'; - -import { ReactElement } from 'react'; - -import { CaretSortIcon, CheckIcon } from '@radix-ui/react-icons'; +import { + CaretSortIcon, + CheckIcon, + PlusCircledIcon, +} from '@radix-ui/react-icons'; import * as React from 'react'; +import { ReactElement } from 'react'; import { useGetUserAccounts } from '@/libs/hooks/useUserAccounts'; import { cn } from '@/libs/utils'; -import { UserAccountType } from '@/neosync-api-client/mgmt/v1alpha1/user_account_pb'; +import { + CreateTeamAccountRequest, + CreateTeamAccountResponse, + UserAccountType, +} from '@/neosync-api-client/mgmt/v1alpha1/user_account_pb'; +import { getErrorMessage } from '@/util/util'; import { useAccount } from './providers/account-provider'; import { Avatar, AvatarFallback, AvatarImage } from './ui/avatar'; import { Button } from './ui/button'; @@ -18,105 +25,208 @@ import { CommandInput, CommandItem, CommandList, + CommandSeparator, } from './ui/command'; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from './ui/dialog'; +import { Input } from './ui/input'; +import { Label } from './ui/label'; import { Popover, PopoverContent, PopoverTrigger } from './ui/popover'; +import { Skeleton } from './ui/skeleton'; +import { toast } from './ui/use-toast'; interface Props {} export default function AccountSwitcher(_: Props): ReactElement { const { account, setAccount } = useAccount(); - const { data } = useGetUserAccounts(); + const { data, mutate, isLoading } = useGetUserAccounts(); const [open, setOpen] = React.useState(false); + const [showNewTeamDialog, setShowNewTeamDialog] = React.useState(false); + const [teamName, setTeamName] = React.useState(''); const personalAccounts = data?.accounts.filter((a) => a.type == UserAccountType.PERSONAL) || []; const teamAccounts = data?.accounts.filter((a) => a.type == UserAccountType.TEAM) || []; + async function onSubmit(teamName: string): Promise { + try { + await createTeamAccount(teamName); + setShowNewTeamDialog(false); + mutate(); + toast({ + title: 'Successfully created team!', + variant: 'success', + }); + } catch (err) { + console.error(err); + toast({ + title: 'Unable to create team', + description: getErrorMessage(err), + variant: 'destructive', + }); + } + } + if (isLoading) { + return ; + } + return ( - - - - - - - - - No Account found. - - {personalAccounts.map((a) => ( - { - setAccount(a); - setOpen(false); - }} - className="text-sm" - > - - + + + + + + + + + No Account found. + + {personalAccounts.map((a) => ( + { + setAccount(a); + setOpen(false); + }} + className="text-sm" + > + + + SC + + {a.name} + - SC - - {a.name} - - - ))} - - - {teamAccounts.map((a) => ( - { - setAccount(a); - setOpen(false); - }} - className="text-sm" - > - - + ))} + + + {teamAccounts.map((a) => ( + { + setAccount(a); + setOpen(false); + }} + className="text-sm" + > + + + + {a.name} + - - {a.name} - - - ))} - - - - - + + ))} + + + + + + + { + setOpen(false); + setShowNewTeamDialog(true); + }} + > + + Create Team + + + + + + + + + + Create team + Add a new team to manage jobs. + +
+
+
+ + setTeamName(event.target.value)} + /> +
+
+
+ + + + +
+ ); } + +export async function createTeamAccount( + teamName: string +): Promise { + const res = await fetch(`/api/teams`, { + method: 'POST', + headers: { + 'content-type': 'application/json', + }, + body: JSON.stringify( + new CreateTeamAccountRequest({ + name: teamName, + }) + ), + }); + if (!res.ok) { + const body = await res.json(); + throw new Error(body.message); + } + return CreateTeamAccountResponse.fromJson(await res.json()); +} diff --git a/frontend/components/SiteHeader.tsx b/frontend/components/SiteHeader.tsx index b40346f7d0..f19d61750c 100644 --- a/frontend/components/SiteHeader.tsx +++ b/frontend/components/SiteHeader.tsx @@ -1,4 +1,3 @@ -import { isAuthEnabled } from '@/api-only/auth-config'; import { siteConfig } from '@/app/config/site'; import { cn } from '@/libs/utils'; import { GitHubLogoIcon, TwitterLogoIcon } from '@radix-ui/react-icons'; @@ -24,7 +23,8 @@ export default function SiteHeader() {