diff --git a/backend/gen/go/db/models.go b/backend/gen/go/db/models.go index 134efe77d7..839cf2d459 100644 --- a/backend/gen/go/db/models.go +++ b/backend/gen/go/db/models.go @@ -44,6 +44,7 @@ type NeosyncApiAccountInvite struct { CreatedAt pgtype.Timestamp UpdatedAt pgtype.Timestamp ExpiresAt pgtype.Timestamp + Role pgtype.Int4 } type NeosyncApiAccountUserAssociation struct { diff --git a/backend/gen/go/db/users.sql.go b/backend/gen/go/db/users.sql.go index d29593a1b6..dff5662917 100644 --- a/backend/gen/go/db/users.sql.go +++ b/backend/gen/go/db/users.sql.go @@ -45,11 +45,11 @@ func (q *Queries) ConvertPersonalAccountToTeam(ctx context.Context, db DBTX, arg const createAccountInvite = `-- name: CreateAccountInvite :one INSERT INTO neosync_api.account_invites ( - account_id, sender_user_id, email, expires_at + account_id, sender_user_id, email, expires_at, role ) VALUES ( - $1, $2, $3, $4 + $1, $2, $3, $4, $5 ) -RETURNING id, account_id, sender_user_id, email, token, accepted, created_at, updated_at, expires_at +RETURNING id, account_id, sender_user_id, email, token, accepted, created_at, updated_at, expires_at, role ` type CreateAccountInviteParams struct { @@ -57,6 +57,7 @@ type CreateAccountInviteParams struct { SenderUserID pgtype.UUID Email string ExpiresAt pgtype.Timestamp + Role pgtype.Int4 } func (q *Queries) CreateAccountInvite(ctx context.Context, db DBTX, arg CreateAccountInviteParams) (NeosyncApiAccountInvite, error) { @@ -65,6 +66,7 @@ func (q *Queries) CreateAccountInvite(ctx context.Context, db DBTX, arg CreateAc arg.SenderUserID, arg.Email, arg.ExpiresAt, + arg.Role, ) var i NeosyncApiAccountInvite err := row.Scan( @@ -77,6 +79,7 @@ func (q *Queries) CreateAccountInvite(ctx context.Context, db DBTX, arg CreateAc &i.CreatedAt, &i.UpdatedAt, &i.ExpiresAt, + &i.Role, ) return i, err } @@ -273,7 +276,7 @@ func (q *Queries) GetAccountIds(ctx context.Context, db DBTX) ([]pgtype.UUID, er } const getAccountInvite = `-- name: GetAccountInvite :one -SELECT id, account_id, sender_user_id, email, token, accepted, created_at, updated_at, expires_at FROM neosync_api.account_invites +SELECT id, account_id, sender_user_id, email, token, accepted, created_at, updated_at, expires_at, role FROM neosync_api.account_invites WHERE id = $1 ` @@ -290,12 +293,13 @@ func (q *Queries) GetAccountInvite(ctx context.Context, db DBTX, id pgtype.UUID) &i.CreatedAt, &i.UpdatedAt, &i.ExpiresAt, + &i.Role, ) return i, err } const getAccountInviteByToken = `-- name: GetAccountInviteByToken :one -SELECT id, account_id, sender_user_id, email, token, accepted, created_at, updated_at, expires_at FROM neosync_api.account_invites +SELECT id, account_id, sender_user_id, email, token, accepted, created_at, updated_at, expires_at, role FROM neosync_api.account_invites WHERE token = $1 ` @@ -312,6 +316,7 @@ func (q *Queries) GetAccountInviteByToken(ctx context.Context, db DBTX, token st &i.CreatedAt, &i.UpdatedAt, &i.ExpiresAt, + &i.Role, ) return i, err } @@ -429,7 +434,7 @@ func (q *Queries) GetAccountsByUser(ctx context.Context, db DBTX, id pgtype.UUID } const getActiveAccountInvites = `-- name: GetActiveAccountInvites :many -SELECT id, account_id, sender_user_id, email, token, accepted, created_at, updated_at, expires_at FROM neosync_api.account_invites +SELECT id, account_id, sender_user_id, email, token, accepted, created_at, updated_at, expires_at, role FROM neosync_api.account_invites WHERE account_id = $1 AND expires_at > CURRENT_TIMESTAMP AND accepted = false ` @@ -452,6 +457,7 @@ func (q *Queries) GetActiveAccountInvites(ctx context.Context, db DBTX, accounti &i.CreatedAt, &i.UpdatedAt, &i.ExpiresAt, + &i.Role, ); err != nil { return nil, err } @@ -876,7 +882,7 @@ const updateAccountInviteToAccepted = `-- name: UpdateAccountInviteToAccepted :o UPDATE neosync_api.account_invites SET accepted = true WHERE id = $1 -RETURNING id, account_id, sender_user_id, email, token, accepted, created_at, updated_at, expires_at +RETURNING id, account_id, sender_user_id, email, token, accepted, created_at, updated_at, expires_at, role ` func (q *Queries) UpdateAccountInviteToAccepted(ctx context.Context, db DBTX, id pgtype.UUID) (NeosyncApiAccountInvite, error) { @@ -892,6 +898,7 @@ func (q *Queries) UpdateAccountInviteToAccepted(ctx context.Context, db DBTX, id &i.CreatedAt, &i.UpdatedAt, &i.ExpiresAt, + &i.Role, ) return i, err } @@ -929,7 +936,7 @@ const updateActiveAccountInvitesToExpired = `-- name: UpdateActiveAccountInvites UPDATE neosync_api.account_invites SET expires_at = CURRENT_TIMESTAMP WHERE account_id = $1 AND email = $2 AND expires_at > CURRENT_TIMESTAMP -RETURNING id, account_id, sender_user_id, email, token, accepted, created_at, updated_at, expires_at +RETURNING id, account_id, sender_user_id, email, token, accepted, created_at, updated_at, expires_at, role ` type UpdateActiveAccountInvitesToExpiredParams struct { @@ -950,6 +957,7 @@ func (q *Queries) UpdateActiveAccountInvitesToExpired(ctx context.Context, db DB &i.CreatedAt, &i.UpdatedAt, &i.ExpiresAt, + &i.Role, ) return i, err } 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 88d98eaef8..d01189e7e6 100644 --- a/backend/gen/go/protos/mgmt/v1alpha1/user_account.pb.go +++ b/backend/gen/go/protos/mgmt/v1alpha1/user_account.pb.go @@ -1223,6 +1223,8 @@ type AccountUser struct { Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` Image string `protobuf:"bytes,3,opt,name=image,proto3" json:"image,omitempty"` Email string `protobuf:"bytes,4,opt,name=email,proto3" json:"email,omitempty"` + // The role of the user in the account. If RBAC is not enabled, will be unspecified. + Role AccountRole `protobuf:"varint,5,opt,name=role,proto3,enum=mgmt.v1alpha1.AccountRole" json:"role,omitempty"` } func (x *AccountUser) Reset() { @@ -1283,6 +1285,13 @@ func (x *AccountUser) GetEmail() string { return "" } +func (x *AccountUser) GetRole() AccountRole { + if x != nil { + return x.Role + } + return AccountRole_ACCOUNT_ROLE_UNSPECIFIED +} + type GetTeamAccountMembersRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1467,8 +1476,12 @@ type InviteUserToTeamAccountRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // The account id to invite the user to AccountId string `protobuf:"bytes,1,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"` - Email string `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` + // The email of the user to invite + Email string `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` + // The role of the user to invite. Only used if RBAC is enabled. + Role *AccountRole `protobuf:"varint,3,opt,name=role,proto3,enum=mgmt.v1alpha1.AccountRole,oneof" json:"role,omitempty"` } func (x *InviteUserToTeamAccountRequest) Reset() { @@ -1515,6 +1528,13 @@ func (x *InviteUserToTeamAccountRequest) GetEmail() string { return "" } +func (x *InviteUserToTeamAccountRequest) GetRole() AccountRole { + if x != nil && x.Role != nil { + return *x.Role + } + return AccountRole_ACCOUNT_ROLE_UNSPECIFIED +} + type AccountInvite struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1529,6 +1549,8 @@ type AccountInvite struct { CreatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` + // The role of the user to invite. Only used if RBAC is enabled. + Role AccountRole `protobuf:"varint,10,opt,name=role,proto3,enum=mgmt.v1alpha1.AccountRole" json:"role,omitempty"` } func (x *AccountInvite) Reset() { @@ -1624,6 +1646,13 @@ func (x *AccountInvite) GetExpiresAt() *timestamppb.Timestamp { return nil } +func (x *AccountInvite) GetRole() AccountRole { + if x != nil { + return x.Role + } + return AccountRole_ACCOUNT_ROLE_UNSPECIFIED +} + type InviteUserToTeamAccountResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3190,38 +3219,45 @@ var file_mgmt_v1alpha1_user_account_proto_rawDesc = []byte{ 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x12, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x55, 0x72, 0x6c, 0x88, 0x01, 0x01, 0x42, 0x17, 0x0a, 0x15, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x22, 0x5d, 0x0a, 0x0b, 0x41, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6d, - 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x47, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x54, 0x65, 0x61, - 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, - 0x03, 0xb0, 0x01, 0x01, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x22, - 0x51, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x30, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, - 0x72, 0x73, 0x22, 0x6c, 0x0a, 0x1e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x65, 0x61, 0x6d, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, - 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, + 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x22, 0x8d, 0x01, 0x0a, 0x0b, 0x41, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, + 0x6d, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x2e, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x6f, 0x6c, + 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0x47, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x54, 0x65, + 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, + 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, + 0x22, 0x51, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x30, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, 0x75, 0x73, + 0x65, 0x72, 0x73, 0x22, 0x6c, 0x0a, 0x1e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x65, 0x61, + 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, + 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, + 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, + 0x64, 0x22, 0x21, 0x0a, 0x1f, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x65, 0x61, 0x6d, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa6, 0x01, 0x0a, 0x1e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x55, + 0x73, 0x65, 0x72, 0x54, 0x6f, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, - 0x22, 0x21, 0x0a, 0x1f, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x68, 0x0a, 0x1e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x55, 0x73, 0x65, - 0x72, 0x54, 0x6f, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, - 0xb0, 0x01, 0x01, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1d, - 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, - 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0xdd, 0x02, + 0x12, 0x1d, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, + 0x33, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, + 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x04, 0x72, 0x6f, 0x6c, + 0x65, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0x8d, 0x03, 0x0a, 0x0d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, @@ -3243,7 +3279,10 @@ var file_mgmt_v1alpha1_user_account_proto_rawDesc = []byte{ 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x22, 0x57, 0x0a, + 0x6d, 0x70, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x12, 0x2e, 0x0a, + 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x6d, 0x67, + 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0x57, 0x0a, 0x1f, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x54, 0x6f, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x06, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, @@ -3778,77 +3817,80 @@ var file_mgmt_v1alpha1_user_account_proto_depIdxs = []int32{ 21, // 2: mgmt.v1alpha1.GetAccountTemporalConfigResponse.config:type_name -> mgmt.v1alpha1.AccountTemporalConfig 21, // 3: mgmt.v1alpha1.SetAccountTemporalConfigRequest.config:type_name -> mgmt.v1alpha1.AccountTemporalConfig 21, // 4: mgmt.v1alpha1.SetAccountTemporalConfigResponse.config:type_name -> mgmt.v1alpha1.AccountTemporalConfig - 24, // 5: mgmt.v1alpha1.GetTeamAccountMembersResponse.users:type_name -> mgmt.v1alpha1.AccountUser - 59, // 6: mgmt.v1alpha1.AccountInvite.created_at:type_name -> google.protobuf.Timestamp - 59, // 7: mgmt.v1alpha1.AccountInvite.updated_at:type_name -> google.protobuf.Timestamp - 59, // 8: mgmt.v1alpha1.AccountInvite.expires_at:type_name -> google.protobuf.Timestamp - 30, // 9: mgmt.v1alpha1.InviteUserToTeamAccountResponse.invite:type_name -> mgmt.v1alpha1.AccountInvite - 30, // 10: mgmt.v1alpha1.GetTeamAccountInvitesResponse.invites:type_name -> mgmt.v1alpha1.AccountInvite - 10, // 11: mgmt.v1alpha1.AcceptTeamAccountInviteResponse.account:type_name -> mgmt.v1alpha1.UserAccount - 59, // 12: mgmt.v1alpha1.GetSystemInformationResponse.build_date:type_name -> google.protobuf.Timestamp - 44, // 13: mgmt.v1alpha1.GetAccountOnboardingConfigResponse.config:type_name -> mgmt.v1alpha1.AccountOnboardingConfig - 44, // 14: mgmt.v1alpha1.SetAccountOnboardingConfigRequest.config:type_name -> mgmt.v1alpha1.AccountOnboardingConfig - 44, // 15: mgmt.v1alpha1.SetAccountOnboardingConfigResponse.config:type_name -> mgmt.v1alpha1.AccountOnboardingConfig - 1, // 16: mgmt.v1alpha1.GetAccountStatusResponse.subscription_status:type_name -> mgmt.v1alpha1.BillingStatus - 2, // 17: mgmt.v1alpha1.IsAccountStatusValidResponse.account_status:type_name -> mgmt.v1alpha1.AccountStatus - 59, // 18: mgmt.v1alpha1.IsAccountStatusValidResponse.trial_expires_at:type_name -> google.protobuf.Timestamp - 10, // 19: mgmt.v1alpha1.GetBillingAccountsResponse.accounts:type_name -> mgmt.v1alpha1.UserAccount - 3, // 20: mgmt.v1alpha1.SetUserRoleRequest.role:type_name -> mgmt.v1alpha1.AccountRole - 4, // 21: mgmt.v1alpha1.UserAccountService.GetUser:input_type -> mgmt.v1alpha1.GetUserRequest - 6, // 22: mgmt.v1alpha1.UserAccountService.SetUser:input_type -> mgmt.v1alpha1.SetUserRequest - 8, // 23: mgmt.v1alpha1.UserAccountService.GetUserAccounts:input_type -> mgmt.v1alpha1.GetUserAccountsRequest - 13, // 24: mgmt.v1alpha1.UserAccountService.SetPersonalAccount:input_type -> mgmt.v1alpha1.SetPersonalAccountRequest - 11, // 25: mgmt.v1alpha1.UserAccountService.ConvertPersonalToTeamAccount:input_type -> mgmt.v1alpha1.ConvertPersonalToTeamAccountRequest - 22, // 26: mgmt.v1alpha1.UserAccountService.CreateTeamAccount:input_type -> mgmt.v1alpha1.CreateTeamAccountRequest - 15, // 27: mgmt.v1alpha1.UserAccountService.IsUserInAccount:input_type -> mgmt.v1alpha1.IsUserInAccountRequest - 17, // 28: mgmt.v1alpha1.UserAccountService.GetAccountTemporalConfig:input_type -> mgmt.v1alpha1.GetAccountTemporalConfigRequest - 19, // 29: mgmt.v1alpha1.UserAccountService.SetAccountTemporalConfig:input_type -> mgmt.v1alpha1.SetAccountTemporalConfigRequest - 25, // 30: mgmt.v1alpha1.UserAccountService.GetTeamAccountMembers:input_type -> mgmt.v1alpha1.GetTeamAccountMembersRequest - 27, // 31: mgmt.v1alpha1.UserAccountService.RemoveTeamAccountMember:input_type -> mgmt.v1alpha1.RemoveTeamAccountMemberRequest - 29, // 32: mgmt.v1alpha1.UserAccountService.InviteUserToTeamAccount:input_type -> mgmt.v1alpha1.InviteUserToTeamAccountRequest - 32, // 33: mgmt.v1alpha1.UserAccountService.GetTeamAccountInvites:input_type -> mgmt.v1alpha1.GetTeamAccountInvitesRequest - 34, // 34: mgmt.v1alpha1.UserAccountService.RemoveTeamAccountInvite:input_type -> mgmt.v1alpha1.RemoveTeamAccountInviteRequest - 36, // 35: mgmt.v1alpha1.UserAccountService.AcceptTeamAccountInvite:input_type -> mgmt.v1alpha1.AcceptTeamAccountInviteRequest - 38, // 36: mgmt.v1alpha1.UserAccountService.GetSystemInformation:input_type -> mgmt.v1alpha1.GetSystemInformationRequest - 40, // 37: mgmt.v1alpha1.UserAccountService.GetAccountOnboardingConfig:input_type -> mgmt.v1alpha1.GetAccountOnboardingConfigRequest - 42, // 38: mgmt.v1alpha1.UserAccountService.SetAccountOnboardingConfig:input_type -> mgmt.v1alpha1.SetAccountOnboardingConfigRequest - 45, // 39: mgmt.v1alpha1.UserAccountService.GetAccountStatus:input_type -> mgmt.v1alpha1.GetAccountStatusRequest - 47, // 40: mgmt.v1alpha1.UserAccountService.IsAccountStatusValid:input_type -> mgmt.v1alpha1.IsAccountStatusValidRequest - 49, // 41: mgmt.v1alpha1.UserAccountService.GetAccountBillingCheckoutSession:input_type -> mgmt.v1alpha1.GetAccountBillingCheckoutSessionRequest - 51, // 42: mgmt.v1alpha1.UserAccountService.GetAccountBillingPortalSession:input_type -> mgmt.v1alpha1.GetAccountBillingPortalSessionRequest - 53, // 43: mgmt.v1alpha1.UserAccountService.GetBillingAccounts:input_type -> mgmt.v1alpha1.GetBillingAccountsRequest - 55, // 44: mgmt.v1alpha1.UserAccountService.SetBillingMeterEvent:input_type -> mgmt.v1alpha1.SetBillingMeterEventRequest - 57, // 45: mgmt.v1alpha1.UserAccountService.SetUserRole:input_type -> mgmt.v1alpha1.SetUserRoleRequest - 5, // 46: mgmt.v1alpha1.UserAccountService.GetUser:output_type -> mgmt.v1alpha1.GetUserResponse - 7, // 47: mgmt.v1alpha1.UserAccountService.SetUser:output_type -> mgmt.v1alpha1.SetUserResponse - 9, // 48: mgmt.v1alpha1.UserAccountService.GetUserAccounts:output_type -> mgmt.v1alpha1.GetUserAccountsResponse - 14, // 49: mgmt.v1alpha1.UserAccountService.SetPersonalAccount:output_type -> mgmt.v1alpha1.SetPersonalAccountResponse - 12, // 50: mgmt.v1alpha1.UserAccountService.ConvertPersonalToTeamAccount:output_type -> mgmt.v1alpha1.ConvertPersonalToTeamAccountResponse - 23, // 51: mgmt.v1alpha1.UserAccountService.CreateTeamAccount:output_type -> mgmt.v1alpha1.CreateTeamAccountResponse - 16, // 52: mgmt.v1alpha1.UserAccountService.IsUserInAccount:output_type -> mgmt.v1alpha1.IsUserInAccountResponse - 18, // 53: mgmt.v1alpha1.UserAccountService.GetAccountTemporalConfig:output_type -> mgmt.v1alpha1.GetAccountTemporalConfigResponse - 20, // 54: mgmt.v1alpha1.UserAccountService.SetAccountTemporalConfig:output_type -> mgmt.v1alpha1.SetAccountTemporalConfigResponse - 26, // 55: mgmt.v1alpha1.UserAccountService.GetTeamAccountMembers:output_type -> mgmt.v1alpha1.GetTeamAccountMembersResponse - 28, // 56: mgmt.v1alpha1.UserAccountService.RemoveTeamAccountMember:output_type -> mgmt.v1alpha1.RemoveTeamAccountMemberResponse - 31, // 57: mgmt.v1alpha1.UserAccountService.InviteUserToTeamAccount:output_type -> mgmt.v1alpha1.InviteUserToTeamAccountResponse - 33, // 58: mgmt.v1alpha1.UserAccountService.GetTeamAccountInvites:output_type -> mgmt.v1alpha1.GetTeamAccountInvitesResponse - 35, // 59: mgmt.v1alpha1.UserAccountService.RemoveTeamAccountInvite:output_type -> mgmt.v1alpha1.RemoveTeamAccountInviteResponse - 37, // 60: mgmt.v1alpha1.UserAccountService.AcceptTeamAccountInvite:output_type -> mgmt.v1alpha1.AcceptTeamAccountInviteResponse - 39, // 61: mgmt.v1alpha1.UserAccountService.GetSystemInformation:output_type -> mgmt.v1alpha1.GetSystemInformationResponse - 41, // 62: mgmt.v1alpha1.UserAccountService.GetAccountOnboardingConfig:output_type -> mgmt.v1alpha1.GetAccountOnboardingConfigResponse - 43, // 63: mgmt.v1alpha1.UserAccountService.SetAccountOnboardingConfig:output_type -> mgmt.v1alpha1.SetAccountOnboardingConfigResponse - 46, // 64: mgmt.v1alpha1.UserAccountService.GetAccountStatus:output_type -> mgmt.v1alpha1.GetAccountStatusResponse - 48, // 65: mgmt.v1alpha1.UserAccountService.IsAccountStatusValid:output_type -> mgmt.v1alpha1.IsAccountStatusValidResponse - 50, // 66: mgmt.v1alpha1.UserAccountService.GetAccountBillingCheckoutSession:output_type -> mgmt.v1alpha1.GetAccountBillingCheckoutSessionResponse - 52, // 67: mgmt.v1alpha1.UserAccountService.GetAccountBillingPortalSession:output_type -> mgmt.v1alpha1.GetAccountBillingPortalSessionResponse - 54, // 68: mgmt.v1alpha1.UserAccountService.GetBillingAccounts:output_type -> mgmt.v1alpha1.GetBillingAccountsResponse - 56, // 69: mgmt.v1alpha1.UserAccountService.SetBillingMeterEvent:output_type -> mgmt.v1alpha1.SetBillingMeterEventResponse - 58, // 70: mgmt.v1alpha1.UserAccountService.SetUserRole:output_type -> mgmt.v1alpha1.SetUserRoleResponse - 46, // [46:71] is the sub-list for method output_type - 21, // [21:46] is the sub-list for method input_type - 21, // [21:21] is the sub-list for extension type_name - 21, // [21:21] is the sub-list for extension extendee - 0, // [0:21] is the sub-list for field type_name + 3, // 5: mgmt.v1alpha1.AccountUser.role:type_name -> mgmt.v1alpha1.AccountRole + 24, // 6: mgmt.v1alpha1.GetTeamAccountMembersResponse.users:type_name -> mgmt.v1alpha1.AccountUser + 3, // 7: mgmt.v1alpha1.InviteUserToTeamAccountRequest.role:type_name -> mgmt.v1alpha1.AccountRole + 59, // 8: mgmt.v1alpha1.AccountInvite.created_at:type_name -> google.protobuf.Timestamp + 59, // 9: mgmt.v1alpha1.AccountInvite.updated_at:type_name -> google.protobuf.Timestamp + 59, // 10: mgmt.v1alpha1.AccountInvite.expires_at:type_name -> google.protobuf.Timestamp + 3, // 11: mgmt.v1alpha1.AccountInvite.role:type_name -> mgmt.v1alpha1.AccountRole + 30, // 12: mgmt.v1alpha1.InviteUserToTeamAccountResponse.invite:type_name -> mgmt.v1alpha1.AccountInvite + 30, // 13: mgmt.v1alpha1.GetTeamAccountInvitesResponse.invites:type_name -> mgmt.v1alpha1.AccountInvite + 10, // 14: mgmt.v1alpha1.AcceptTeamAccountInviteResponse.account:type_name -> mgmt.v1alpha1.UserAccount + 59, // 15: mgmt.v1alpha1.GetSystemInformationResponse.build_date:type_name -> google.protobuf.Timestamp + 44, // 16: mgmt.v1alpha1.GetAccountOnboardingConfigResponse.config:type_name -> mgmt.v1alpha1.AccountOnboardingConfig + 44, // 17: mgmt.v1alpha1.SetAccountOnboardingConfigRequest.config:type_name -> mgmt.v1alpha1.AccountOnboardingConfig + 44, // 18: mgmt.v1alpha1.SetAccountOnboardingConfigResponse.config:type_name -> mgmt.v1alpha1.AccountOnboardingConfig + 1, // 19: mgmt.v1alpha1.GetAccountStatusResponse.subscription_status:type_name -> mgmt.v1alpha1.BillingStatus + 2, // 20: mgmt.v1alpha1.IsAccountStatusValidResponse.account_status:type_name -> mgmt.v1alpha1.AccountStatus + 59, // 21: mgmt.v1alpha1.IsAccountStatusValidResponse.trial_expires_at:type_name -> google.protobuf.Timestamp + 10, // 22: mgmt.v1alpha1.GetBillingAccountsResponse.accounts:type_name -> mgmt.v1alpha1.UserAccount + 3, // 23: mgmt.v1alpha1.SetUserRoleRequest.role:type_name -> mgmt.v1alpha1.AccountRole + 4, // 24: mgmt.v1alpha1.UserAccountService.GetUser:input_type -> mgmt.v1alpha1.GetUserRequest + 6, // 25: mgmt.v1alpha1.UserAccountService.SetUser:input_type -> mgmt.v1alpha1.SetUserRequest + 8, // 26: mgmt.v1alpha1.UserAccountService.GetUserAccounts:input_type -> mgmt.v1alpha1.GetUserAccountsRequest + 13, // 27: mgmt.v1alpha1.UserAccountService.SetPersonalAccount:input_type -> mgmt.v1alpha1.SetPersonalAccountRequest + 11, // 28: mgmt.v1alpha1.UserAccountService.ConvertPersonalToTeamAccount:input_type -> mgmt.v1alpha1.ConvertPersonalToTeamAccountRequest + 22, // 29: mgmt.v1alpha1.UserAccountService.CreateTeamAccount:input_type -> mgmt.v1alpha1.CreateTeamAccountRequest + 15, // 30: mgmt.v1alpha1.UserAccountService.IsUserInAccount:input_type -> mgmt.v1alpha1.IsUserInAccountRequest + 17, // 31: mgmt.v1alpha1.UserAccountService.GetAccountTemporalConfig:input_type -> mgmt.v1alpha1.GetAccountTemporalConfigRequest + 19, // 32: mgmt.v1alpha1.UserAccountService.SetAccountTemporalConfig:input_type -> mgmt.v1alpha1.SetAccountTemporalConfigRequest + 25, // 33: mgmt.v1alpha1.UserAccountService.GetTeamAccountMembers:input_type -> mgmt.v1alpha1.GetTeamAccountMembersRequest + 27, // 34: mgmt.v1alpha1.UserAccountService.RemoveTeamAccountMember:input_type -> mgmt.v1alpha1.RemoveTeamAccountMemberRequest + 29, // 35: mgmt.v1alpha1.UserAccountService.InviteUserToTeamAccount:input_type -> mgmt.v1alpha1.InviteUserToTeamAccountRequest + 32, // 36: mgmt.v1alpha1.UserAccountService.GetTeamAccountInvites:input_type -> mgmt.v1alpha1.GetTeamAccountInvitesRequest + 34, // 37: mgmt.v1alpha1.UserAccountService.RemoveTeamAccountInvite:input_type -> mgmt.v1alpha1.RemoveTeamAccountInviteRequest + 36, // 38: mgmt.v1alpha1.UserAccountService.AcceptTeamAccountInvite:input_type -> mgmt.v1alpha1.AcceptTeamAccountInviteRequest + 38, // 39: mgmt.v1alpha1.UserAccountService.GetSystemInformation:input_type -> mgmt.v1alpha1.GetSystemInformationRequest + 40, // 40: mgmt.v1alpha1.UserAccountService.GetAccountOnboardingConfig:input_type -> mgmt.v1alpha1.GetAccountOnboardingConfigRequest + 42, // 41: mgmt.v1alpha1.UserAccountService.SetAccountOnboardingConfig:input_type -> mgmt.v1alpha1.SetAccountOnboardingConfigRequest + 45, // 42: mgmt.v1alpha1.UserAccountService.GetAccountStatus:input_type -> mgmt.v1alpha1.GetAccountStatusRequest + 47, // 43: mgmt.v1alpha1.UserAccountService.IsAccountStatusValid:input_type -> mgmt.v1alpha1.IsAccountStatusValidRequest + 49, // 44: mgmt.v1alpha1.UserAccountService.GetAccountBillingCheckoutSession:input_type -> mgmt.v1alpha1.GetAccountBillingCheckoutSessionRequest + 51, // 45: mgmt.v1alpha1.UserAccountService.GetAccountBillingPortalSession:input_type -> mgmt.v1alpha1.GetAccountBillingPortalSessionRequest + 53, // 46: mgmt.v1alpha1.UserAccountService.GetBillingAccounts:input_type -> mgmt.v1alpha1.GetBillingAccountsRequest + 55, // 47: mgmt.v1alpha1.UserAccountService.SetBillingMeterEvent:input_type -> mgmt.v1alpha1.SetBillingMeterEventRequest + 57, // 48: mgmt.v1alpha1.UserAccountService.SetUserRole:input_type -> mgmt.v1alpha1.SetUserRoleRequest + 5, // 49: mgmt.v1alpha1.UserAccountService.GetUser:output_type -> mgmt.v1alpha1.GetUserResponse + 7, // 50: mgmt.v1alpha1.UserAccountService.SetUser:output_type -> mgmt.v1alpha1.SetUserResponse + 9, // 51: mgmt.v1alpha1.UserAccountService.GetUserAccounts:output_type -> mgmt.v1alpha1.GetUserAccountsResponse + 14, // 52: mgmt.v1alpha1.UserAccountService.SetPersonalAccount:output_type -> mgmt.v1alpha1.SetPersonalAccountResponse + 12, // 53: mgmt.v1alpha1.UserAccountService.ConvertPersonalToTeamAccount:output_type -> mgmt.v1alpha1.ConvertPersonalToTeamAccountResponse + 23, // 54: mgmt.v1alpha1.UserAccountService.CreateTeamAccount:output_type -> mgmt.v1alpha1.CreateTeamAccountResponse + 16, // 55: mgmt.v1alpha1.UserAccountService.IsUserInAccount:output_type -> mgmt.v1alpha1.IsUserInAccountResponse + 18, // 56: mgmt.v1alpha1.UserAccountService.GetAccountTemporalConfig:output_type -> mgmt.v1alpha1.GetAccountTemporalConfigResponse + 20, // 57: mgmt.v1alpha1.UserAccountService.SetAccountTemporalConfig:output_type -> mgmt.v1alpha1.SetAccountTemporalConfigResponse + 26, // 58: mgmt.v1alpha1.UserAccountService.GetTeamAccountMembers:output_type -> mgmt.v1alpha1.GetTeamAccountMembersResponse + 28, // 59: mgmt.v1alpha1.UserAccountService.RemoveTeamAccountMember:output_type -> mgmt.v1alpha1.RemoveTeamAccountMemberResponse + 31, // 60: mgmt.v1alpha1.UserAccountService.InviteUserToTeamAccount:output_type -> mgmt.v1alpha1.InviteUserToTeamAccountResponse + 33, // 61: mgmt.v1alpha1.UserAccountService.GetTeamAccountInvites:output_type -> mgmt.v1alpha1.GetTeamAccountInvitesResponse + 35, // 62: mgmt.v1alpha1.UserAccountService.RemoveTeamAccountInvite:output_type -> mgmt.v1alpha1.RemoveTeamAccountInviteResponse + 37, // 63: mgmt.v1alpha1.UserAccountService.AcceptTeamAccountInvite:output_type -> mgmt.v1alpha1.AcceptTeamAccountInviteResponse + 39, // 64: mgmt.v1alpha1.UserAccountService.GetSystemInformation:output_type -> mgmt.v1alpha1.GetSystemInformationResponse + 41, // 65: mgmt.v1alpha1.UserAccountService.GetAccountOnboardingConfig:output_type -> mgmt.v1alpha1.GetAccountOnboardingConfigResponse + 43, // 66: mgmt.v1alpha1.UserAccountService.SetAccountOnboardingConfig:output_type -> mgmt.v1alpha1.SetAccountOnboardingConfigResponse + 46, // 67: mgmt.v1alpha1.UserAccountService.GetAccountStatus:output_type -> mgmt.v1alpha1.GetAccountStatusResponse + 48, // 68: mgmt.v1alpha1.UserAccountService.IsAccountStatusValid:output_type -> mgmt.v1alpha1.IsAccountStatusValidResponse + 50, // 69: mgmt.v1alpha1.UserAccountService.GetAccountBillingCheckoutSession:output_type -> mgmt.v1alpha1.GetAccountBillingCheckoutSessionResponse + 52, // 70: mgmt.v1alpha1.UserAccountService.GetAccountBillingPortalSession:output_type -> mgmt.v1alpha1.GetAccountBillingPortalSessionResponse + 54, // 71: mgmt.v1alpha1.UserAccountService.GetBillingAccounts:output_type -> mgmt.v1alpha1.GetBillingAccountsResponse + 56, // 72: mgmt.v1alpha1.UserAccountService.SetBillingMeterEvent:output_type -> mgmt.v1alpha1.SetBillingMeterEventResponse + 58, // 73: mgmt.v1alpha1.UserAccountService.SetUserRole:output_type -> mgmt.v1alpha1.SetUserRoleResponse + 49, // [49:74] is the sub-list for method output_type + 24, // [24:49] is the sub-list for method input_type + 24, // [24:24] is the sub-list for extension type_name + 24, // [24:24] is the sub-list for extension extendee + 0, // [0:24] is the sub-list for field type_name } func init() { file_mgmt_v1alpha1_user_account_proto_init() } @@ -3859,6 +3901,7 @@ func file_mgmt_v1alpha1_user_account_proto_init() { file_mgmt_v1alpha1_user_account_proto_msgTypes[7].OneofWrappers = []any{} file_mgmt_v1alpha1_user_account_proto_msgTypes[8].OneofWrappers = []any{} file_mgmt_v1alpha1_user_account_proto_msgTypes[19].OneofWrappers = []any{} + file_mgmt_v1alpha1_user_account_proto_msgTypes[25].OneofWrappers = []any{} file_mgmt_v1alpha1_user_account_proto_msgTypes[42].OneofWrappers = []any{} file_mgmt_v1alpha1_user_account_proto_msgTypes[43].OneofWrappers = []any{} file_mgmt_v1alpha1_user_account_proto_msgTypes[44].OneofWrappers = []any{} diff --git a/backend/internal/dtomaps/users.go b/backend/internal/dtomaps/users.go index cf1b470371..2f53c72ae7 100644 --- a/backend/internal/dtomaps/users.go +++ b/backend/internal/dtomaps/users.go @@ -32,9 +32,16 @@ func ToAccountInviteDto(input *db_queries.NeosyncApiAccountInvite) *mgmtv1alpha1 CreatedAt: timestamppb.New(input.CreatedAt.Time), UpdatedAt: timestamppb.New(input.UpdatedAt.Time), ExpiresAt: timestamppb.New(input.ExpiresAt.Time), + Role: toRoleDto(input.Role), } } +func toRoleDto(role pgtype.Int4) mgmtv1alpha1.AccountRole { + if !role.Valid { + return mgmtv1alpha1.AccountRole_ACCOUNT_ROLE_UNSPECIFIED + } + return mgmtv1alpha1.AccountRole(role.Int32) +} func ToUserAccount(input *db_queries.NeosyncApiAccount) *mgmtv1alpha1.UserAccount { return &mgmtv1alpha1.UserAccount{ Id: neosyncdb.UUIDString(input.ID), diff --git a/backend/internal/ee/rbac/allow_all_client.go b/backend/internal/ee/rbac/allow_all_client.go index 9f7e9e4c24..98c6bbfa31 100644 --- a/backend/internal/ee/rbac/allow_all_client.go +++ b/backend/internal/ee/rbac/allow_all_client.go @@ -51,6 +51,9 @@ func (a *AllowAllClient) RemoveAccountUser(ctx context.Context, user, account En func (a *AllowAllClient) SetupNewAccount(ctx context.Context, accountId string, logger *slog.Logger) error { return nil } +func (a *AllowAllClient) GetUserRoles(ctx context.Context, users []EntityString, account EntityString, logger *slog.Logger) map[string]Role { + return map[string]Role{} +} func NewAllowAllClient() *AllowAllClient { return &AllowAllClient{} diff --git a/backend/internal/ee/rbac/policy.go b/backend/internal/ee/rbac/policy.go index a176f8a1ec..72053fc0c0 100644 --- a/backend/internal/ee/rbac/policy.go +++ b/backend/internal/ee/rbac/policy.go @@ -33,6 +33,7 @@ type RoleAdmin interface { RemoveAccountRole(ctx context.Context, user EntityString, account EntityString, role mgmtv1alpha1.AccountRole) error RemoveAccountUser(ctx context.Context, user EntityString, account EntityString) error SetupNewAccount(ctx context.Context, accountId string, logger *slog.Logger) error + GetUserRoles(ctx context.Context, users []EntityString, account EntityString, logger *slog.Logger) map[string]Role } // Initialize default policies for existing accounts at startup @@ -170,6 +171,7 @@ func getAccountPolicyRules(accountId string) [][]string { Wildcard, // any resource in the account Wildcard, // all actions in the account }, + // Job Developer { Role_JobDeveloper.String(), accountKey, @@ -188,17 +190,37 @@ func getAccountPolicyRules(accountId string) [][]string { accountKey, AccountAction_View.String(), // job developer can view the account }, + // Job Executor { - Role_JobViewer.String(), + Role_JobExecutor.String(), accountKey, JobWildcard.String(), - JobAction_View.String(), // job viewer can view all jobs in the account + JobAction_View.String(), // job executor can view all jobs in the account + }, + { + Role_JobExecutor.String(), + accountKey, + ConnectionWildcard.String(), + ConnectionAction_View.String(), // job executor can view all connections in the account + }, + { + Role_JobExecutor.String(), + accountKey, + accountKey, + AccountAction_View.String(), // job executor can view the account + }, + { + Role_JobExecutor.String(), + accountKey, + JobWildcard.String(), + JobAction_Execute.String(), // job executor can execute all jobs in the account }, + // Job Viewer { Role_JobViewer.String(), accountKey, JobWildcard.String(), - JobAction_Execute.String(), // job viewer can execute all jobs in the account + JobAction_View.String(), // job viewer can view all jobs in the account }, { Role_JobViewer.String(), @@ -222,7 +244,7 @@ func (r *Rbac) SetAccountRole( account EntityString, role mgmtv1alpha1.AccountRole, ) error { - roleName, err := toRoleName(role) + roleName, err := fromRoleDto(role) if err != nil { return err } @@ -243,7 +265,7 @@ func (r *Rbac) RemoveAccountRole( account EntityString, role mgmtv1alpha1.AccountRole, ) error { - roleName, err := toRoleName(role) + roleName, err := fromRoleDto(role) if err != nil { return err } @@ -261,6 +283,29 @@ func (r *Rbac) RemoveAccountUser( return err } +// GetUserRoles returns a map of user entities to their associated roles for a given account +func (r *Rbac) GetUserRoles( + ctx context.Context, + users []EntityString, + account EntityString, + logger *slog.Logger, +) map[string]Role { + result := make(map[string]Role) + for _, user := range users { + roles := r.e.GetRolesForUserInDomain(user.String(), account.String()) + if len(roles) > 1 { + logger.Warn("user has multiple roles when they should only have one", + "user", user.String(), + "account", account.String(), + "roles", roles) + } + if len(roles) > 0 { + result[user.String()] = Role(roles[0]) + } + } + return result +} + func (r *Rbac) Job( ctx context.Context, user EntityString, @@ -340,19 +385,6 @@ func (r *Rbac) EnforceAccount( return nil } -func toRoleName(role mgmtv1alpha1.AccountRole) (string, error) { - switch role { - case mgmtv1alpha1.AccountRole_ACCOUNT_ROLE_ADMIN: - return Role_AccountAdmin.String(), nil - case mgmtv1alpha1.AccountRole_ACCOUNT_ROLE_JOB_DEVELOPER: - return Role_JobDeveloper.String(), nil - case mgmtv1alpha1.AccountRole_ACCOUNT_ROLE_JOB_VIEWER: - return Role_JobViewer.String(), nil - default: - return "", fmt.Errorf("account role provided has not be mapped to a casbin role name: %d", role) - } -} - func setPolicy(e casbin.IEnforcer, policy []string) error { // AddPoliciesEx is what should be uesd here but is resulting in duplicates (and errors with unique constraint) // AddPolicies handles the unique constraint but fails if even one policy already exists.. diff --git a/backend/internal/ee/rbac/rbac_integration_test.go b/backend/internal/ee/rbac/rbac_integration_test.go index 16b918de7e..011197ed4e 100644 --- a/backend/internal/ee/rbac/rbac_integration_test.go +++ b/backend/internal/ee/rbac/rbac_integration_test.go @@ -94,7 +94,7 @@ func TestRbac(t *testing.T) { require.NoError(t, err) }) - t.Run("job_viewer", func(t *testing.T) { + t.Run("job_executor", func(t *testing.T) { t.Parallel() accountId := uuid.NewString() @@ -102,8 +102,8 @@ func TestRbac(t *testing.T) { err := rbacclient.SetupNewAccount(ctx, accountId, testutil.GetTestLogger(t)) require.NoError(t, err) - // Set user as job viewer - err = rbacclient.SetAccountRole(ctx, NewUserIdEntity(userId), NewAccountIdEntity(accountId), mgmtv1alpha1.AccountRole_ACCOUNT_ROLE_JOB_VIEWER) + // Set user as job executor + err = rbacclient.SetAccountRole(ctx, NewUserIdEntity(userId), NewAccountIdEntity(accountId), mgmtv1alpha1.AccountRole_ACCOUNT_ROLE_JOB_EXECUTOR) require.NoError(t, err) // Test Account permissions (should only have view) @@ -123,6 +123,35 @@ func TestRbac(t *testing.T) { require.ErrorContains(t, err, "user does not have permission to create job") }) + t.Run("job_viewer", func(t *testing.T) { + t.Parallel() + + accountId := uuid.NewString() + userId := uuid.NewString() + err := rbacclient.SetupNewAccount(ctx, accountId, testutil.GetTestLogger(t)) + require.NoError(t, err) + + // Set user as job viewer + err = rbacclient.SetAccountRole(ctx, NewUserIdEntity(userId), NewAccountIdEntity(accountId), mgmtv1alpha1.AccountRole_ACCOUNT_ROLE_JOB_VIEWER) + require.NoError(t, err) + + // Test Account permissions (should only have view) + err = rbacclient.EnforceAccount(ctx, NewUserIdEntity(userId), NewAccountIdEntity(accountId), AccountAction_View) + require.NoError(t, err) + + // Test Job permissions (should only have view) + jobId := uuid.NewString() + err = rbacclient.EnforceJob(ctx, NewUserIdEntity(userId), NewAccountIdEntity(accountId), NewJobIdEntity(jobId), JobAction_View) + require.NoError(t, err) + + err = rbacclient.EnforceJob(ctx, NewUserIdEntity(userId), NewAccountIdEntity(accountId), NewJobIdEntity(jobId), JobAction_Execute) + require.Error(t, err) + require.ErrorContains(t, err, "user does not have permission to execute job") + err = rbacclient.EnforceJob(ctx, NewUserIdEntity(userId), NewAccountIdEntity(accountId), NewJobIdEntity(jobId), JobAction_Create) + require.Error(t, err) + require.ErrorContains(t, err, "user does not have permission to create job") + }) + t.Run("role_changes", func(t *testing.T) { t.Parallel() @@ -212,10 +241,13 @@ func TestRbac(t *testing.T) { // Verify job viewer can only view and execute jobs err = rbacclient.EnforceJob(ctx, NewUserIdEntity(viewerUserId), NewAccountIdEntity(accountId), NewJobIdEntity(jobId), JobAction_View) require.NoError(t, err) - err = rbacclient.EnforceJob(ctx, NewUserIdEntity(viewerUserId), NewAccountIdEntity(accountId), NewJobIdEntity(jobId), JobAction_Execute) - require.NoError(t, err) // Verify job viewer cannot perform other actions + + err = rbacclient.EnforceJob(ctx, NewUserIdEntity(viewerUserId), NewAccountIdEntity(accountId), NewJobIdEntity(jobId), JobAction_Execute) + require.Error(t, err) + require.ErrorContains(t, err, "user does not have permission to execute job") + err = rbacclient.EnforceJob(ctx, NewUserIdEntity(viewerUserId), NewAccountIdEntity(accountId), NewJobIdEntity(jobId), JobAction_Create) require.Error(t, err) require.ErrorContains(t, err, "user does not have permission to create job") diff --git a/backend/internal/ee/rbac/roles.go b/backend/internal/ee/rbac/roles.go index cd23445bc0..49e7a0f9d7 100644 --- a/backend/internal/ee/rbac/roles.go +++ b/backend/internal/ee/rbac/roles.go @@ -1,13 +1,50 @@ package rbac +import ( + "fmt" + + mgmtv1alpha1 "github.com/nucleuscloud/neosync/backend/gen/go/protos/mgmt/v1alpha1" +) + type Role string const ( Role_AccountAdmin Role = "account_admin" Role_JobDeveloper Role = "job_developer" + Role_JobExecutor Role = "job_executor" Role_JobViewer Role = "job_viewer" ) func (r Role) String() string { return string(r) } + +func (r Role) ToDto() mgmtv1alpha1.AccountRole { + switch r { + case Role_AccountAdmin: + return mgmtv1alpha1.AccountRole_ACCOUNT_ROLE_ADMIN + case Role_JobDeveloper: + return mgmtv1alpha1.AccountRole_ACCOUNT_ROLE_JOB_DEVELOPER + case Role_JobExecutor: + return mgmtv1alpha1.AccountRole_ACCOUNT_ROLE_JOB_EXECUTOR + case Role_JobViewer: + return mgmtv1alpha1.AccountRole_ACCOUNT_ROLE_JOB_VIEWER + default: + return mgmtv1alpha1.AccountRole_ACCOUNT_ROLE_UNSPECIFIED + } +} + +func fromRoleDto(role mgmtv1alpha1.AccountRole) (string, error) { + switch role { + case mgmtv1alpha1.AccountRole_ACCOUNT_ROLE_ADMIN: + return Role_AccountAdmin.String(), nil + case mgmtv1alpha1.AccountRole_ACCOUNT_ROLE_JOB_DEVELOPER: + return Role_JobDeveloper.String(), nil + case mgmtv1alpha1.AccountRole_ACCOUNT_ROLE_JOB_EXECUTOR: + return Role_JobExecutor.String(), nil + case mgmtv1alpha1.AccountRole_ACCOUNT_ROLE_JOB_VIEWER: + return Role_JobViewer.String(), nil + default: + return "", fmt.Errorf("account role provided has not be mapped to a casbin role name: %d", role) + } +} diff --git a/backend/internal/neosyncdb/integration_test.go b/backend/internal/neosyncdb/integration_test.go index defb49f3d1..fddad338a7 100644 --- a/backend/internal/neosyncdb/integration_test.go +++ b/backend/internal/neosyncdb/integration_test.go @@ -274,6 +274,10 @@ func (s *IntegrationTestSuite) Test_UpsertStripeCustomerId() { }) } +var ( + dbViewerRole = pgtype.Int4{Int32: int32(mgmtv1alpha1.AccountRole_ACCOUNT_ROLE_JOB_VIEWER), Valid: true} +) + func (s *IntegrationTestSuite) Test_CreateTeamAccountInvite() { t := s.T() @@ -282,15 +286,15 @@ func (s *IntegrationTestSuite) Test_CreateTeamAccountInvite() { requireNoErrResp(t, account, err) t.Run("new invite", func(t *testing.T) { - invite, err := s.db.CreateTeamAccountInvite(s.ctx, account.ID, user.ID, "foo2@example.com", getFutureTs(t, 1*time.Hour)) + invite, err := s.db.CreateTeamAccountInvite(s.ctx, account.ID, user.ID, "foo2@example.com", getFutureTs(t, 1*time.Hour), dbViewerRole) requireNoErrResp(t, invite, err) }) t.Run("expire old invites", func(t *testing.T) { - invite, err := s.db.CreateTeamAccountInvite(s.ctx, account.ID, user.ID, "foo2@example.com", getFutureTs(t, 48*time.Hour)) + invite, err := s.db.CreateTeamAccountInvite(s.ctx, account.ID, user.ID, "foo2@example.com", getFutureTs(t, 48*time.Hour), dbViewerRole) requireNoErrResp(t, invite, err) - invite2, err := s.db.CreateTeamAccountInvite(s.ctx, account.ID, user.ID, "foo2@example.com", getFutureTs(t, 48*time.Hour)) + invite2, err := s.db.CreateTeamAccountInvite(s.ctx, account.ID, user.ID, "foo2@example.com", getFutureTs(t, 48*time.Hour), dbViewerRole) requireNoErrResp(t, invite2, err) // Add time here as the expired invites as updated to CURRENT_TIMESTAMP, so this reduces flakiness now := time.Now().Add(5 * time.Second) @@ -304,7 +308,7 @@ func (s *IntegrationTestSuite) Test_CreateTeamAccountInvite() { account, err := s.db.SetPersonalAccount(s.ctx, user.ID, nil) requireNoErrResp(t, account, err) - invite, err := s.db.CreateTeamAccountInvite(s.ctx, account.ID, user.ID, "foo@example.com", getFutureTs(t, 1*time.Hour)) + invite, err := s.db.CreateTeamAccountInvite(s.ctx, account.ID, user.ID, "foo@example.com", getFutureTs(t, 1*time.Hour), dbViewerRole) requireErrResp(t, invite, err) forbiddin := nucleuserrors.NewForbidden("") require.ErrorAs(t, err, &forbiddin) @@ -319,7 +323,7 @@ func (s *IntegrationTestSuite) Test_ValidateInviteAddUserToAccount() { requireNoErrResp(t, account, err) t.Run("accept invite", func(t *testing.T) { - invite, err := s.db.CreateTeamAccountInvite(s.ctx, account.ID, user.ID, "foo2@example.com", getFutureTs(t, 24*time.Hour)) + invite, err := s.db.CreateTeamAccountInvite(s.ctx, account.ID, user.ID, "foo2@example.com", getFutureTs(t, 24*time.Hour), dbViewerRole) requireNoErrResp(t, invite, err) user2 := s.setUser(t, s.ctx, "foo2") @@ -329,27 +333,27 @@ func (s *IntegrationTestSuite) Test_ValidateInviteAddUserToAccount() { }) t.Run("expired invite", func(t *testing.T) { - invite, err := s.db.CreateTeamAccountInvite(s.ctx, account.ID, user.ID, "foo3@example.com", getFutureTs(t, -1*time.Hour)) + invite, err := s.db.CreateTeamAccountInvite(s.ctx, account.ID, user.ID, "foo3@example.com", getFutureTs(t, -1*time.Hour), dbViewerRole) requireNoErrResp(t, invite, err) user3 := s.setUser(t, s.ctx, "foo3") - accountId, err := s.db.ValidateInviteAddUserToAccount(s.ctx, user3.ID, invite.Token, "foo3@example.com") + verifyResp, err := s.db.ValidateInviteAddUserToAccount(s.ctx, user3.ID, invite.Token, "foo3@example.com") require.Error(t, err) - require.False(t, accountId.Valid) + require.Nil(t, verifyResp) forbidden := nucleuserrors.NewForbidden("") require.ErrorAs(t, err, &forbidden) }) t.Run("incorrect email", func(t *testing.T) { - invite, err := s.db.CreateTeamAccountInvite(s.ctx, account.ID, user.ID, "foo4@example.com", getFutureTs(t, -1*time.Hour)) + invite, err := s.db.CreateTeamAccountInvite(s.ctx, account.ID, user.ID, "foo4@example.com", getFutureTs(t, -1*time.Hour), dbViewerRole) requireNoErrResp(t, invite, err) user4 := s.setUser(t, s.ctx, "foo3") - accountId, err := s.db.ValidateInviteAddUserToAccount(s.ctx, user4.ID, invite.Token, "blah@example.com") + verifyResp, err := s.db.ValidateInviteAddUserToAccount(s.ctx, user4.ID, invite.Token, "blah@example.com") require.Error(t, err) - require.False(t, accountId.Valid) + require.Nil(t, verifyResp) badrequest := nucleuserrors.NewBadRequest("") require.ErrorAs(t, err, &badrequest) t.Log(err.Error()) diff --git a/backend/internal/neosyncdb/users.go b/backend/internal/neosyncdb/users.go index 0d7bb4a3d6..8f4f3004c4 100644 --- a/backend/internal/neosyncdb/users.go +++ b/backend/internal/neosyncdb/users.go @@ -11,6 +11,7 @@ import ( "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgtype" db_queries "github.com/nucleuscloud/neosync/backend/gen/go/db" + mgmtv1alpha1 "github.com/nucleuscloud/neosync/backend/gen/go/protos/mgmt/v1alpha1" nucleuserrors "github.com/nucleuscloud/neosync/backend/internal/errors" ) @@ -315,6 +316,7 @@ func (d *NeosyncDb) CreateTeamAccountInvite( userId pgtype.UUID, email string, expiresAt pgtype.Timestamp, + role pgtype.Int4, ) (*db_queries.NeosyncApiAccountInvite, error) { var accountInvite *db_queries.NeosyncApiAccountInvite if err := d.WithTx(ctx, nil, func(dbtx BaseDBTX) error { @@ -341,6 +343,7 @@ func (d *NeosyncDb) CreateTeamAccountInvite( SenderUserID: userId, Email: email, ExpiresAt: expiresAt, + Role: role, }) if err != nil { return err @@ -354,13 +357,19 @@ func (d *NeosyncDb) CreateTeamAccountInvite( return accountInvite, nil } +type ValidateInviteAddUserToAccountResponse struct { + AccountId pgtype.UUID + Role mgmtv1alpha1.AccountRole +} + func (d *NeosyncDb) ValidateInviteAddUserToAccount( ctx context.Context, userId pgtype.UUID, token string, userEmail string, -) (pgtype.UUID, error) { - var accountId pgtype.UUID +) (*ValidateInviteAddUserToAccountResponse, error) { + resp := &ValidateInviteAddUserToAccountResponse{} + if err := d.WithTx(ctx, nil, func(dbtx BaseDBTX) error { invite, err := d.Q.GetAccountInviteByToken(ctx, dbtx, token) if err != nil && !IsNoRows(err) { @@ -377,7 +386,13 @@ func (d *NeosyncDb) ValidateInviteAddUserToAccount( return err } } - accountId = invite.AccountID + resp.AccountId = invite.AccountID + if invite.Role.Valid { + resp.Role = mgmtv1alpha1.AccountRole(invite.Role.Int32) + } else { + resp.Role = mgmtv1alpha1.AccountRole_ACCOUNT_ROLE_JOB_VIEWER + } + _, err = d.Q.GetAccountUserAssociation(ctx, dbtx, db_queries.GetAccountUserAssociationParams{ AccountId: invite.AccountID, UserId: userId, @@ -405,7 +420,7 @@ func (d *NeosyncDb) ValidateInviteAddUserToAccount( } return nil }); err != nil { - return pgtype.UUID{}, err + return nil, err } - return accountId, nil + return resp, nil } diff --git a/backend/internal/userdata/entity_enforcer.go b/backend/internal/userdata/entity_enforcer.go index 827f0d2f6e..23e0d937d8 100644 --- a/backend/internal/userdata/entity_enforcer.go +++ b/backend/internal/userdata/entity_enforcer.go @@ -10,6 +10,7 @@ type UserEntityEnforcer struct { enforcer rbac.EntityEnforcer user rbac.EntityString enforceAccountAccess func(ctx context.Context, accountId string) error + isApiKey bool } var _ EntityEnforcer = (*UserEntityEnforcer)(nil) @@ -28,6 +29,9 @@ func (u *UserEntityEnforcer) EnforceJob(ctx context.Context, job DomainEntity, a if err := u.enforceAccountAccess(ctx, job.GetAccountId()); err != nil { return err } + if u.isApiKey { + return nil + } return u.enforcer.EnforceJob(ctx, u.user, rbac.NewAccountIdEntity(job.GetAccountId()), rbac.NewJobIdEntity(job.GetId()), action) } @@ -35,6 +39,9 @@ func (u *UserEntityEnforcer) EnforceConnection(ctx context.Context, connection D if err := u.enforceAccountAccess(ctx, connection.GetAccountId()); err != nil { return err } + if u.isApiKey { + return nil + } return u.enforcer.EnforceConnection(ctx, u.user, rbac.NewAccountIdEntity(connection.GetAccountId()), rbac.NewConnectionIdEntity(connection.GetId()), action) } @@ -42,5 +49,8 @@ func (u *UserEntityEnforcer) EnforceAccount(ctx context.Context, account Identif if err := u.enforceAccountAccess(ctx, account.GetId()); err != nil { return err } + if u.isApiKey { + return nil + } return u.enforcer.EnforceAccount(ctx, u.user, rbac.NewAccountIdEntity(account.GetId()), action) } diff --git a/backend/protos/mgmt/v1alpha1/user_account.proto b/backend/protos/mgmt/v1alpha1/user_account.proto index 7f18dd5c93..5bcc7f269a 100644 --- a/backend/protos/mgmt/v1alpha1/user_account.proto +++ b/backend/protos/mgmt/v1alpha1/user_account.proto @@ -102,6 +102,8 @@ message AccountUser { string name = 2; string image = 3; string email = 4; + // The role of the user in the account. If RBAC is not enabled, will be unspecified. + AccountRole role = 5; } message GetTeamAccountMembersRequest { @@ -118,8 +120,12 @@ message RemoveTeamAccountMemberRequest { message RemoveTeamAccountMemberResponse {} message InviteUserToTeamAccountRequest { + // The account id to invite the user to string account_id = 1 [(buf.validate.field).string.uuid = true]; + // The email of the user to invite string email = 2 [(buf.validate.field).string.min_len = 1]; + // The role of the user to invite. Only used if RBAC is enabled. + optional AccountRole role = 3; } message AccountInvite { @@ -132,6 +138,8 @@ message AccountInvite { google.protobuf.Timestamp created_at = 7; google.protobuf.Timestamp updated_at = 8; google.protobuf.Timestamp expires_at = 9; + // The role of the user to invite. Only used if RBAC is enabled. + AccountRole role = 10; } message InviteUserToTeamAccountResponse { diff --git a/backend/services/mgmt/v1alpha1/user-account-service/users.go b/backend/services/mgmt/v1alpha1/user-account-service/users.go index 1dff668945..e126300ffd 100644 --- a/backend/services/mgmt/v1alpha1/user-account-service/users.go +++ b/backend/services/mgmt/v1alpha1/user-account-service/users.go @@ -478,6 +478,14 @@ func (s *Service) GetTeamAccountMembers( return nil, err } + rbacUsers := []rbac.EntityString{} + for _, user := range userIdentities { + rbacUsers = append(rbacUsers, rbac.NewPgUserIdEntity(user.UserID)) + } + + userRoles := s.rbacClient.GetUserRoles(ctx, rbacUsers, rbac.NewAccountIdEntity(neosyncdb.UUIDString(accountUuid)), logger) + logger.Debug(fmt.Sprintf("found %d users with roles", len(userRoles))) + dtoUsers := make([]*mgmtv1alpha1.AccountUser, len(userIdentities)) group := new(errgroup.Group) for i := range userIdentities { @@ -487,11 +495,17 @@ func (s *Service) GetTeamAccountMembers( dtoUsers[i] = &mgmtv1alpha1.AccountUser{ Id: neosyncdb.UUIDString(user.UserID), } + role, ok := userRoles[rbac.NewPgUserIdEntity(user.UserID).String()] + if ok { + logger.Debug(fmt.Sprintf("found role for user: %s - %s", neosyncdb.UUIDString(user.UserID), role.String())) + dtoUsers[i].Role = role.ToDto() + } else { + dtoUsers[i].Role = mgmtv1alpha1.AccountRole_ACCOUNT_ROLE_UNSPECIFIED + } if user.ProviderSub == "" { logger.Warn(fmt.Sprintf("unable to find provider sub associated with user id: %q", neosyncdb.UUIDString(user.UserID))) return nil - } - if user.ProviderSub != "" { + } else { authuser, err := s.authadminclient.GetUserBySub(ctx, user.ProviderSub) if err != nil { logger.Warn(fmt.Sprintf("unable to retrieve user by sub: %s", err.Error())) @@ -582,9 +596,12 @@ func (s *Service) InviteUserToTeamAccount( return nil, err } - // todo: this method will need the intended role for the user + var role pgtype.Int4 + if req.Msg.GetRole() != mgmtv1alpha1.AccountRole_ACCOUNT_ROLE_UNSPECIFIED { + role = pgtype.Int4{Int32: int32(req.Msg.GetRole()), Valid: true} + } - invite, err := s.db.CreateTeamAccountInvite(ctx, accountUuid, user.PgId(), req.Msg.GetEmail(), expiresAt) + invite, err := s.db.CreateTeamAccountInvite(ctx, accountUuid, user.PgId(), req.Msg.GetEmail(), expiresAt, role) if err != nil { return nil, err } @@ -679,7 +696,7 @@ func (s *Service) AcceptTeamAccountInvite( if err != nil { return nil, err } - userUuid, err := neosyncdb.ToUuid(user.Msg.UserId) + userUuid, err := neosyncdb.ToUuid(user.Msg.GetUserId()) if err != nil { return nil, err } @@ -710,21 +727,20 @@ func (s *Service) AcceptTeamAccountInvite( return nil, nucleuserrors.NewUnauthenticated("unable to find email to valid to add user to account") } - accountId, err := s.db.ValidateInviteAddUserToAccount(ctx, userUuid, req.Msg.Token, *email) + validateResp, err := s.db.ValidateInviteAddUserToAccount(ctx, userUuid, req.Msg.Token, *email) if err != nil { return nil, err } - // todo: this should be updated to set the intended role based on what was configured in the invite - if err := s.rbacClient.SetAccountRole(ctx, rbac.NewUserIdEntity(user.Msg.GetUserId()), rbac.NewAccountIdEntity(neosyncdb.UUIDString(accountId)), mgmtv1alpha1.AccountRole_ACCOUNT_ROLE_ADMIN); err != nil { + if err := s.rbacClient.SetAccountRole(ctx, rbac.NewUserIdEntity(user.Msg.GetUserId()), rbac.NewAccountIdEntity(neosyncdb.UUIDString(validateResp.AccountId)), validateResp.Role); err != nil { return nil, fmt.Errorf("unable to set account role for user, please reach out to support for further assistance: %w", err) } - if err := s.verifyTeamAccount(ctx, accountId); err != nil { + if err := s.verifyTeamAccount(ctx, validateResp.AccountId); err != nil { return nil, err } - account, err := s.db.Q.GetAccount(ctx, s.db.Db, accountId) + account, err := s.db.Q.GetAccount(ctx, s.db.Db, validateResp.AccountId) if err != nil { return nil, err } diff --git a/backend/sql/postgresql/queries/users.sql b/backend/sql/postgresql/queries/users.sql index 534d4cfcdb..76839bab9c 100644 --- a/backend/sql/postgresql/queries/users.sql +++ b/backend/sql/postgresql/queries/users.sql @@ -164,9 +164,9 @@ WHERE account_id = sqlc.arg('accountId') AND user_id = sqlc.arg('userId'); -- name: CreateAccountInvite :one INSERT INTO neosync_api.account_invites ( - account_id, sender_user_id, email, expires_at + account_id, sender_user_id, email, expires_at, role ) VALUES ( - $1, $2, $3, $4 + $1, $2, $3, $4, $5 ) RETURNING *; diff --git a/backend/sql/postgresql/schema/20241216205042_add-member-invite-role.down.sql b/backend/sql/postgresql/schema/20241216205042_add-member-invite-role.down.sql new file mode 100644 index 0000000000..d838df3922 --- /dev/null +++ b/backend/sql/postgresql/schema/20241216205042_add-member-invite-role.down.sql @@ -0,0 +1 @@ +ALTER TABLE neosync_api.account_invites DROP COLUMN IF EXISTS role; diff --git a/backend/sql/postgresql/schema/20241216205042_add-member-invite-role.up.sql b/backend/sql/postgresql/schema/20241216205042_add-member-invite-role.up.sql new file mode 100644 index 0000000000..cc71619523 --- /dev/null +++ b/backend/sql/postgresql/schema/20241216205042_add-member-invite-role.up.sql @@ -0,0 +1,2 @@ + +ALTER TABLE neosync_api.account_invites ADD COLUMN IF NOT EXISTS role INTEGER DEFAULT NULL; diff --git a/compose.auth.yml b/compose.auth.yml index c1a9237deb..7f51772288 100644 --- a/compose.auth.yml +++ b/compose.auth.yml @@ -31,6 +31,10 @@ services: - AUTH_CLI_AUDIENCE=neosync - AUTH_CLIENTID_SECRET={"neosync-cli":"GkVsthDzDvBfzb2vT4UO95xbXrwoXE5w"} - AUTH_SIGNATURE_ALGORITHM=RS256 + - AUTH_API_CLIENT_ID=neosync-api + - AUTH_API_CLIENT_SECRET=PufiCKGRDISEokPZ9VwB6T86aDKj33f4 + - AUTH_API_BASEURL=http://keycloak:8080/admin/realms/neosync + - AUTH_API_PROVIDER=keycloak networks: - kc-network diff --git a/docs/openapi/mgmt/v1alpha1/user_account.openapi.yaml b/docs/openapi/mgmt/v1alpha1/user_account.openapi.yaml index 21aa9b37a7..ffd80b4140 100644 --- a/docs/openapi/mgmt/v1alpha1/user_account.openapi.yaml +++ b/docs/openapi/mgmt/v1alpha1/user_account.openapi.yaml @@ -1069,6 +1069,11 @@ components: allOf: - title: expires_at - $ref: '#/components/schemas/google.protobuf.Timestamp' + role: + allOf: + - title: role + description: The role of the user to invite. Only used if RBAC is enabled. + - $ref: '#/components/schemas/mgmt.v1alpha1.AccountRole' title: AccountInvite additionalProperties: false mgmt.v1alpha1.AccountOnboardingConfig: @@ -1127,6 +1132,11 @@ components: email: type: string title: email + role: + allOf: + - title: role + description: The role of the user in the account. If RBAC is not enabled, will be unspecified. + - $ref: '#/components/schemas/mgmt.v1alpha1.AccountRole' title: AccountUser additionalProperties: false mgmt.v1alpha1.ConvertPersonalToTeamAccountRequest: @@ -1466,15 +1476,37 @@ components: additionalProperties: false mgmt.v1alpha1.InviteUserToTeamAccountRequest: type: object + allOf: + - anyOf: + - required: + - role + - not: + anyOf: + - required: + - role + anyOf: + - required: + - role + - not: + anyOf: + - required: + - role properties: accountId: type: string title: account_id format: uuid + description: The account id to invite the user to email: type: string title: email minLength: 1 + description: The email of the user to invite + role: + allOf: + - title: role + description: The role of the user to invite. Only used if RBAC is enabled. + - $ref: '#/components/schemas/mgmt.v1alpha1.AccountRole' title: InviteUserToTeamAccountRequest additionalProperties: false mgmt.v1alpha1.InviteUserToTeamAccountResponse: diff --git a/docs/openapi/neosync.mgmt.v1alpha1.yaml b/docs/openapi/neosync.mgmt.v1alpha1.yaml index 59dba30864..e6dc2eef68 100644 --- a/docs/openapi/neosync.mgmt.v1alpha1.yaml +++ b/docs/openapi/neosync.mgmt.v1alpha1.yaml @@ -12380,6 +12380,11 @@ components: allOf: - title: expires_at - $ref: '#/components/schemas/google.protobuf.Timestamp' + role: + allOf: + - title: role + description: The role of the user to invite. Only used if RBAC is enabled. + - $ref: '#/components/schemas/mgmt.v1alpha1.AccountRole' title: AccountInvite additionalProperties: false mgmt.v1alpha1.AccountOnboardingConfig: @@ -12438,6 +12443,13 @@ components: email: type: string title: email + role: + allOf: + - title: role + description: >- + The role of the user in the account. If RBAC is not enabled, + will be unspecified. + - $ref: '#/components/schemas/mgmt.v1alpha1.AccountRole' title: AccountUser additionalProperties: false mgmt.v1alpha1.ConvertPersonalToTeamAccountRequest: @@ -12787,15 +12799,37 @@ components: additionalProperties: false mgmt.v1alpha1.InviteUserToTeamAccountRequest: type: object + allOf: + - anyOf: + - required: + - role + - not: + anyOf: + - required: + - role + anyOf: + - required: + - role + - not: + anyOf: + - required: + - role properties: accountId: type: string title: account_id format: uuid + description: The account id to invite the user to email: type: string title: email minLength: 1 + description: The email of the user to invite + role: + allOf: + - title: role + description: The role of the user to invite. Only used if RBAC is enabled. + - $ref: '#/components/schemas/mgmt.v1alpha1.AccountRole' title: InviteUserToTeamAccountRequest additionalProperties: false mgmt.v1alpha1.InviteUserToTeamAccountResponse: diff --git a/docs/protos/mgmt/v1alpha1/user_account.proto.mdx b/docs/protos/mgmt/v1alpha1/user_account.proto.mdx index 393fd9277d..07676f6e6a 100644 --- a/docs/protos/mgmt/v1alpha1/user_account.proto.mdx +++ b/docs/protos/mgmt/v1alpha1/user_account.proto.mdx @@ -26,7 +26,7 @@ _**package** mgmt.v1alpha1_ ### `AccountInvite` - + ### `AccountOnboardingConfig` @@ -38,7 +38,7 @@ _**package** mgmt.v1alpha1_ ### `AccountUser` - + ### `ConvertPersonalToTeamAccountRequest` @@ -146,7 +146,7 @@ _**package** mgmt.v1alpha1_ ### `InviteUserToTeamAccountRequest` - + ### `InviteUserToTeamAccountResponse` diff --git a/docs/protos/proto_docs.json b/docs/protos/proto_docs.json index ece92cc186..10613ca1e8 100644 --- a/docs/protos/proto_docs.json +++ b/docs/protos/proto_docs.json @@ -15990,6 +15990,18 @@ "isoneof": false, "oneofdecl": "", "defaultValue": "" + }, + { + "name": "role", + "description": "The role of the user to invite. Only used if RBAC is enabled.", + "label": "", + "type": "AccountRole", + "longType": "AccountRole", + "fullType": "mgmt.v1alpha1.AccountRole", + "ismap": false, + "isoneof": false, + "oneofdecl": "", + "defaultValue": "" } ] }, @@ -16170,6 +16182,18 @@ "isoneof": false, "oneofdecl": "", "defaultValue": "" + }, + { + "name": "role", + "description": "The role of the user in the account. If RBAC is not enabled, will be unspecified.", + "label": "", + "type": "AccountRole", + "longType": "AccountRole", + "fullType": "mgmt.v1alpha1.AccountRole", + "ismap": false, + "isoneof": false, + "oneofdecl": "", + "defaultValue": "" } ] }, @@ -16885,12 +16909,12 @@ "description": "", "hasExtensions": false, "hasFields": true, - "hasOneofs": false, + "hasOneofs": true, "extensions": [], "fields": [ { "name": "account_id", - "description": "", + "description": "The account id to invite the user to", "label": "", "type": "string", "longType": "string", @@ -16902,7 +16926,7 @@ }, { "name": "email", - "description": "", + "description": "The email of the user to invite", "label": "", "type": "string", "longType": "string", @@ -16911,6 +16935,18 @@ "isoneof": false, "oneofdecl": "", "defaultValue": "" + }, + { + "name": "role", + "description": "The role of the user to invite. Only used if RBAC is enabled.", + "label": "optional", + "type": "AccountRole", + "longType": "AccountRole", + "fullType": "mgmt.v1alpha1.AccountRole", + "ismap": false, + "isoneof": true, + "oneofdecl": "_role", + "defaultValue": "" } ] }, diff --git a/frontend/apps/web/app/(mgmt)/[account]/jobs/[id]/hooks/components/stores.ts b/frontend/apps/web/app/(mgmt)/[account]/jobs/[id]/hooks/components/stores.ts index cbd92e5bae..ae7a837023 100644 --- a/frontend/apps/web/app/(mgmt)/[account]/jobs/[id]/hooks/components/stores.ts +++ b/frontend/apps/web/app/(mgmt)/[account]/jobs/[id]/hooks/components/stores.ts @@ -1,19 +1,7 @@ +import { BaseHookStore } from '@/util/zustand.stores.util'; import { create } from 'zustand'; import { EditJobHookFormValues, NewJobHookFormValues } from './validation'; -type FieldValues = Record; // eslint-disable-line @typescript-eslint/no-explicit-any -type FieldErrors = Record; // todo: make this type safe - -interface BaseHookStore { - formData: T; - errors: FieldErrors; - isSubmitting: boolean; - setFormData(data: Partial): void; - setErrors(errors: Record): void; - setSubmitting(isSubmitting: boolean): void; - resetForm(): void; -} - function getInitialEditFormState(): EditJobHookFormValues { return { hookType: 'sql', diff --git a/frontend/apps/web/app/(mgmt)/[account]/settings/members/components/InviteTable.tsx b/frontend/apps/web/app/(mgmt)/[account]/settings/members/components/InviteTable.tsx index 61b10ca8fe..c31008b29f 100644 --- a/frontend/apps/web/app/(mgmt)/[account]/settings/members/components/InviteTable.tsx +++ b/frontend/apps/web/app/(mgmt)/[account]/settings/members/components/InviteTable.tsx @@ -3,8 +3,10 @@ import { ColumnDef, ColumnFiltersState, + RowData, SortingState, VisibilityState, + createColumnHelper, flexRender, getCoreRowModel, getFilteredRowModel, @@ -12,7 +14,6 @@ import { getSortedRowModel, useReactTable, } from '@tanstack/react-table'; -import * as React from 'react'; import { CopyButton } from '@/components/CopyButton'; import DeleteConfirmationDialog from '@/components/DeleteConfirmationDialog'; @@ -28,108 +29,160 @@ import { TableRow, } from '@/components/ui/table'; import { useGetSystemAppConfig } from '@/libs/hooks/useGetSystemAppConfig'; -import { formatDateTime, getErrorMessage } from '@/util/util'; -import { PlainMessage, Timestamp } from '@bufbuild/protobuf'; +import { + formatDateTime, + getAccountRoleString, + getErrorMessage, +} from '@/util/util'; import { useMutation, useQuery } from '@connectrpc/connect-query'; -import { AccountInvite } from '@neosync/sdk'; +import { AccountRole } from '@neosync/sdk'; import { getTeamAccountInvites, removeTeamAccountInvite, } from '@neosync/sdk/connectquery'; import { TrashIcon } from '@radix-ui/react-icons'; +import { useMemo, useState } from 'react'; import { toast } from 'sonner'; import { buildInviteLink } from './InviteUserForm'; -interface ColumnProps { - onDeleted(id: string): void; +interface MemberInviteRow { + id: string; + email: string; + createdAt: Date; + expiresAt: Date; + token: string; + role: AccountRole; } -function getColumns( - props: ColumnProps -): ColumnDef>[] { - const { onDeleted } = props; - return [ - { - accessorKey: 'email', - header: 'Email', - cell: ({ row }) =>
{row.getValue('email')}
, - }, - { - accessorKey: 'createdAt', - header: 'Created At', - cell: ({ row }) => { - return ( -
- - {formatDateTime(row.getValue('createdAt')?.toDate())} - -
- ); - }, +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function getColumns(isRbacEnabled: boolean): ColumnDef[] { + const columnHelper = createColumnHelper(); + const emailColumn = columnHelper.accessor('email', { + header: 'Email', + cell: ({ getValue }) =>
{getValue()}
, + }); + + const createdAtColumn = columnHelper.accessor('createdAt', { + header: 'Created At', + cell: ({ getValue }) => { + return
{formatDateTime(getValue())}
; }, - { - accessorKey: 'expiresAt', - header: 'Expires At', - cell: ({ row }) => { - return ( -
- - {formatDateTime(row.getValue('expiresAt')?.toDate())} - -
- ); - }, + }); + + const expiresAtColumn = columnHelper.accessor('expiresAt', { + header: 'Expires At', + cell: ({ getValue }) => { + return
{formatDateTime(getValue())}
; }, - { - id: 'actions', - cell: ({ row }) => { - return ( -
- - -
- ); - }, + }); + + const roleColumn = columnHelper.accessor('role', { + header: 'Role', + cell: ({ getValue }) => ( + + {getAccountRoleString(getValue())} + + ), + }); + + const actionsColumn = columnHelper.display({ + id: 'actions', + cell: ({ row, table }) => { + return ( +
+ + + table.options.meta?.invitesTable?.onDeleted(row.original.id) + } + inviteId={row.original.id} + /> +
+ ); }, - ]; + }); + + if (isRbacEnabled) { + return [ + emailColumn, + createdAtColumn, + expiresAtColumn, + roleColumn, + actionsColumn, + ]; + } + + return [emailColumn, createdAtColumn, expiresAtColumn, actionsColumn]; +} + +function useGetColumns(): ColumnDef[] { + const { data: config } = useGetSystemAppConfig(); + const isRbacEnabled = config?.isRbacEnabled ?? false; + return useMemo(() => { + return getColumns(isRbacEnabled); + }, [isRbacEnabled]); } interface Props { accountId: string; } -export function InvitesTable(props: Props) { +export function InvitesTable(props: Props): React.ReactElement { const { accountId } = props; - const { data, isLoading, refetch } = useQuery( + const { data, isLoading, refetch, isFetching } = useQuery( getTeamAccountInvites, { accountId: accountId }, { enabled: !!accountId } ); + const invites = data?.invites || []; + const invitesRows = useMemo(() => { + return invites.map((invite): MemberInviteRow => { + return { + id: invite.id, + email: invite.email, + createdAt: invite.createdAt?.toDate() ?? new Date(), + expiresAt: invite.expiresAt?.toDate() ?? new Date(), + token: invite.token, + role: invite.role, + }; + }); + }, [isFetching, invites]); + + const columns = useGetColumns(); + if (isLoading) { return ; } - return refetch()} />; + return ( + refetch()} + /> + ); +} + +declare module '@tanstack/react-table' { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + interface TableMeta { + invitesTable?: { + onDeleted(id: string): void; + }; + } } interface DataTableProps { - data: AccountInvite[]; + data: MemberInviteRow[]; + columns: ColumnDef[]; onDeleted(id: string): void; } function DataTable(props: DataTableProps): React.ReactElement { - const { data, onDeleted } = props; - const [sorting, setSorting] = React.useState([]); - const [columnFilters, setColumnFilters] = React.useState( - [] - ); - const [columnVisibility, setColumnVisibility] = - React.useState({}); - const [rowSelection, setRowSelection] = React.useState({}); - - const columns = React.useMemo(() => getColumns({ onDeleted }), []); + const { data, columns, onDeleted } = props; + const [sorting, setSorting] = useState([]); + const [columnFilters, setColumnFilters] = useState([]); + const [columnVisibility, setColumnVisibility] = useState({}); + const [rowSelection, setRowSelection] = useState({}); const table = useReactTable({ data, @@ -148,6 +201,11 @@ function DataTable(props: DataTableProps): React.ReactElement { columnVisibility, rowSelection, }, + meta: { + invitesTable: { + onDeleted, + }, + }, }); return ( diff --git a/frontend/apps/web/app/(mgmt)/[account]/settings/members/components/InviteUserForm.tsx b/frontend/apps/web/app/(mgmt)/[account]/settings/members/components/InviteUserForm.tsx index 66eccb1e59..ecf684f561 100644 --- a/frontend/apps/web/app/(mgmt)/[account]/settings/members/components/InviteUserForm.tsx +++ b/frontend/apps/web/app/(mgmt)/[account]/settings/members/components/InviteUserForm.tsx @@ -15,8 +15,10 @@ import { import { Form, FormControl, + FormDescription, FormField, FormItem, + FormLabel, FormMessage, } from '@/components/ui/form'; import { Input } from '@/components/ui/input'; @@ -25,12 +27,14 @@ import { getErrorMessage } from '@/util/util'; import { InviteMembersForm } from '@/yup-validations/invite-members'; import { useMutation } from '@connectrpc/connect-query'; import { yupResolver } from '@hookform/resolvers/yup'; +import { AccountRole } from '@neosync/sdk'; import { inviteUserToTeamAccount } from '@neosync/sdk/connectquery'; import { DialogClose } from '@radix-ui/react-dialog'; import { PlusIcon } from '@radix-ui/react-icons'; import { ReactElement, useState } from 'react'; import { useForm } from 'react-hook-form'; import { toast } from 'sonner'; +import SelectAccountRole from './SelectAccountRole'; interface Props { accountId: string; @@ -38,6 +42,8 @@ interface Props { } export default function InviteUserForm(props: Props): ReactElement { const { accountId, onInvited } = props; + const { data: systemAppData } = useGetSystemAppConfig(); + const isRbacEnabled = systemAppData?.isRbacEnabled ?? false; const [showNewInviteDialog, setShowNewinviteDialog] = useState(false); const [newInviteToken, setNewInviteToken] = useState(''); const [openInviteCreated, setOpenInviteCreated] = useState(false); @@ -46,6 +52,7 @@ export default function InviteUserForm(props: Props): ReactElement { resolver: yupResolver(InviteMembersForm), defaultValues: { email: '', + role: AccountRole.JOB_VIEWER, }, }); const { mutateAsync } = useMutation(inviteUserToTeamAccount); @@ -55,6 +62,7 @@ export default function InviteUserForm(props: Props): ReactElement { const invite = await mutateAsync({ accountId: accountId, email: values.email, + role: values.role, }); setShowNewinviteDialog(false); if (invite?.invite?.token) { @@ -89,16 +97,20 @@ export default function InviteUserForm(props: Props): ReactElement { Add new member - Invite members with their email. + Invite a new member to your account.
- + ( + Email + + The email of the user that will be invited. + )} /> + {isRbacEnabled && ( + ( + + Role + + The role of the user that will be invited. + + + + + + + )} + /> + )} + + + + + ); +} + +interface AccountRoleFieldProps { + error?: string; + value: AccountRole; + onChange(value: AccountRole): void; +} +function AccountRoleField(props: AccountRoleFieldProps): ReactElement { + const { error, value, onChange } = props; + + return ( +
+ + onChange(role)} /> + +
+ ); +} diff --git a/frontend/apps/web/app/api/config/config.ts b/frontend/apps/web/app/api/config/config.ts index ef393a9db5..25b540e797 100644 --- a/frontend/apps/web/app/api/config/config.ts +++ b/frontend/apps/web/app/api/config/config.ts @@ -8,6 +8,7 @@ export const PUBLIC_PATHNAME = '/api/neosync'; // This only seems to be an issue with the root layout.tsx, where as all sub pages cause a re-render of the root layout // which causes them to be their correct values. However, if navigating to "/", the root layout isn't re-rendered and is given the defaults. export function getSystemAppConfig(): SystemAppConfig { + const isNeosyncCloud = process.env.NEOSYNC_CLOUD === 'true'; return { isAuthEnabled: process.env.AUTH_ENABLED === 'true', publicAppBaseUrl: @@ -21,7 +22,7 @@ export function getSystemAppConfig(): SystemAppConfig { enabled: isAnalyticsEnabled() && !!process.env.KOALA_KEY, key: process.env.KOALA_KEY, }, - isNeosyncCloud: process.env.NEOSYNC_CLOUD === 'true', + isNeosyncCloud, isStripeEnabled: process.env.STRIPE_ENABLED === 'true', enableRunLogs: process.env.ENABLE_RUN_LOGS === 'true', signInProviderId: process.env.AUTH_PROVIDER_ID, @@ -35,6 +36,7 @@ export function getSystemAppConfig(): SystemAppConfig { process.env.NEOSYNC_API_BASE_URL ?? 'http://localhost:8080', publicNeosyncApiBaseUrl: PUBLIC_PATHNAME, // ensures that this always points to the same domain isJobHooksEnabled: process.env.JOBHOOKS_ENABLED === 'true', + isRbacEnabled: isNeosyncCloud || process.env.RBAC_ENABLED === 'true', }; } diff --git a/frontend/apps/web/app/config/app-config.ts b/frontend/apps/web/app/config/app-config.ts index 6c150f5a0a..84969e2e76 100644 --- a/frontend/apps/web/app/config/app-config.ts +++ b/frontend/apps/web/app/config/app-config.ts @@ -18,6 +18,7 @@ export interface SystemAppConfig { neosyncApiBaseUrl: string; // public (client-side) base url; publicNeosyncApiBaseUrl: string; + isRbacEnabled: boolean; } interface PosthogConfig { diff --git a/frontend/apps/web/components/jobs/JobMappingTable/Columns.tsx b/frontend/apps/web/components/jobs/JobMappingTable/Columns.tsx index 3e6d865a4e..1f570283a2 100644 --- a/frontend/apps/web/components/jobs/JobMappingTable/Columns.tsx +++ b/frontend/apps/web/components/jobs/JobMappingTable/Columns.tsx @@ -189,7 +189,7 @@ function getJobMappingColumns(): ColumnDef[] { }, cell({ table, row }) { const transformer = - table.options.meta?.getTransformerFromField(row.index) ?? + table.options.meta?.jmTable?.getTransformerFromField(row.index) ?? new SystemTransformer(); const transformerForm = row.original.transformer; return ( @@ -197,7 +197,9 @@ function getJobMappingColumns(): ColumnDef[] {
- table.options.meta?.getAvailableTransformers(row.index) ?? { + table.options.meta?.jmTable?.getAvailableTransformers( + row.index + ) ?? { system: [], userDefined: [], } @@ -206,7 +208,7 @@ function getJobMappingColumns(): ColumnDef[] { buttonClassName="w-[140px]" value={transformerForm} onSelect={(updatedValue) => - table.options.meta?.onTransformerUpdate( + table.options.meta?.jmTable?.onTransformerUpdate( row.index, updatedValue ) @@ -219,7 +221,7 @@ function getJobMappingColumns(): ColumnDef[] { transformer={transformer} value={transformerForm} onSubmit={(updatedValue) => { - table.options.meta?.onTransformerUpdate( + table.options.meta?.jmTable?.onTransformerUpdate( row.index, updatedValue ); @@ -304,11 +306,13 @@ function getNosqlJobMappingColumns(): ColumnDef[] { { - if (table.options.meta?.onRowUpdate) { - table.options.meta.onRowUpdate(row.index, { + if (table.options.meta?.jmTable?.onRowUpdate) { + table.options.meta.jmTable.onRowUpdate(row.index, { ...row.original, collection: updatedValue.collection, }); @@ -330,13 +334,16 @@ function getNosqlJobMappingColumns(): ColumnDef[] { isDuplicate={(newValue, currValue) => { return ( newValue !== currValue && - (table.options.meta?.canRenameColumn(row.index, newValue) ?? + (table.options.meta?.jmTable?.canRenameColumn( + row.index, + newValue + ) ?? false) ); }} onEdit={(updatedValue) => { - if (table.options.meta?.onRowUpdate) { - table.options.meta.onRowUpdate(row.index, { + if (table.options.meta?.jmTable?.onRowUpdate) { + table.options.meta.jmTable.onRowUpdate(row.index, { ...row.original, column: updatedValue.column, }); @@ -362,7 +369,7 @@ function getNosqlJobMappingColumns(): ColumnDef[] { }, cell({ table, row }) { const transformer = - table.options.meta?.getTransformerFromField(row.index) ?? + table.options.meta?.jmTable?.getTransformerFromField(row.index) ?? new SystemTransformer(); const transformerForm = row.original.transformer; return ( @@ -370,7 +377,9 @@ function getNosqlJobMappingColumns(): ColumnDef[] {
- table.options.meta?.getAvailableTransformers(row.index) ?? { + table.options.meta?.jmTable?.getAvailableTransformers( + row.index + ) ?? { system: [], userDefined: [], } @@ -379,7 +388,7 @@ function getNosqlJobMappingColumns(): ColumnDef[] { buttonClassName="w-[175px]" value={transformerForm} onSelect={(updatedValue) => - table.options.meta?.onTransformerUpdate( + table.options.meta?.jmTable?.onTransformerUpdate( row.index, updatedValue ) @@ -392,7 +401,7 @@ function getNosqlJobMappingColumns(): ColumnDef[] { transformer={transformer} value={transformerForm} onSubmit={(updatedValue) => { - table.options.meta?.onTransformerUpdate( + table.options.meta?.jmTable?.onTransformerUpdate( row.index, updatedValue ); @@ -416,8 +425,10 @@ function getNosqlJobMappingColumns(): ColumnDef[] { return ( table.options.meta?.onDuplicateRow(row.index)} - onDelete={() => table.options.meta?.onDeleteRow(row.index)} + onDuplicate={() => + table.options.meta?.jmTable?.onDuplicateRow(row.index) + } + onDelete={() => table.options.meta?.jmTable?.onDeleteRow(row.index)} /> ); }, diff --git a/frontend/apps/web/components/jobs/JobMappingTable/JobMappingTable.tsx b/frontend/apps/web/components/jobs/JobMappingTable/JobMappingTable.tsx index 2fb658caa1..9780fc9e1e 100644 --- a/frontend/apps/web/components/jobs/JobMappingTable/JobMappingTable.tsx +++ b/frontend/apps/web/components/jobs/JobMappingTable/JobMappingTable.tsx @@ -60,19 +60,21 @@ interface Props { declare module '@tanstack/react-table' { interface TableMeta { - onTransformerUpdate( - rowIndex: number, - transformer: JobMappingTransformerForm - ): void; - getAvailableTransformers(rowIndex: number): TransformerResult; - getTransformerFromField(index: number): Transformer; + jmTable?: { + onTransformerUpdate( + rowIndex: number, + transformer: JobMappingTransformerForm + ): void; + getAvailableTransformers(rowIndex: number): TransformerResult; + getTransformerFromField(index: number): Transformer; - onDuplicateRow(rowIndex: number): void; - onDeleteRow(rowIndex: number): void; - canRenameColumn(rowIndex: number, newColumn: string): boolean; - onRowUpdate(rowIndex: number, newValue: TData): void; - // Returns the available schema.table list - getAvailableCollectionsByRow(rowIndex: number): string[]; + onDuplicateRow(rowIndex: number): void; + onDeleteRow(rowIndex: number): void; + canRenameColumn(rowIndex: number, newColumn: string): boolean; + onRowUpdate(rowIndex: number, newValue: TData): void; + // Returns the available schema.table list + getAvailableCollectionsByRow(rowIndex: number): string[]; + }; } } @@ -106,14 +108,16 @@ export default function JobMappingTable( getSortedRowModel: getSortedRowModel(), getFilteredRowModel: getFilteredRowModel(), meta: { - onTransformerUpdate: onTransformerUpdate, - getAvailableTransformers: getAvailableTransformers, - getTransformerFromField: getTransformerFromField, - onDeleteRow, - onDuplicateRow, - canRenameColumn, - onRowUpdate, - getAvailableCollectionsByRow, + jmTable: { + onTransformerUpdate, + getAvailableTransformers, + getTransformerFromField, + onDeleteRow, + onDuplicateRow, + canRenameColumn, + onRowUpdate, + getAvailableCollectionsByRow, + }, }, }); diff --git a/frontend/apps/web/util/util.ts b/frontend/apps/web/util/util.ts index 50cae189dc..8277afaae5 100644 --- a/frontend/apps/web/util/util.ts +++ b/frontend/apps/web/util/util.ts @@ -2,6 +2,7 @@ import { TransformerHandler } from '@/components/jobs/SchemaTable/transformer-ha import { Transformer } from '@/shared/transformers'; import { JobMappingTransformerForm } from '@/yup-validations/jobs'; import { + AccountRole, AwsS3DestinationConnectionOptions_StorageClass, GenerateEmailType, GenerateIpAddressType, @@ -140,6 +141,11 @@ export function getInvalidEmailActionString( return value ? value.toLowerCase() : 'unknown'; } +export function getAccountRoleString(role: AccountRole): string { + const value = AccountRole[role]; + return value ? value.toLowerCase() : 'unknown'; +} + export function getStorageClassString( storageclass: AwsS3DestinationConnectionOptions_StorageClass ): string { diff --git a/frontend/apps/web/util/zustand.stores.util.ts b/frontend/apps/web/util/zustand.stores.util.ts new file mode 100644 index 0000000000..989c002b1c --- /dev/null +++ b/frontend/apps/web/util/zustand.stores.util.ts @@ -0,0 +1,12 @@ +type FieldValues = Record; // eslint-disable-line @typescript-eslint/no-explicit-any +type FieldErrors = Record; // todo: make this type safe + +export interface BaseHookStore { + formData: T; + errors: FieldErrors; + isSubmitting: boolean; + setFormData(data: Partial): void; + setErrors(errors: Record): void; + setSubmitting(isSubmitting: boolean): void; + resetForm(): void; +} diff --git a/frontend/apps/web/yup-validations/invite-members.ts b/frontend/apps/web/yup-validations/invite-members.ts index d11ed8e330..3ba1e91072 100644 --- a/frontend/apps/web/yup-validations/invite-members.ts +++ b/frontend/apps/web/yup-validations/invite-members.ts @@ -1,7 +1,18 @@ import * as Yup from 'yup'; +const RoleFormValue = Yup.number().required('The Role is required'); + export const InviteMembersForm = Yup.object({ email: Yup.string().email().required('The Email is required'), + role: RoleFormValue, }); export type InviteMembersForm = Yup.InferType; + +export const UpdateMemberRoleFormValues = Yup.object({ + role: RoleFormValue, +}); + +export type UpdateMemberRoleFormValues = Yup.InferType< + typeof UpdateMemberRoleFormValues +>; diff --git a/frontend/packages/sdk/src/client/mgmt/v1alpha1/user_account_pb.ts b/frontend/packages/sdk/src/client/mgmt/v1alpha1/user_account_pb.ts index bc232ea774..0b3b5b56a8 100644 --- a/frontend/packages/sdk/src/client/mgmt/v1alpha1/user_account_pb.ts +++ b/frontend/packages/sdk/src/client/mgmt/v1alpha1/user_account_pb.ts @@ -1012,6 +1012,13 @@ export class AccountUser extends Message { */ email = ""; + /** + * The role of the user in the account. If RBAC is not enabled, will be unspecified. + * + * @generated from field: mgmt.v1alpha1.AccountRole role = 5; + */ + role = AccountRole.UNSPECIFIED; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -1024,6 +1031,7 @@ export class AccountUser extends Message { { no: 2, name: "name", kind: "scalar", T: 9 /* ScalarType.STRING */ }, { no: 3, name: "image", kind: "scalar", T: 9 /* ScalarType.STRING */ }, { no: 4, name: "email", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 5, name: "role", kind: "enum", T: proto3.getEnumType(AccountRole) }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): AccountUser { @@ -1196,15 +1204,26 @@ export class RemoveTeamAccountMemberResponse extends Message { /** + * The account id to invite the user to + * * @generated from field: string account_id = 1; */ accountId = ""; /** + * The email of the user to invite + * * @generated from field: string email = 2; */ email = ""; + /** + * The role of the user to invite. Only used if RBAC is enabled. + * + * @generated from field: optional mgmt.v1alpha1.AccountRole role = 3; + */ + role?: AccountRole; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -1215,6 +1234,7 @@ export class InviteUserToTeamAccountRequest extends Message [ { no: 1, name: "account_id", kind: "scalar", T: 9 /* ScalarType.STRING */ }, { no: 2, name: "email", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 3, name: "role", kind: "enum", T: proto3.getEnumType(AccountRole), opt: true }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): InviteUserToTeamAccountRequest { @@ -1283,6 +1303,13 @@ export class AccountInvite extends Message { */ expiresAt?: Timestamp; + /** + * The role of the user to invite. Only used if RBAC is enabled. + * + * @generated from field: mgmt.v1alpha1.AccountRole role = 10; + */ + role = AccountRole.UNSPECIFIED; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -1300,6 +1327,7 @@ export class AccountInvite extends Message { { no: 7, name: "created_at", kind: "message", T: Timestamp }, { no: 8, name: "updated_at", kind: "message", T: Timestamp }, { no: 9, name: "expires_at", kind: "message", T: Timestamp }, + { no: 10, name: "role", kind: "enum", T: proto3.getEnumType(AccountRole) }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): AccountInvite { diff --git a/keycloak/imports/neosync.json b/keycloak/imports/neosync.json index 82c98aa8ac..b22b62db38 100644 --- a/keycloak/imports/neosync.json +++ b/keycloak/imports/neosync.json @@ -37,12 +37,299 @@ "editUsernameAllowed": false, "bruteForceProtected": false, "permanentLockout": false, + "maxTemporaryLockouts": 0, "maxFailureWaitSeconds": 900, "minimumQuickLoginWaitSeconds": 60, "waitIncrementSeconds": 60, "quickLoginCheckMilliSeconds": 1000, "maxDeltaTimeSeconds": 43200, "failureFactor": 30, + "roles": { + "realm": [ + { + "id": "a3b4c234-3add-472a-9faa-d0e92c385d8b", + "name": "default-roles-neosync", + "description": "${role_default-roles}", + "composite": true, + "composites": { + "realm": [ + "offline_access", + "uma_authorization" + ] + }, + "clientRole": false, + "containerId": "23ab91d5-7f02-46c4-b48f-91e7ef91bc09", + "attributes": {} + }, + { + "id": "4d037417-d50e-4e53-b7a1-a71bc72ba9c1", + "name": "offline_access", + "description": "${role_offline-access}", + "composite": false, + "clientRole": false, + "containerId": "23ab91d5-7f02-46c4-b48f-91e7ef91bc09", + "attributes": {} + }, + { + "id": "db33e524-a6d1-4a7d-93d8-2bad6e0086e2", + "name": "uma_authorization", + "description": "${role_uma_authorization}", + "composite": false, + "clientRole": false, + "containerId": "23ab91d5-7f02-46c4-b48f-91e7ef91bc09", + "attributes": {} + } + ], + "client": { + "neosync-api": [], + "realm-management": [ + { + "id": "3f63c376-77c7-4160-8ddb-96a6623f10d2", + "name": "view-authorization", + "description": "${role_view-authorization}", + "composite": false, + "clientRole": true, + "containerId": "a8395b5e-b8a8-4e45-a021-824927a0d696", + "attributes": {} + }, + { + "id": "c47a82d4-5513-40f0-a64e-f29582079ad9", + "name": "create-client", + "description": "${role_create-client}", + "composite": false, + "clientRole": true, + "containerId": "a8395b5e-b8a8-4e45-a021-824927a0d696", + "attributes": {} + }, + { + "id": "11b6063f-a125-49b3-84eb-61788ddf0fe0", + "name": "view-events", + "description": "${role_view-events}", + "composite": false, + "clientRole": true, + "containerId": "a8395b5e-b8a8-4e45-a021-824927a0d696", + "attributes": {} + }, + { + "id": "2163b58d-0d14-4d34-8e0b-4192f7724acf", + "name": "manage-users", + "description": "${role_manage-users}", + "composite": false, + "clientRole": true, + "containerId": "a8395b5e-b8a8-4e45-a021-824927a0d696", + "attributes": {} + }, + { + "id": "07b671e7-e9e6-480a-b549-6c7733f44d03", + "name": "impersonation", + "description": "${role_impersonation}", + "composite": false, + "clientRole": true, + "containerId": "a8395b5e-b8a8-4e45-a021-824927a0d696", + "attributes": {} + }, + { + "id": "2d4611bc-7abf-482d-ba66-bf4fbd9a2362", + "name": "query-users", + "description": "${role_query-users}", + "composite": false, + "clientRole": true, + "containerId": "a8395b5e-b8a8-4e45-a021-824927a0d696", + "attributes": {} + }, + { + "id": "d1d640db-238c-4118-a998-6a1891a63bf5", + "name": "view-users", + "description": "${role_view-users}", + "composite": true, + "composites": { + "client": { + "realm-management": [ + "query-users", + "query-groups" + ] + } + }, + "clientRole": true, + "containerId": "a8395b5e-b8a8-4e45-a021-824927a0d696", + "attributes": {} + }, + { + "id": "6740555f-f8fc-4417-8380-f297d0e185e6", + "name": "query-realms", + "description": "${role_query-realms}", + "composite": false, + "clientRole": true, + "containerId": "a8395b5e-b8a8-4e45-a021-824927a0d696", + "attributes": {} + }, + { + "id": "2d2caeff-6756-406c-b337-9ee2208ba6fb", + "name": "view-identity-providers", + "description": "${role_view-identity-providers}", + "composite": false, + "clientRole": true, + "containerId": "a8395b5e-b8a8-4e45-a021-824927a0d696", + "attributes": {} + }, + { + "id": "2abaeff8-5207-4470-afdc-94059ab5fcae", + "name": "realm-admin", + "description": "${role_realm-admin}", + "composite": true, + "composites": { + "client": { + "realm-management": [ + "view-authorization", + "view-events", + "create-client", + "manage-users", + "impersonation", + "view-users", + "query-users", + "view-identity-providers", + "query-realms", + "view-realm", + "query-groups", + "manage-realm", + "manage-clients", + "manage-events", + "query-clients", + "view-clients", + "manage-identity-providers", + "manage-authorization" + ] + } + }, + "clientRole": true, + "containerId": "a8395b5e-b8a8-4e45-a021-824927a0d696", + "attributes": {} + }, + { + "id": "b4147a2d-39b1-43fb-bd01-757b8125be8e", + "name": "view-realm", + "description": "${role_view-realm}", + "composite": false, + "clientRole": true, + "containerId": "a8395b5e-b8a8-4e45-a021-824927a0d696", + "attributes": {} + }, + { + "id": "8eb9b48c-1492-44c5-aa21-1231cd91dea6", + "name": "query-groups", + "description": "${role_query-groups}", + "composite": false, + "clientRole": true, + "containerId": "a8395b5e-b8a8-4e45-a021-824927a0d696", + "attributes": {} + }, + { + "id": "c68aae31-abfb-4e38-ae46-578d7a125f94", + "name": "manage-realm", + "description": "${role_manage-realm}", + "composite": false, + "clientRole": true, + "containerId": "a8395b5e-b8a8-4e45-a021-824927a0d696", + "attributes": {} + }, + { + "id": "13df2fcb-06d8-4941-b2f6-d675d28b782b", + "name": "manage-clients", + "description": "${role_manage-clients}", + "composite": false, + "clientRole": true, + "containerId": "a8395b5e-b8a8-4e45-a021-824927a0d696", + "attributes": {} + }, + { + "id": "0155bf55-9b5c-4f37-a982-6c9d4f7bf7a7", + "name": "manage-events", + "description": "${role_manage-events}", + "composite": false, + "clientRole": true, + "containerId": "a8395b5e-b8a8-4e45-a021-824927a0d696", + "attributes": {} + }, + { + "id": "721a772a-295f-4975-b693-f3eca9c0d95a", + "name": "query-clients", + "description": "${role_query-clients}", + "composite": false, + "clientRole": true, + "containerId": "a8395b5e-b8a8-4e45-a021-824927a0d696", + "attributes": {} + }, + { + "id": "3fb56823-25ae-4337-817f-cc09233b0b94", + "name": "view-clients", + "description": "${role_view-clients}", + "composite": true, + "composites": { + "client": { + "realm-management": [ + "query-clients" + ] + } + }, + "clientRole": true, + "containerId": "a8395b5e-b8a8-4e45-a021-824927a0d696", + "attributes": {} + }, + { + "id": "befc162f-899c-4924-9852-e9c11e802d5f", + "name": "manage-identity-providers", + "description": "${role_manage-identity-providers}", + "composite": false, + "clientRole": true, + "containerId": "a8395b5e-b8a8-4e45-a021-824927a0d696", + "attributes": {} + }, + { + "id": "88d8ab9c-eac2-4187-819b-9bd32f126ee1", + "name": "manage-authorization", + "description": "${role_manage-authorization}", + "composite": false, + "clientRole": true, + "containerId": "a8395b5e-b8a8-4e45-a021-824927a0d696", + "attributes": {} + } + ], + "neosync-app": [], + "security-admin-console": [], + "neosync-cli": [], + "admin-cli": [], + "account-console": [], + "broker": [], + "account": [ + { + "id": "5e865988-54ba-44cd-b107-63baf58611cb", + "name": "manage-account", + "composite": false, + "clientRole": true, + "containerId": "b2534bc6-74bf-4950-8116-2498067910ef", + "attributes": {} + }, + { + "id": "2e3be368-5dc7-4d95-bccb-7f0019de8153", + "name": "view-groups", + "composite": false, + "clientRole": true, + "containerId": "b2534bc6-74bf-4950-8116-2498067910ef", + "attributes": {} + }, + { + "id": "8b902a26-6104-45b8-b0ce-e011818f5c80", + "name": "delete-account", + "description": "${role_delete-account}", + "composite": false, + "clientRole": true, + "containerId": "b2534bc6-74bf-4950-8116-2498067910ef", + "attributes": {} + } + ] + } + }, + "groups": [], "defaultRole": { "id": "a3b4c234-3add-472a-9faa-d0e92c385d8b", "name": "default-roles-neosync", @@ -93,6 +380,29 @@ "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister": false, "webAuthnPolicyPasswordlessAcceptableAaguids": [], "webAuthnPolicyPasswordlessExtraOrigins": [], + "users": [ + { + "id": "87b1376c-8963-4950-aa5c-2dbff5e12187", + "username": "service-account-neosync-api", + "emailVerified": false, + "createdTimestamp": 1734375263242, + "enabled": true, + "totp": false, + "serviceAccountClientId": "neosync-api", + "disableableCredentialTypes": [], + "requiredActions": [], + "realmRoles": [ + "default-roles-neosync" + ], + "clientRoles": { + "realm-management": [ + "view-users" + ] + }, + "notBefore": 0, + "groups": [] + } + ], "scopeMappings": [ { "clientScope": "offline_access", @@ -148,6 +458,7 @@ "acr", "roles", "profile", + "basic", "email" ], "optionalClientScopes": [ @@ -203,6 +514,7 @@ "acr", "roles", "profile", + "basic", "email" ], "optionalClientScopes": [ @@ -243,6 +555,7 @@ "acr", "roles", "profile", + "basic", "email" ], "optionalClientScopes": [ @@ -292,6 +605,109 @@ "microprofile-jwt" ] }, + { + "id": "63da787f-770a-4c13-b5a2-12ede311edc8", + "clientId": "neosync-api", + "name": "Neosync API", + "description": "", + "rootUrl": "", + "adminUrl": "", + "baseUrl": "", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "secret": "PufiCKGRDISEokPZ9VwB6T86aDKj33f4", + "redirectUris": [ + "/*" + ], + "webOrigins": [ + "/*" + ], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": false, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": true, + "publicClient": false, + "frontchannelLogout": true, + "protocol": "openid-connect", + "attributes": { + "oidc.ciba.grant.enabled": "false", + "client.secret.creation.time": "1734375220", + "backchannel.logout.session.required": "true", + "display.on.consent.screen": "false", + "oauth2.device.authorization.grant.enabled": "false", + "backchannel.logout.revoke.offline.tokens": "false" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": true, + "nodeReRegistrationTimeout": -1, + "protocolMappers": [ + { + "id": "abdfd41b-cf96-4029-9416-97452a797dd5", + "name": "Client IP Address", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "clientAddress", + "id.token.claim": "true", + "introspection.token.claim": "true", + "access.token.claim": "true", + "claim.name": "clientAddress", + "jsonType.label": "String" + } + }, + { + "id": "615113c2-8936-4f48-84cd-7fab14c36d10", + "name": "Client ID", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "client_id", + "id.token.claim": "true", + "introspection.token.claim": "true", + "access.token.claim": "true", + "claim.name": "client_id", + "jsonType.label": "String" + } + }, + { + "id": "b3b251fe-33fe-4bb5-95ff-8085e1b50199", + "name": "Client Host", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "clientHost", + "id.token.claim": "true", + "introspection.token.claim": "true", + "access.token.claim": "true", + "claim.name": "clientHost", + "jsonType.label": "String" + } + } + ], + "defaultClientScopes": [ + "web-origins", + "acr", + "roles", + "profile", + "neosync-aud", + "basic", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + }, { "id": "eb7857c1-8d05-435c-a855-f44ba6d89791", "clientId": "neosync-app", @@ -304,7 +720,7 @@ "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", - "secret": "72alWGzhHInDskRHduTQ8BjB4Lgn0n3a", + "secret": "**********", "redirectUris": [ "http://localhost:3000/*" ], @@ -339,6 +755,7 @@ "roles", "profile", "neosync-aud", + "basic", "email" ], "optionalClientScopes": [ @@ -396,6 +813,7 @@ "roles", "profile", "neosync-aud", + "basic", "email" ], "optionalClientScopes": [ @@ -501,6 +919,7 @@ "acr", "roles", "profile", + "basic", "email" ], "optionalClientScopes": [ @@ -544,8 +963,8 @@ "protocol": "openid-connect", "attributes": { "include.in.token.scope": "false", - "display.on.consent.screen": "false", - "consent.screen.text": "" + "consent.screen.text": "", + "display.on.consent.screen": "false" }, "protocolMappers": [ { @@ -592,8 +1011,8 @@ "protocol": "openid-connect", "attributes": { "include.in.token.scope": "false", - "display.on.consent.screen": "true", - "consent.screen.text": "${rolesScopeConsentText}" + "consent.screen.text": "${rolesScopeConsentText}", + "display.on.consent.screen": "true" }, "protocolMappers": [ { @@ -603,12 +1022,12 @@ "protocolMapper": "oidc-usermodel-realm-role-mapper", "consentRequired": false, "config": { - "introspection.token.claim": "true", - "multivalued": "true", "user.attribute": "foo", + "introspection.token.claim": "true", "access.token.claim": "true", "claim.name": "realm_access.roles", - "jsonType.label": "String" + "jsonType.label": "String", + "multivalued": "true" } }, { @@ -618,12 +1037,12 @@ "protocolMapper": "oidc-usermodel-client-role-mapper", "consentRequired": false, "config": { - "introspection.token.claim": "true", - "multivalued": "true", "user.attribute": "foo", + "introspection.token.claim": "true", "access.token.claim": "true", "claim.name": "resource_access.${client_id}.roles", - "jsonType.label": "String" + "jsonType.label": "String", + "multivalued": "true" } }, { @@ -646,8 +1065,8 @@ "protocol": "openid-connect", "attributes": { "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${emailScopeConsentText}" + "consent.screen.text": "${emailScopeConsentText}", + "display.on.consent.screen": "true" }, "protocolMappers": [ { @@ -691,8 +1110,8 @@ "protocol": "openid-connect", "attributes": { "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${addressScopeConsentText}" + "consent.screen.text": "${addressScopeConsentText}", + "display.on.consent.screen": "true" }, "protocolMappers": [ { @@ -716,6 +1135,44 @@ } ] }, + { + "id": "2ea1b7fe-8b76-48e8-bbf7-ab0c6f06dbdf", + "name": "basic", + "description": "OpenID Connect scope for add all basic claims to the token", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "false", + "display.on.consent.screen": "false" + }, + "protocolMappers": [ + { + "id": "7191dc2d-19cc-4644-8dc8-fc7c9672057d", + "name": "sub", + "protocol": "openid-connect", + "protocolMapper": "oidc-sub-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "access.token.claim": "true" + } + }, + { + "id": "c9a32866-9a8f-4e97-9d29-7e7ef765d901", + "name": "auth_time", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "AUTH_TIME", + "id.token.claim": "true", + "introspection.token.claim": "true", + "access.token.claim": "true", + "claim.name": "auth_time", + "jsonType.label": "long" + } + } + ] + }, { "id": "78b6eaac-c148-4f80-a1f0-3bd32cc60482", "name": "phone", @@ -723,8 +1180,8 @@ "protocol": "openid-connect", "attributes": { "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${phoneScopeConsentText}" + "consent.screen.text": "${phoneScopeConsentText}", + "display.on.consent.screen": "true" }, "protocolMappers": [ { @@ -778,8 +1235,8 @@ "protocol": "openid-connect", "attributes": { "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${profileScopeConsentText}" + "consent.screen.text": "${profileScopeConsentText}", + "display.on.consent.screen": "true" }, "protocolMappers": [ { @@ -1072,7 +1529,8 @@ "id.token.claim": "false", "access.token.claim": "true", "introspection.token.claim": "true", - "included.custom.audience": "neosync" + "included.custom.audience": "neosync", + "userinfo.token.claim": "false" } } ] @@ -1085,7 +1543,8 @@ "roles", "web-origins", "acr", - "neosync-aud" + "neosync-aud", + "basic" ], "defaultOptionalClientScopes": [ "offline_access", @@ -1132,13 +1591,13 @@ "config": { "allowed-protocol-mapper-types": [ "oidc-sha256-pairwise-sub-mapper", - "oidc-full-name-mapper", - "saml-role-list-mapper", - "saml-user-property-mapper", "oidc-usermodel-property-mapper", - "saml-user-attribute-mapper", "oidc-usermodel-attribute-mapper", - "oidc-address-mapper" + "oidc-address-mapper", + "oidc-full-name-mapper", + "saml-user-attribute-mapper", + "saml-user-property-mapper", + "saml-role-list-mapper" ] } }, @@ -1151,13 +1610,13 @@ "config": { "allowed-protocol-mapper-types": [ "oidc-sha256-pairwise-sub-mapper", - "saml-role-list-mapper", - "oidc-usermodel-property-mapper", + "oidc-address-mapper", "saml-user-attribute-mapper", + "saml-role-list-mapper", "oidc-full-name-mapper", "saml-user-property-mapper", - "oidc-address-mapper", - "oidc-usermodel-attribute-mapper" + "oidc-usermodel-attribute-mapper", + "oidc-usermodel-property-mapper" ] } }, @@ -1221,6 +1680,18 @@ } } ], + "org.keycloak.userprofile.UserProfileProvider": [ + { + "id": "751d6d25-0081-445e-8036-b09bc79b2a23", + "providerId": "declarative-user-profile", + "subComponents": {}, + "config": { + "kc.user.profile.config": [ + "{\"attributes\":[{\"name\":\"username\",\"displayName\":\"${username}\",\"validations\":{\"length\":{\"min\":3,\"max\":255},\"username-prohibited-characters\":{},\"up-username-not-idn-homograph\":{}},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"email\",\"displayName\":\"${email}\",\"validations\":{\"email\":{},\"length\":{\"max\":255}},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"firstName\",\"displayName\":\"${firstName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"lastName\",\"displayName\":\"${lastName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false}],\"groups\":[{\"name\":\"user-metadata\",\"displayHeader\":\"User metadata\",\"displayDescription\":\"Attributes, which refer to user metadata\"}],\"unmanagedAttributePolicy\":\"ENABLED\"}" + ] + } + } + ], "org.keycloak.keys.KeyProvider": [ { "id": "eeec4a1b-5611-4f08-836f-dd263b786287", @@ -1258,6 +1729,20 @@ ] } }, + { + "id": "86a09b9d-21d5-470a-b88c-74e5062a9a06", + "name": "hmac-generated-hs512", + "providerId": "hmac-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ], + "algorithm": [ + "HS512" + ] + } + }, { "id": "613646d6-36c9-4a5f-9cb5-7cb68dc69f1b", "name": "rsa-enc-generated", @@ -1878,6 +2363,15 @@ "priority": 80, "config": {} }, + { + "alias": "delete_credential", + "name": "Delete Credential", + "providerId": "delete_credential", + "enabled": true, + "defaultAction": false, + "priority": 100, + "config": {} + }, { "alias": "update_user_locale", "name": "Update User Locale", @@ -1894,6 +2388,7 @@ "resetCredentialsFlow": "reset credentials", "clientAuthenticationFlow": "clients", "dockerAuthenticationFlow": "docker auth", + "firstBrokerLoginFlow": "first broker login", "attributes": { "cibaBackchannelTokenDeliveryMode": "poll", "cibaAuthRequestedUserHint": "login_hint", @@ -1902,8 +2397,11 @@ "clientSessionIdleTimeout": "0", "actionTokenGeneratedByUserLifespan-execute-actions": "", "actionTokenGeneratedByUserLifespan-verify-email": "", + "actionTokenGeneratedByUserLifespan.verify-email": "", + "actionTokenGeneratedByUserLifespan.idp-verify-account-via-email": "", "clientOfflineSessionIdleTimeout": "0", "actionTokenGeneratedByUserLifespan-reset-credentials": "", + "actionTokenGeneratedByUserLifespan.execute-actions": "", "cibaInterval": "5", "realmReusableOtpCode": "false", "cibaExpiresIn": "120", @@ -1911,10 +2409,13 @@ "actionTokenGeneratedByUserLifespan-idp-verify-account-via-email": "", "parRequestUriLifespan": "60", "clientSessionMaxLifespan": "0", - "shortVerificationUri": "" + "organizationsEnabled": "false", + "shortVerificationUri": "", + "actionTokenGeneratedByUserLifespan.reset-credentials": "" }, - "keycloakVersion": "23.0.3", + "keycloakVersion": "25.0.5", "userManagedAccessAllowed": false, + "organizationsEnabled": false, "clientProfiles": { "profiles": [] }, diff --git a/python/src/neosync/mgmt/v1alpha1/user_account_pb2.py b/python/src/neosync/mgmt/v1alpha1/user_account_pb2.py index ba8817d4dc..0311348cf8 100644 --- a/python/src/neosync/mgmt/v1alpha1/user_account_pb2.py +++ b/python/src/neosync/mgmt/v1alpha1/user_account_pb2.py @@ -26,7 +26,7 @@ from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n mgmt/v1alpha1/user_account.proto\x12\rmgmt.v1alpha1\x1a\x1b\x62uf/validate/validate.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x10\n\x0eGetUserRequest\"*\n\x0fGetUserResponse\x12\x17\n\x07user_id\x18\x01 \x01(\tR\x06userId\"\x10\n\x0eSetUserRequest\"*\n\x0fSetUserResponse\x12\x17\n\x07user_id\x18\x01 \x01(\tR\x06userId\"\x18\n\x16GetUserAccountsRequest\"Q\n\x17GetUserAccountsResponse\x12\x36\n\x08\x61\x63\x63ounts\x18\x01 \x03(\x0b\x32\x1a.mgmt.v1alpha1.UserAccountR\x08\x61\x63\x63ounts\"\x9a\x01\n\x0bUserAccount\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n\x04name\x18\x02 \x01(\tR\x04name\x12\x32\n\x04type\x18\x03 \x01(\x0e\x32\x1e.mgmt.v1alpha1.UserAccountTypeR\x04type\x12\x33\n\x16has_stripe_customer_id\x18\x04 \x01(\x08R\x13hasStripeCustomerId\"\x91\x01\n#ConvertPersonalToTeamAccountRequest\x12-\n\x04name\x18\x01 \x01(\tB\x19\xbaH\x16r\x14\x32\x12^[a-z0-9-]{3,100}$R\x04name\x12,\n\naccount_id\x18\x02 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01H\x00R\taccountId\x88\x01\x01\x42\r\n\x0b_account_id\"\xcc\x01\n$ConvertPersonalToTeamAccountResponse\x12\x1d\n\naccount_id\x18\x01 \x01(\tR\taccountId\x12\x35\n\x14\x63heckout_session_url\x18\x02 \x01(\tH\x00R\x12\x63heckoutSessionUrl\x88\x01\x01\x12\x35\n\x17new_personal_account_id\x18\x03 \x01(\tR\x14newPersonalAccountIdB\x17\n\x15_checkout_session_url\"\x1b\n\x19SetPersonalAccountRequest\";\n\x1aSetPersonalAccountResponse\x12\x1d\n\naccount_id\x18\x01 \x01(\tR\taccountId\"A\n\x16IsUserInAccountRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\")\n\x17IsUserInAccountResponse\x12\x0e\n\x02ok\x18\x01 \x01(\x08R\x02ok\"J\n\x1fGetAccountTemporalConfigRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"`\n GetAccountTemporalConfigResponse\x12<\n\x06\x63onfig\x18\x01 \x01(\x0b\x32$.mgmt.v1alpha1.AccountTemporalConfigR\x06\x63onfig\"\x88\x01\n\x1fSetAccountTemporalConfigRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\x12<\n\x06\x63onfig\x18\x02 \x01(\x0b\x32$.mgmt.v1alpha1.AccountTemporalConfigR\x06\x63onfig\"`\n SetAccountTemporalConfigResponse\x12<\n\x06\x63onfig\x18\x01 \x01(\x0b\x32$.mgmt.v1alpha1.AccountTemporalConfigR\x06\x63onfig\"\x91\x01\n\x15\x41\x63\x63ountTemporalConfig\x12\x19\n\x03url\x18\x01 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\x03url\x12%\n\tnamespace\x18\x02 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\tnamespace\x12\x36\n\x13sync_job_queue_name\x18\x03 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\x10syncJobQueueName\"I\n\x18\x43reateTeamAccountRequest\x12-\n\x04name\x18\x01 \x01(\tB\x19\xbaH\x16r\x14\x32\x12^[a-z0-9-]{3,100}$R\x04name\"\x8a\x01\n\x19\x43reateTeamAccountResponse\x12\x1d\n\naccount_id\x18\x01 \x01(\tR\taccountId\x12\x35\n\x14\x63heckout_session_url\x18\x02 \x01(\tH\x00R\x12\x63heckoutSessionUrl\x88\x01\x01\x42\x17\n\x15_checkout_session_url\"]\n\x0b\x41\x63\x63ountUser\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n\x04name\x18\x02 \x01(\tR\x04name\x12\x14\n\x05image\x18\x03 \x01(\tR\x05image\x12\x14\n\x05\x65mail\x18\x04 \x01(\tR\x05\x65mail\"G\n\x1cGetTeamAccountMembersRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"Q\n\x1dGetTeamAccountMembersResponse\x12\x30\n\x05users\x18\x01 \x03(\x0b\x32\x1a.mgmt.v1alpha1.AccountUserR\x05users\"l\n\x1eRemoveTeamAccountMemberRequest\x12!\n\x07user_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x06userId\x12\'\n\naccount_id\x18\x02 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"!\n\x1fRemoveTeamAccountMemberResponse\"h\n\x1eInviteUserToTeamAccountRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\x12\x1d\n\x05\x65mail\x18\x02 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\x05\x65mail\"\xdd\x02\n\rAccountInvite\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x1d\n\naccount_id\x18\x02 \x01(\tR\taccountId\x12$\n\x0esender_user_id\x18\x03 \x01(\tR\x0csenderUserId\x12\x14\n\x05\x65mail\x18\x04 \x01(\tR\x05\x65mail\x12\x14\n\x05token\x18\x05 \x01(\tR\x05token\x12\x1a\n\x08\x61\x63\x63\x65pted\x18\x06 \x01(\x08R\x08\x61\x63\x63\x65pted\x12\x39\n\ncreated_at\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\tcreatedAt\x12\x39\n\nupdated_at\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\tupdatedAt\x12\x39\n\nexpires_at\x18\t \x01(\x0b\x32\x1a.google.protobuf.TimestampR\texpiresAt\"W\n\x1fInviteUserToTeamAccountResponse\x12\x34\n\x06invite\x18\x01 \x01(\x0b\x32\x1c.mgmt.v1alpha1.AccountInviteR\x06invite\"G\n\x1cGetTeamAccountInvitesRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"W\n\x1dGetTeamAccountInvitesResponse\x12\x36\n\x07invites\x18\x01 \x03(\x0b\x32\x1c.mgmt.v1alpha1.AccountInviteR\x07invites\":\n\x1eRemoveTeamAccountInviteRequest\x12\x18\n\x02id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x02id\"!\n\x1fRemoveTeamAccountInviteResponse\"?\n\x1e\x41\x63\x63\x65ptTeamAccountInviteRequest\x12\x1d\n\x05token\x18\x01 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\x05token\"W\n\x1f\x41\x63\x63\x65ptTeamAccountInviteResponse\x12\x34\n\x07\x61\x63\x63ount\x18\x01 \x01(\x0b\x32\x1a.mgmt.v1alpha1.UserAccountR\x07\x61\x63\x63ount\"\x1d\n\x1bGetSystemInformationRequest\"\xc3\x01\n\x1cGetSystemInformationResponse\x12\x18\n\x07version\x18\x01 \x01(\tR\x07version\x12\x16\n\x06\x63ommit\x18\x02 \x01(\tR\x06\x63ommit\x12\x1a\n\x08\x63ompiler\x18\x03 \x01(\tR\x08\x63ompiler\x12\x1a\n\x08platform\x18\x04 \x01(\tR\x08platform\x12\x39\n\nbuild_date\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\tbuildDate\"L\n!GetAccountOnboardingConfigRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"d\n\"GetAccountOnboardingConfigResponse\x12>\n\x06\x63onfig\x18\x01 \x01(\x0b\x32&.mgmt.v1alpha1.AccountOnboardingConfigR\x06\x63onfig\"\x8c\x01\n!SetAccountOnboardingConfigRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\x12>\n\x06\x63onfig\x18\x02 \x01(\x0b\x32&.mgmt.v1alpha1.AccountOnboardingConfigR\x06\x63onfig\"d\n\"SetAccountOnboardingConfigResponse\x12>\n\x06\x63onfig\x18\x01 \x01(\x0b\x32&.mgmt.v1alpha1.AccountOnboardingConfigR\x06\x63onfig\"\xbb\x02\n\x17\x41\x63\x63ountOnboardingConfig\x12\x41\n\x1dhas_created_source_connection\x18\x01 \x01(\x08R\x1ahasCreatedSourceConnection\x12K\n\"has_created_destination_connection\x18\x02 \x01(\x08R\x1fhasCreatedDestinationConnection\x12&\n\x0fhas_created_job\x18\x03 \x01(\x08R\rhasCreatedJob\x12.\n\x13has_invited_members\x18\x04 \x01(\x08R\x11hasInvitedMembers\x12\x38\n\x18has_completed_onboarding\x18\x05 \x01(\x08R\x16hasCompletedOnboarding\"B\n\x17GetAccountStatusRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"\xe5\x01\n\x18GetAccountStatusResponse\x12*\n\x11used_record_count\x18\x01 \x01(\x04R\x0fusedRecordCount\x12\x35\n\x14\x61llowed_record_count\x18\x02 \x01(\x04H\x00R\x12\x61llowedRecordCount\x88\x01\x01\x12M\n\x13subscription_status\x18\x03 \x01(\x0e\x32\x1c.mgmt.v1alpha1.BillingStatusR\x12subscriptionStatusB\x17\n\x15_allowed_record_count\"\x9c\x01\n\x1bIsAccountStatusValidRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\x12\x39\n\x16requested_record_count\x18\x02 \x01(\x04H\x00R\x14requestedRecordCount\x88\x01\x01\x42\x19\n\x17_requested_record_count\"\xa3\x03\n\x1cIsAccountStatusValidResponse\x12\x19\n\x08is_valid\x18\x01 \x01(\x08R\x07isValid\x12\x1b\n\x06reason\x18\x02 \x01(\tH\x00R\x06reason\x88\x01\x01\x12\x1f\n\x0bshould_poll\x18\x03 \x01(\x08R\nshouldPoll\x12*\n\x11used_record_count\x18\x04 \x01(\x04R\x0fusedRecordCount\x12\x35\n\x14\x61llowed_record_count\x18\x05 \x01(\x04H\x01R\x12\x61llowedRecordCount\x88\x01\x01\x12\x43\n\x0e\x61\x63\x63ount_status\x18\x06 \x01(\x0e\x32\x1c.mgmt.v1alpha1.AccountStatusR\raccountStatus\x12I\n\x10trial_expires_at\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x02R\x0etrialExpiresAt\x88\x01\x01\x42\t\n\x07_reasonB\x17\n\x15_allowed_record_countB\x13\n\x11_trial_expires_at\"R\n\'GetAccountBillingCheckoutSessionRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"\\\n(GetAccountBillingCheckoutSessionResponse\x12\x30\n\x14\x63heckout_session_url\x18\x01 \x01(\tR\x12\x63heckoutSessionUrl\"P\n%GetAccountBillingPortalSessionRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"V\n&GetAccountBillingPortalSessionResponse\x12,\n\x12portal_session_url\x18\x01 \x01(\tR\x10portalSessionUrl\"<\n\x19GetBillingAccountsRequest\x12\x1f\n\x0b\x61\x63\x63ount_ids\x18\x01 \x03(\tR\naccountIds\"T\n\x1aGetBillingAccountsResponse\x12\x36\n\x08\x61\x63\x63ounts\x18\x01 \x03(\x0b\x32\x1a.mgmt.v1alpha1.UserAccountR\x08\x61\x63\x63ounts\"\xe2\x01\n\x1bSetBillingMeterEventRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\x12&\n\nevent_name\x18\x02 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\teventName\x12\x1d\n\x05value\x18\x03 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\x05value\x12\"\n\x08\x65vent_id\x18\x04 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\x07\x65ventId\x12!\n\ttimestamp\x18\x05 \x01(\x04H\x00R\ttimestamp\x88\x01\x01\x42\x0c\n\n_timestamp\"\x1e\n\x1cSetBillingMeterEventResponse\"\x90\x01\n\x12SetUserRoleRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\x12!\n\x07user_id\x18\x02 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x06userId\x12.\n\x04role\x18\x03 \x01(\x0e\x32\x1a.mgmt.v1alpha1.AccountRoleR\x04role\"\x15\n\x13SetUserRoleResponse*\x92\x01\n\x0fUserAccountType\x12!\n\x1dUSER_ACCOUNT_TYPE_UNSPECIFIED\x10\x00\x12\x1e\n\x1aUSER_ACCOUNT_TYPE_PERSONAL\x10\x01\x12\x1a\n\x16USER_ACCOUNT_TYPE_TEAM\x10\x02\x12 \n\x1cUSER_ACCOUNT_TYPE_ENTERPRISE\x10\x03*\xa9\x01\n\rBillingStatus\x12\x1e\n\x1a\x42ILLING_STATUS_UNSPECIFIED\x10\x00\x12\x19\n\x15\x42ILLING_STATUS_ACTIVE\x10\x01\x12\x1a\n\x16\x42ILLING_STATUS_EXPIRED\x10\x02\x12\x1f\n\x1b\x42ILLING_STATUS_TRIAL_ACTIVE\x10\x03\x12 \n\x1c\x42ILLING_STATUS_TRIAL_EXPIRED\x10\x04*\x8c\x02\n\rAccountStatus\x12%\n!ACCOUNT_STATUS_REASON_UNSPECIFIED\x10\x00\x12(\n$ACCOUNT_STATUS_EXCEEDS_ALLOWED_LIMIT\x10\x01\x12*\n&ACCOUNT_STATUS_REQUESTED_EXCEEDS_LIMIT\x10\x02\x12+\n\'ACCOUNT_STATUS_ACCOUNT_IN_EXPIRED_STATE\x10\x03\x12\'\n#ACCOUNT_STATUS_ACCOUNT_TRIAL_ACTIVE\x10\x04\x12(\n$ACCOUNT_STATUS_ACCOUNT_TRIAL_EXPIRED\x10\x05*\x9f\x01\n\x0b\x41\x63\x63ountRole\x12\x1c\n\x18\x41\x43\x43OUNT_ROLE_UNSPECIFIED\x10\x00\x12\x16\n\x12\x41\x43\x43OUNT_ROLE_ADMIN\x10\x01\x12\x1e\n\x1a\x41\x43\x43OUNT_ROLE_JOB_DEVELOPER\x10\x02\x12\x1b\n\x17\x41\x43\x43OUNT_ROLE_JOB_VIEWER\x10\x03\x12\x1d\n\x19\x41\x43\x43OUNT_ROLE_JOB_EXECUTOR\x10\x04\x32\xf8\x16\n\x12UserAccountService\x12J\n\x07GetUser\x12\x1d.mgmt.v1alpha1.GetUserRequest\x1a\x1e.mgmt.v1alpha1.GetUserResponse\"\x00\x12J\n\x07SetUser\x12\x1d.mgmt.v1alpha1.SetUserRequest\x1a\x1e.mgmt.v1alpha1.SetUserResponse\"\x00\x12\x62\n\x0fGetUserAccounts\x12%.mgmt.v1alpha1.GetUserAccountsRequest\x1a&.mgmt.v1alpha1.GetUserAccountsResponse\"\x00\x12k\n\x12SetPersonalAccount\x12(.mgmt.v1alpha1.SetPersonalAccountRequest\x1a).mgmt.v1alpha1.SetPersonalAccountResponse\"\x00\x12\x89\x01\n\x1c\x43onvertPersonalToTeamAccount\x12\x32.mgmt.v1alpha1.ConvertPersonalToTeamAccountRequest\x1a\x33.mgmt.v1alpha1.ConvertPersonalToTeamAccountResponse\"\x00\x12h\n\x11\x43reateTeamAccount\x12\'.mgmt.v1alpha1.CreateTeamAccountRequest\x1a(.mgmt.v1alpha1.CreateTeamAccountResponse\"\x00\x12\x62\n\x0fIsUserInAccount\x12%.mgmt.v1alpha1.IsUserInAccountRequest\x1a&.mgmt.v1alpha1.IsUserInAccountResponse\"\x00\x12}\n\x18GetAccountTemporalConfig\x12..mgmt.v1alpha1.GetAccountTemporalConfigRequest\x1a/.mgmt.v1alpha1.GetAccountTemporalConfigResponse\"\x00\x12}\n\x18SetAccountTemporalConfig\x12..mgmt.v1alpha1.SetAccountTemporalConfigRequest\x1a/.mgmt.v1alpha1.SetAccountTemporalConfigResponse\"\x00\x12t\n\x15GetTeamAccountMembers\x12+.mgmt.v1alpha1.GetTeamAccountMembersRequest\x1a,.mgmt.v1alpha1.GetTeamAccountMembersResponse\"\x00\x12z\n\x17RemoveTeamAccountMember\x12-.mgmt.v1alpha1.RemoveTeamAccountMemberRequest\x1a..mgmt.v1alpha1.RemoveTeamAccountMemberResponse\"\x00\x12z\n\x17InviteUserToTeamAccount\x12-.mgmt.v1alpha1.InviteUserToTeamAccountRequest\x1a..mgmt.v1alpha1.InviteUserToTeamAccountResponse\"\x00\x12t\n\x15GetTeamAccountInvites\x12+.mgmt.v1alpha1.GetTeamAccountInvitesRequest\x1a,.mgmt.v1alpha1.GetTeamAccountInvitesResponse\"\x00\x12z\n\x17RemoveTeamAccountInvite\x12-.mgmt.v1alpha1.RemoveTeamAccountInviteRequest\x1a..mgmt.v1alpha1.RemoveTeamAccountInviteResponse\"\x00\x12z\n\x17\x41\x63\x63\x65ptTeamAccountInvite\x12-.mgmt.v1alpha1.AcceptTeamAccountInviteRequest\x1a..mgmt.v1alpha1.AcceptTeamAccountInviteResponse\"\x00\x12t\n\x14GetSystemInformation\x12*.mgmt.v1alpha1.GetSystemInformationRequest\x1a+.mgmt.v1alpha1.GetSystemInformationResponse\"\x03\x90\x02\x01\x12\x83\x01\n\x1aGetAccountOnboardingConfig\x12\x30.mgmt.v1alpha1.GetAccountOnboardingConfigRequest\x1a\x31.mgmt.v1alpha1.GetAccountOnboardingConfigResponse\"\x00\x12\x83\x01\n\x1aSetAccountOnboardingConfig\x12\x30.mgmt.v1alpha1.SetAccountOnboardingConfigRequest\x1a\x31.mgmt.v1alpha1.SetAccountOnboardingConfigResponse\"\x00\x12h\n\x10GetAccountStatus\x12&.mgmt.v1alpha1.GetAccountStatusRequest\x1a\'.mgmt.v1alpha1.GetAccountStatusResponse\"\x03\x90\x02\x01\x12t\n\x14IsAccountStatusValid\x12*.mgmt.v1alpha1.IsAccountStatusValidRequest\x1a+.mgmt.v1alpha1.IsAccountStatusValidResponse\"\x03\x90\x02\x01\x12\x95\x01\n GetAccountBillingCheckoutSession\x12\x36.mgmt.v1alpha1.GetAccountBillingCheckoutSessionRequest\x1a\x37.mgmt.v1alpha1.GetAccountBillingCheckoutSessionResponse\"\x00\x12\x8f\x01\n\x1eGetAccountBillingPortalSession\x12\x34.mgmt.v1alpha1.GetAccountBillingPortalSessionRequest\x1a\x35.mgmt.v1alpha1.GetAccountBillingPortalSessionResponse\"\x00\x12n\n\x12GetBillingAccounts\x12(.mgmt.v1alpha1.GetBillingAccountsRequest\x1a).mgmt.v1alpha1.GetBillingAccountsResponse\"\x03\x90\x02\x01\x12q\n\x14SetBillingMeterEvent\x12*.mgmt.v1alpha1.SetBillingMeterEventRequest\x1a+.mgmt.v1alpha1.SetBillingMeterEventResponse\"\x00\x12V\n\x0bSetUserRole\x12!.mgmt.v1alpha1.SetUserRoleRequest\x1a\".mgmt.v1alpha1.SetUserRoleResponse\"\x00\x42\xcc\x01\n\x11\x63om.mgmt.v1alpha1B\x10UserAccountProtoP\x01ZPgithub.com/nucleuscloud/neosync/backend/gen/go/protos/mgmt/v1alpha1;mgmtv1alpha1\xa2\x02\x03MXX\xaa\x02\rMgmt.V1alpha1\xca\x02\rMgmt\\V1alpha1\xe2\x02\x19Mgmt\\V1alpha1\\GPBMetadata\xea\x02\x0eMgmt::V1alpha1b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n mgmt/v1alpha1/user_account.proto\x12\rmgmt.v1alpha1\x1a\x1b\x62uf/validate/validate.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x10\n\x0eGetUserRequest\"*\n\x0fGetUserResponse\x12\x17\n\x07user_id\x18\x01 \x01(\tR\x06userId\"\x10\n\x0eSetUserRequest\"*\n\x0fSetUserResponse\x12\x17\n\x07user_id\x18\x01 \x01(\tR\x06userId\"\x18\n\x16GetUserAccountsRequest\"Q\n\x17GetUserAccountsResponse\x12\x36\n\x08\x61\x63\x63ounts\x18\x01 \x03(\x0b\x32\x1a.mgmt.v1alpha1.UserAccountR\x08\x61\x63\x63ounts\"\x9a\x01\n\x0bUserAccount\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n\x04name\x18\x02 \x01(\tR\x04name\x12\x32\n\x04type\x18\x03 \x01(\x0e\x32\x1e.mgmt.v1alpha1.UserAccountTypeR\x04type\x12\x33\n\x16has_stripe_customer_id\x18\x04 \x01(\x08R\x13hasStripeCustomerId\"\x91\x01\n#ConvertPersonalToTeamAccountRequest\x12-\n\x04name\x18\x01 \x01(\tB\x19\xbaH\x16r\x14\x32\x12^[a-z0-9-]{3,100}$R\x04name\x12,\n\naccount_id\x18\x02 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01H\x00R\taccountId\x88\x01\x01\x42\r\n\x0b_account_id\"\xcc\x01\n$ConvertPersonalToTeamAccountResponse\x12\x1d\n\naccount_id\x18\x01 \x01(\tR\taccountId\x12\x35\n\x14\x63heckout_session_url\x18\x02 \x01(\tH\x00R\x12\x63heckoutSessionUrl\x88\x01\x01\x12\x35\n\x17new_personal_account_id\x18\x03 \x01(\tR\x14newPersonalAccountIdB\x17\n\x15_checkout_session_url\"\x1b\n\x19SetPersonalAccountRequest\";\n\x1aSetPersonalAccountResponse\x12\x1d\n\naccount_id\x18\x01 \x01(\tR\taccountId\"A\n\x16IsUserInAccountRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\")\n\x17IsUserInAccountResponse\x12\x0e\n\x02ok\x18\x01 \x01(\x08R\x02ok\"J\n\x1fGetAccountTemporalConfigRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"`\n GetAccountTemporalConfigResponse\x12<\n\x06\x63onfig\x18\x01 \x01(\x0b\x32$.mgmt.v1alpha1.AccountTemporalConfigR\x06\x63onfig\"\x88\x01\n\x1fSetAccountTemporalConfigRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\x12<\n\x06\x63onfig\x18\x02 \x01(\x0b\x32$.mgmt.v1alpha1.AccountTemporalConfigR\x06\x63onfig\"`\n SetAccountTemporalConfigResponse\x12<\n\x06\x63onfig\x18\x01 \x01(\x0b\x32$.mgmt.v1alpha1.AccountTemporalConfigR\x06\x63onfig\"\x91\x01\n\x15\x41\x63\x63ountTemporalConfig\x12\x19\n\x03url\x18\x01 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\x03url\x12%\n\tnamespace\x18\x02 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\tnamespace\x12\x36\n\x13sync_job_queue_name\x18\x03 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\x10syncJobQueueName\"I\n\x18\x43reateTeamAccountRequest\x12-\n\x04name\x18\x01 \x01(\tB\x19\xbaH\x16r\x14\x32\x12^[a-z0-9-]{3,100}$R\x04name\"\x8a\x01\n\x19\x43reateTeamAccountResponse\x12\x1d\n\naccount_id\x18\x01 \x01(\tR\taccountId\x12\x35\n\x14\x63heckout_session_url\x18\x02 \x01(\tH\x00R\x12\x63heckoutSessionUrl\x88\x01\x01\x42\x17\n\x15_checkout_session_url\"\x8d\x01\n\x0b\x41\x63\x63ountUser\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n\x04name\x18\x02 \x01(\tR\x04name\x12\x14\n\x05image\x18\x03 \x01(\tR\x05image\x12\x14\n\x05\x65mail\x18\x04 \x01(\tR\x05\x65mail\x12.\n\x04role\x18\x05 \x01(\x0e\x32\x1a.mgmt.v1alpha1.AccountRoleR\x04role\"G\n\x1cGetTeamAccountMembersRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"Q\n\x1dGetTeamAccountMembersResponse\x12\x30\n\x05users\x18\x01 \x03(\x0b\x32\x1a.mgmt.v1alpha1.AccountUserR\x05users\"l\n\x1eRemoveTeamAccountMemberRequest\x12!\n\x07user_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x06userId\x12\'\n\naccount_id\x18\x02 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"!\n\x1fRemoveTeamAccountMemberResponse\"\xa6\x01\n\x1eInviteUserToTeamAccountRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\x12\x1d\n\x05\x65mail\x18\x02 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\x05\x65mail\x12\x33\n\x04role\x18\x03 \x01(\x0e\x32\x1a.mgmt.v1alpha1.AccountRoleH\x00R\x04role\x88\x01\x01\x42\x07\n\x05_role\"\x8d\x03\n\rAccountInvite\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x1d\n\naccount_id\x18\x02 \x01(\tR\taccountId\x12$\n\x0esender_user_id\x18\x03 \x01(\tR\x0csenderUserId\x12\x14\n\x05\x65mail\x18\x04 \x01(\tR\x05\x65mail\x12\x14\n\x05token\x18\x05 \x01(\tR\x05token\x12\x1a\n\x08\x61\x63\x63\x65pted\x18\x06 \x01(\x08R\x08\x61\x63\x63\x65pted\x12\x39\n\ncreated_at\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\tcreatedAt\x12\x39\n\nupdated_at\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\tupdatedAt\x12\x39\n\nexpires_at\x18\t \x01(\x0b\x32\x1a.google.protobuf.TimestampR\texpiresAt\x12.\n\x04role\x18\n \x01(\x0e\x32\x1a.mgmt.v1alpha1.AccountRoleR\x04role\"W\n\x1fInviteUserToTeamAccountResponse\x12\x34\n\x06invite\x18\x01 \x01(\x0b\x32\x1c.mgmt.v1alpha1.AccountInviteR\x06invite\"G\n\x1cGetTeamAccountInvitesRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"W\n\x1dGetTeamAccountInvitesResponse\x12\x36\n\x07invites\x18\x01 \x03(\x0b\x32\x1c.mgmt.v1alpha1.AccountInviteR\x07invites\":\n\x1eRemoveTeamAccountInviteRequest\x12\x18\n\x02id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x02id\"!\n\x1fRemoveTeamAccountInviteResponse\"?\n\x1e\x41\x63\x63\x65ptTeamAccountInviteRequest\x12\x1d\n\x05token\x18\x01 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\x05token\"W\n\x1f\x41\x63\x63\x65ptTeamAccountInviteResponse\x12\x34\n\x07\x61\x63\x63ount\x18\x01 \x01(\x0b\x32\x1a.mgmt.v1alpha1.UserAccountR\x07\x61\x63\x63ount\"\x1d\n\x1bGetSystemInformationRequest\"\xc3\x01\n\x1cGetSystemInformationResponse\x12\x18\n\x07version\x18\x01 \x01(\tR\x07version\x12\x16\n\x06\x63ommit\x18\x02 \x01(\tR\x06\x63ommit\x12\x1a\n\x08\x63ompiler\x18\x03 \x01(\tR\x08\x63ompiler\x12\x1a\n\x08platform\x18\x04 \x01(\tR\x08platform\x12\x39\n\nbuild_date\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\tbuildDate\"L\n!GetAccountOnboardingConfigRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"d\n\"GetAccountOnboardingConfigResponse\x12>\n\x06\x63onfig\x18\x01 \x01(\x0b\x32&.mgmt.v1alpha1.AccountOnboardingConfigR\x06\x63onfig\"\x8c\x01\n!SetAccountOnboardingConfigRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\x12>\n\x06\x63onfig\x18\x02 \x01(\x0b\x32&.mgmt.v1alpha1.AccountOnboardingConfigR\x06\x63onfig\"d\n\"SetAccountOnboardingConfigResponse\x12>\n\x06\x63onfig\x18\x01 \x01(\x0b\x32&.mgmt.v1alpha1.AccountOnboardingConfigR\x06\x63onfig\"\xbb\x02\n\x17\x41\x63\x63ountOnboardingConfig\x12\x41\n\x1dhas_created_source_connection\x18\x01 \x01(\x08R\x1ahasCreatedSourceConnection\x12K\n\"has_created_destination_connection\x18\x02 \x01(\x08R\x1fhasCreatedDestinationConnection\x12&\n\x0fhas_created_job\x18\x03 \x01(\x08R\rhasCreatedJob\x12.\n\x13has_invited_members\x18\x04 \x01(\x08R\x11hasInvitedMembers\x12\x38\n\x18has_completed_onboarding\x18\x05 \x01(\x08R\x16hasCompletedOnboarding\"B\n\x17GetAccountStatusRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"\xe5\x01\n\x18GetAccountStatusResponse\x12*\n\x11used_record_count\x18\x01 \x01(\x04R\x0fusedRecordCount\x12\x35\n\x14\x61llowed_record_count\x18\x02 \x01(\x04H\x00R\x12\x61llowedRecordCount\x88\x01\x01\x12M\n\x13subscription_status\x18\x03 \x01(\x0e\x32\x1c.mgmt.v1alpha1.BillingStatusR\x12subscriptionStatusB\x17\n\x15_allowed_record_count\"\x9c\x01\n\x1bIsAccountStatusValidRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\x12\x39\n\x16requested_record_count\x18\x02 \x01(\x04H\x00R\x14requestedRecordCount\x88\x01\x01\x42\x19\n\x17_requested_record_count\"\xa3\x03\n\x1cIsAccountStatusValidResponse\x12\x19\n\x08is_valid\x18\x01 \x01(\x08R\x07isValid\x12\x1b\n\x06reason\x18\x02 \x01(\tH\x00R\x06reason\x88\x01\x01\x12\x1f\n\x0bshould_poll\x18\x03 \x01(\x08R\nshouldPoll\x12*\n\x11used_record_count\x18\x04 \x01(\x04R\x0fusedRecordCount\x12\x35\n\x14\x61llowed_record_count\x18\x05 \x01(\x04H\x01R\x12\x61llowedRecordCount\x88\x01\x01\x12\x43\n\x0e\x61\x63\x63ount_status\x18\x06 \x01(\x0e\x32\x1c.mgmt.v1alpha1.AccountStatusR\raccountStatus\x12I\n\x10trial_expires_at\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x02R\x0etrialExpiresAt\x88\x01\x01\x42\t\n\x07_reasonB\x17\n\x15_allowed_record_countB\x13\n\x11_trial_expires_at\"R\n\'GetAccountBillingCheckoutSessionRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"\\\n(GetAccountBillingCheckoutSessionResponse\x12\x30\n\x14\x63heckout_session_url\x18\x01 \x01(\tR\x12\x63heckoutSessionUrl\"P\n%GetAccountBillingPortalSessionRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"V\n&GetAccountBillingPortalSessionResponse\x12,\n\x12portal_session_url\x18\x01 \x01(\tR\x10portalSessionUrl\"<\n\x19GetBillingAccountsRequest\x12\x1f\n\x0b\x61\x63\x63ount_ids\x18\x01 \x03(\tR\naccountIds\"T\n\x1aGetBillingAccountsResponse\x12\x36\n\x08\x61\x63\x63ounts\x18\x01 \x03(\x0b\x32\x1a.mgmt.v1alpha1.UserAccountR\x08\x61\x63\x63ounts\"\xe2\x01\n\x1bSetBillingMeterEventRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\x12&\n\nevent_name\x18\x02 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\teventName\x12\x1d\n\x05value\x18\x03 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\x05value\x12\"\n\x08\x65vent_id\x18\x04 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\x07\x65ventId\x12!\n\ttimestamp\x18\x05 \x01(\x04H\x00R\ttimestamp\x88\x01\x01\x42\x0c\n\n_timestamp\"\x1e\n\x1cSetBillingMeterEventResponse\"\x90\x01\n\x12SetUserRoleRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\x12!\n\x07user_id\x18\x02 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x06userId\x12.\n\x04role\x18\x03 \x01(\x0e\x32\x1a.mgmt.v1alpha1.AccountRoleR\x04role\"\x15\n\x13SetUserRoleResponse*\x92\x01\n\x0fUserAccountType\x12!\n\x1dUSER_ACCOUNT_TYPE_UNSPECIFIED\x10\x00\x12\x1e\n\x1aUSER_ACCOUNT_TYPE_PERSONAL\x10\x01\x12\x1a\n\x16USER_ACCOUNT_TYPE_TEAM\x10\x02\x12 \n\x1cUSER_ACCOUNT_TYPE_ENTERPRISE\x10\x03*\xa9\x01\n\rBillingStatus\x12\x1e\n\x1a\x42ILLING_STATUS_UNSPECIFIED\x10\x00\x12\x19\n\x15\x42ILLING_STATUS_ACTIVE\x10\x01\x12\x1a\n\x16\x42ILLING_STATUS_EXPIRED\x10\x02\x12\x1f\n\x1b\x42ILLING_STATUS_TRIAL_ACTIVE\x10\x03\x12 \n\x1c\x42ILLING_STATUS_TRIAL_EXPIRED\x10\x04*\x8c\x02\n\rAccountStatus\x12%\n!ACCOUNT_STATUS_REASON_UNSPECIFIED\x10\x00\x12(\n$ACCOUNT_STATUS_EXCEEDS_ALLOWED_LIMIT\x10\x01\x12*\n&ACCOUNT_STATUS_REQUESTED_EXCEEDS_LIMIT\x10\x02\x12+\n\'ACCOUNT_STATUS_ACCOUNT_IN_EXPIRED_STATE\x10\x03\x12\'\n#ACCOUNT_STATUS_ACCOUNT_TRIAL_ACTIVE\x10\x04\x12(\n$ACCOUNT_STATUS_ACCOUNT_TRIAL_EXPIRED\x10\x05*\x9f\x01\n\x0b\x41\x63\x63ountRole\x12\x1c\n\x18\x41\x43\x43OUNT_ROLE_UNSPECIFIED\x10\x00\x12\x16\n\x12\x41\x43\x43OUNT_ROLE_ADMIN\x10\x01\x12\x1e\n\x1a\x41\x43\x43OUNT_ROLE_JOB_DEVELOPER\x10\x02\x12\x1b\n\x17\x41\x43\x43OUNT_ROLE_JOB_VIEWER\x10\x03\x12\x1d\n\x19\x41\x43\x43OUNT_ROLE_JOB_EXECUTOR\x10\x04\x32\xf8\x16\n\x12UserAccountService\x12J\n\x07GetUser\x12\x1d.mgmt.v1alpha1.GetUserRequest\x1a\x1e.mgmt.v1alpha1.GetUserResponse\"\x00\x12J\n\x07SetUser\x12\x1d.mgmt.v1alpha1.SetUserRequest\x1a\x1e.mgmt.v1alpha1.SetUserResponse\"\x00\x12\x62\n\x0fGetUserAccounts\x12%.mgmt.v1alpha1.GetUserAccountsRequest\x1a&.mgmt.v1alpha1.GetUserAccountsResponse\"\x00\x12k\n\x12SetPersonalAccount\x12(.mgmt.v1alpha1.SetPersonalAccountRequest\x1a).mgmt.v1alpha1.SetPersonalAccountResponse\"\x00\x12\x89\x01\n\x1c\x43onvertPersonalToTeamAccount\x12\x32.mgmt.v1alpha1.ConvertPersonalToTeamAccountRequest\x1a\x33.mgmt.v1alpha1.ConvertPersonalToTeamAccountResponse\"\x00\x12h\n\x11\x43reateTeamAccount\x12\'.mgmt.v1alpha1.CreateTeamAccountRequest\x1a(.mgmt.v1alpha1.CreateTeamAccountResponse\"\x00\x12\x62\n\x0fIsUserInAccount\x12%.mgmt.v1alpha1.IsUserInAccountRequest\x1a&.mgmt.v1alpha1.IsUserInAccountResponse\"\x00\x12}\n\x18GetAccountTemporalConfig\x12..mgmt.v1alpha1.GetAccountTemporalConfigRequest\x1a/.mgmt.v1alpha1.GetAccountTemporalConfigResponse\"\x00\x12}\n\x18SetAccountTemporalConfig\x12..mgmt.v1alpha1.SetAccountTemporalConfigRequest\x1a/.mgmt.v1alpha1.SetAccountTemporalConfigResponse\"\x00\x12t\n\x15GetTeamAccountMembers\x12+.mgmt.v1alpha1.GetTeamAccountMembersRequest\x1a,.mgmt.v1alpha1.GetTeamAccountMembersResponse\"\x00\x12z\n\x17RemoveTeamAccountMember\x12-.mgmt.v1alpha1.RemoveTeamAccountMemberRequest\x1a..mgmt.v1alpha1.RemoveTeamAccountMemberResponse\"\x00\x12z\n\x17InviteUserToTeamAccount\x12-.mgmt.v1alpha1.InviteUserToTeamAccountRequest\x1a..mgmt.v1alpha1.InviteUserToTeamAccountResponse\"\x00\x12t\n\x15GetTeamAccountInvites\x12+.mgmt.v1alpha1.GetTeamAccountInvitesRequest\x1a,.mgmt.v1alpha1.GetTeamAccountInvitesResponse\"\x00\x12z\n\x17RemoveTeamAccountInvite\x12-.mgmt.v1alpha1.RemoveTeamAccountInviteRequest\x1a..mgmt.v1alpha1.RemoveTeamAccountInviteResponse\"\x00\x12z\n\x17\x41\x63\x63\x65ptTeamAccountInvite\x12-.mgmt.v1alpha1.AcceptTeamAccountInviteRequest\x1a..mgmt.v1alpha1.AcceptTeamAccountInviteResponse\"\x00\x12t\n\x14GetSystemInformation\x12*.mgmt.v1alpha1.GetSystemInformationRequest\x1a+.mgmt.v1alpha1.GetSystemInformationResponse\"\x03\x90\x02\x01\x12\x83\x01\n\x1aGetAccountOnboardingConfig\x12\x30.mgmt.v1alpha1.GetAccountOnboardingConfigRequest\x1a\x31.mgmt.v1alpha1.GetAccountOnboardingConfigResponse\"\x00\x12\x83\x01\n\x1aSetAccountOnboardingConfig\x12\x30.mgmt.v1alpha1.SetAccountOnboardingConfigRequest\x1a\x31.mgmt.v1alpha1.SetAccountOnboardingConfigResponse\"\x00\x12h\n\x10GetAccountStatus\x12&.mgmt.v1alpha1.GetAccountStatusRequest\x1a\'.mgmt.v1alpha1.GetAccountStatusResponse\"\x03\x90\x02\x01\x12t\n\x14IsAccountStatusValid\x12*.mgmt.v1alpha1.IsAccountStatusValidRequest\x1a+.mgmt.v1alpha1.IsAccountStatusValidResponse\"\x03\x90\x02\x01\x12\x95\x01\n GetAccountBillingCheckoutSession\x12\x36.mgmt.v1alpha1.GetAccountBillingCheckoutSessionRequest\x1a\x37.mgmt.v1alpha1.GetAccountBillingCheckoutSessionResponse\"\x00\x12\x8f\x01\n\x1eGetAccountBillingPortalSession\x12\x34.mgmt.v1alpha1.GetAccountBillingPortalSessionRequest\x1a\x35.mgmt.v1alpha1.GetAccountBillingPortalSessionResponse\"\x00\x12n\n\x12GetBillingAccounts\x12(.mgmt.v1alpha1.GetBillingAccountsRequest\x1a).mgmt.v1alpha1.GetBillingAccountsResponse\"\x03\x90\x02\x01\x12q\n\x14SetBillingMeterEvent\x12*.mgmt.v1alpha1.SetBillingMeterEventRequest\x1a+.mgmt.v1alpha1.SetBillingMeterEventResponse\"\x00\x12V\n\x0bSetUserRole\x12!.mgmt.v1alpha1.SetUserRoleRequest\x1a\".mgmt.v1alpha1.SetUserRoleResponse\"\x00\x42\xcc\x01\n\x11\x63om.mgmt.v1alpha1B\x10UserAccountProtoP\x01ZPgithub.com/nucleuscloud/neosync/backend/gen/go/protos/mgmt/v1alpha1;mgmtv1alpha1\xa2\x02\x03MXX\xaa\x02\rMgmt.V1alpha1\xca\x02\rMgmt\\V1alpha1\xe2\x02\x19Mgmt\\V1alpha1\\GPBMetadata\xea\x02\x0eMgmt::V1alpha1b\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -100,14 +100,14 @@ _globals['_USERACCOUNTSERVICE'].methods_by_name['IsAccountStatusValid']._serialized_options = b'\220\002\001' _globals['_USERACCOUNTSERVICE'].methods_by_name['GetBillingAccounts']._loaded_options = None _globals['_USERACCOUNTSERVICE'].methods_by_name['GetBillingAccounts']._serialized_options = b'\220\002\001' - _globals['_USERACCOUNTTYPE']._serialized_start=5968 - _globals['_USERACCOUNTTYPE']._serialized_end=6114 - _globals['_BILLINGSTATUS']._serialized_start=6117 - _globals['_BILLINGSTATUS']._serialized_end=6286 - _globals['_ACCOUNTSTATUS']._serialized_start=6289 - _globals['_ACCOUNTSTATUS']._serialized_end=6557 - _globals['_ACCOUNTROLE']._serialized_start=6560 - _globals['_ACCOUNTROLE']._serialized_end=6719 + _globals['_USERACCOUNTTYPE']._serialized_start=6128 + _globals['_USERACCOUNTTYPE']._serialized_end=6274 + _globals['_BILLINGSTATUS']._serialized_start=6277 + _globals['_BILLINGSTATUS']._serialized_end=6446 + _globals['_ACCOUNTSTATUS']._serialized_start=6449 + _globals['_ACCOUNTSTATUS']._serialized_end=6717 + _globals['_ACCOUNTROLE']._serialized_start=6720 + _globals['_ACCOUNTROLE']._serialized_end=6879 _globals['_GETUSERREQUEST']._serialized_start=113 _globals['_GETUSERREQUEST']._serialized_end=129 _globals['_GETUSERRESPONSE']._serialized_start=131 @@ -148,76 +148,76 @@ _globals['_CREATETEAMACCOUNTREQUEST']._serialized_end=1690 _globals['_CREATETEAMACCOUNTRESPONSE']._serialized_start=1693 _globals['_CREATETEAMACCOUNTRESPONSE']._serialized_end=1831 - _globals['_ACCOUNTUSER']._serialized_start=1833 - _globals['_ACCOUNTUSER']._serialized_end=1926 - _globals['_GETTEAMACCOUNTMEMBERSREQUEST']._serialized_start=1928 - _globals['_GETTEAMACCOUNTMEMBERSREQUEST']._serialized_end=1999 - _globals['_GETTEAMACCOUNTMEMBERSRESPONSE']._serialized_start=2001 - _globals['_GETTEAMACCOUNTMEMBERSRESPONSE']._serialized_end=2082 - _globals['_REMOVETEAMACCOUNTMEMBERREQUEST']._serialized_start=2084 - _globals['_REMOVETEAMACCOUNTMEMBERREQUEST']._serialized_end=2192 - _globals['_REMOVETEAMACCOUNTMEMBERRESPONSE']._serialized_start=2194 - _globals['_REMOVETEAMACCOUNTMEMBERRESPONSE']._serialized_end=2227 - _globals['_INVITEUSERTOTEAMACCOUNTREQUEST']._serialized_start=2229 - _globals['_INVITEUSERTOTEAMACCOUNTREQUEST']._serialized_end=2333 - _globals['_ACCOUNTINVITE']._serialized_start=2336 - _globals['_ACCOUNTINVITE']._serialized_end=2685 - _globals['_INVITEUSERTOTEAMACCOUNTRESPONSE']._serialized_start=2687 - _globals['_INVITEUSERTOTEAMACCOUNTRESPONSE']._serialized_end=2774 - _globals['_GETTEAMACCOUNTINVITESREQUEST']._serialized_start=2776 - _globals['_GETTEAMACCOUNTINVITESREQUEST']._serialized_end=2847 - _globals['_GETTEAMACCOUNTINVITESRESPONSE']._serialized_start=2849 - _globals['_GETTEAMACCOUNTINVITESRESPONSE']._serialized_end=2936 - _globals['_REMOVETEAMACCOUNTINVITEREQUEST']._serialized_start=2938 - _globals['_REMOVETEAMACCOUNTINVITEREQUEST']._serialized_end=2996 - _globals['_REMOVETEAMACCOUNTINVITERESPONSE']._serialized_start=2998 - _globals['_REMOVETEAMACCOUNTINVITERESPONSE']._serialized_end=3031 - _globals['_ACCEPTTEAMACCOUNTINVITEREQUEST']._serialized_start=3033 - _globals['_ACCEPTTEAMACCOUNTINVITEREQUEST']._serialized_end=3096 - _globals['_ACCEPTTEAMACCOUNTINVITERESPONSE']._serialized_start=3098 - _globals['_ACCEPTTEAMACCOUNTINVITERESPONSE']._serialized_end=3185 - _globals['_GETSYSTEMINFORMATIONREQUEST']._serialized_start=3187 - _globals['_GETSYSTEMINFORMATIONREQUEST']._serialized_end=3216 - _globals['_GETSYSTEMINFORMATIONRESPONSE']._serialized_start=3219 - _globals['_GETSYSTEMINFORMATIONRESPONSE']._serialized_end=3414 - _globals['_GETACCOUNTONBOARDINGCONFIGREQUEST']._serialized_start=3416 - _globals['_GETACCOUNTONBOARDINGCONFIGREQUEST']._serialized_end=3492 - _globals['_GETACCOUNTONBOARDINGCONFIGRESPONSE']._serialized_start=3494 - _globals['_GETACCOUNTONBOARDINGCONFIGRESPONSE']._serialized_end=3594 - _globals['_SETACCOUNTONBOARDINGCONFIGREQUEST']._serialized_start=3597 - _globals['_SETACCOUNTONBOARDINGCONFIGREQUEST']._serialized_end=3737 - _globals['_SETACCOUNTONBOARDINGCONFIGRESPONSE']._serialized_start=3739 - _globals['_SETACCOUNTONBOARDINGCONFIGRESPONSE']._serialized_end=3839 - _globals['_ACCOUNTONBOARDINGCONFIG']._serialized_start=3842 - _globals['_ACCOUNTONBOARDINGCONFIG']._serialized_end=4157 - _globals['_GETACCOUNTSTATUSREQUEST']._serialized_start=4159 - _globals['_GETACCOUNTSTATUSREQUEST']._serialized_end=4225 - _globals['_GETACCOUNTSTATUSRESPONSE']._serialized_start=4228 - _globals['_GETACCOUNTSTATUSRESPONSE']._serialized_end=4457 - _globals['_ISACCOUNTSTATUSVALIDREQUEST']._serialized_start=4460 - _globals['_ISACCOUNTSTATUSVALIDREQUEST']._serialized_end=4616 - _globals['_ISACCOUNTSTATUSVALIDRESPONSE']._serialized_start=4619 - _globals['_ISACCOUNTSTATUSVALIDRESPONSE']._serialized_end=5038 - _globals['_GETACCOUNTBILLINGCHECKOUTSESSIONREQUEST']._serialized_start=5040 - _globals['_GETACCOUNTBILLINGCHECKOUTSESSIONREQUEST']._serialized_end=5122 - _globals['_GETACCOUNTBILLINGCHECKOUTSESSIONRESPONSE']._serialized_start=5124 - _globals['_GETACCOUNTBILLINGCHECKOUTSESSIONRESPONSE']._serialized_end=5216 - _globals['_GETACCOUNTBILLINGPORTALSESSIONREQUEST']._serialized_start=5218 - _globals['_GETACCOUNTBILLINGPORTALSESSIONREQUEST']._serialized_end=5298 - _globals['_GETACCOUNTBILLINGPORTALSESSIONRESPONSE']._serialized_start=5300 - _globals['_GETACCOUNTBILLINGPORTALSESSIONRESPONSE']._serialized_end=5386 - _globals['_GETBILLINGACCOUNTSREQUEST']._serialized_start=5388 - _globals['_GETBILLINGACCOUNTSREQUEST']._serialized_end=5448 - _globals['_GETBILLINGACCOUNTSRESPONSE']._serialized_start=5450 - _globals['_GETBILLINGACCOUNTSRESPONSE']._serialized_end=5534 - _globals['_SETBILLINGMETEREVENTREQUEST']._serialized_start=5537 - _globals['_SETBILLINGMETEREVENTREQUEST']._serialized_end=5763 - _globals['_SETBILLINGMETEREVENTRESPONSE']._serialized_start=5765 - _globals['_SETBILLINGMETEREVENTRESPONSE']._serialized_end=5795 - _globals['_SETUSERROLEREQUEST']._serialized_start=5798 - _globals['_SETUSERROLEREQUEST']._serialized_end=5942 - _globals['_SETUSERROLERESPONSE']._serialized_start=5944 - _globals['_SETUSERROLERESPONSE']._serialized_end=5965 - _globals['_USERACCOUNTSERVICE']._serialized_start=6722 - _globals['_USERACCOUNTSERVICE']._serialized_end=9658 + _globals['_ACCOUNTUSER']._serialized_start=1834 + _globals['_ACCOUNTUSER']._serialized_end=1975 + _globals['_GETTEAMACCOUNTMEMBERSREQUEST']._serialized_start=1977 + _globals['_GETTEAMACCOUNTMEMBERSREQUEST']._serialized_end=2048 + _globals['_GETTEAMACCOUNTMEMBERSRESPONSE']._serialized_start=2050 + _globals['_GETTEAMACCOUNTMEMBERSRESPONSE']._serialized_end=2131 + _globals['_REMOVETEAMACCOUNTMEMBERREQUEST']._serialized_start=2133 + _globals['_REMOVETEAMACCOUNTMEMBERREQUEST']._serialized_end=2241 + _globals['_REMOVETEAMACCOUNTMEMBERRESPONSE']._serialized_start=2243 + _globals['_REMOVETEAMACCOUNTMEMBERRESPONSE']._serialized_end=2276 + _globals['_INVITEUSERTOTEAMACCOUNTREQUEST']._serialized_start=2279 + _globals['_INVITEUSERTOTEAMACCOUNTREQUEST']._serialized_end=2445 + _globals['_ACCOUNTINVITE']._serialized_start=2448 + _globals['_ACCOUNTINVITE']._serialized_end=2845 + _globals['_INVITEUSERTOTEAMACCOUNTRESPONSE']._serialized_start=2847 + _globals['_INVITEUSERTOTEAMACCOUNTRESPONSE']._serialized_end=2934 + _globals['_GETTEAMACCOUNTINVITESREQUEST']._serialized_start=2936 + _globals['_GETTEAMACCOUNTINVITESREQUEST']._serialized_end=3007 + _globals['_GETTEAMACCOUNTINVITESRESPONSE']._serialized_start=3009 + _globals['_GETTEAMACCOUNTINVITESRESPONSE']._serialized_end=3096 + _globals['_REMOVETEAMACCOUNTINVITEREQUEST']._serialized_start=3098 + _globals['_REMOVETEAMACCOUNTINVITEREQUEST']._serialized_end=3156 + _globals['_REMOVETEAMACCOUNTINVITERESPONSE']._serialized_start=3158 + _globals['_REMOVETEAMACCOUNTINVITERESPONSE']._serialized_end=3191 + _globals['_ACCEPTTEAMACCOUNTINVITEREQUEST']._serialized_start=3193 + _globals['_ACCEPTTEAMACCOUNTINVITEREQUEST']._serialized_end=3256 + _globals['_ACCEPTTEAMACCOUNTINVITERESPONSE']._serialized_start=3258 + _globals['_ACCEPTTEAMACCOUNTINVITERESPONSE']._serialized_end=3345 + _globals['_GETSYSTEMINFORMATIONREQUEST']._serialized_start=3347 + _globals['_GETSYSTEMINFORMATIONREQUEST']._serialized_end=3376 + _globals['_GETSYSTEMINFORMATIONRESPONSE']._serialized_start=3379 + _globals['_GETSYSTEMINFORMATIONRESPONSE']._serialized_end=3574 + _globals['_GETACCOUNTONBOARDINGCONFIGREQUEST']._serialized_start=3576 + _globals['_GETACCOUNTONBOARDINGCONFIGREQUEST']._serialized_end=3652 + _globals['_GETACCOUNTONBOARDINGCONFIGRESPONSE']._serialized_start=3654 + _globals['_GETACCOUNTONBOARDINGCONFIGRESPONSE']._serialized_end=3754 + _globals['_SETACCOUNTONBOARDINGCONFIGREQUEST']._serialized_start=3757 + _globals['_SETACCOUNTONBOARDINGCONFIGREQUEST']._serialized_end=3897 + _globals['_SETACCOUNTONBOARDINGCONFIGRESPONSE']._serialized_start=3899 + _globals['_SETACCOUNTONBOARDINGCONFIGRESPONSE']._serialized_end=3999 + _globals['_ACCOUNTONBOARDINGCONFIG']._serialized_start=4002 + _globals['_ACCOUNTONBOARDINGCONFIG']._serialized_end=4317 + _globals['_GETACCOUNTSTATUSREQUEST']._serialized_start=4319 + _globals['_GETACCOUNTSTATUSREQUEST']._serialized_end=4385 + _globals['_GETACCOUNTSTATUSRESPONSE']._serialized_start=4388 + _globals['_GETACCOUNTSTATUSRESPONSE']._serialized_end=4617 + _globals['_ISACCOUNTSTATUSVALIDREQUEST']._serialized_start=4620 + _globals['_ISACCOUNTSTATUSVALIDREQUEST']._serialized_end=4776 + _globals['_ISACCOUNTSTATUSVALIDRESPONSE']._serialized_start=4779 + _globals['_ISACCOUNTSTATUSVALIDRESPONSE']._serialized_end=5198 + _globals['_GETACCOUNTBILLINGCHECKOUTSESSIONREQUEST']._serialized_start=5200 + _globals['_GETACCOUNTBILLINGCHECKOUTSESSIONREQUEST']._serialized_end=5282 + _globals['_GETACCOUNTBILLINGCHECKOUTSESSIONRESPONSE']._serialized_start=5284 + _globals['_GETACCOUNTBILLINGCHECKOUTSESSIONRESPONSE']._serialized_end=5376 + _globals['_GETACCOUNTBILLINGPORTALSESSIONREQUEST']._serialized_start=5378 + _globals['_GETACCOUNTBILLINGPORTALSESSIONREQUEST']._serialized_end=5458 + _globals['_GETACCOUNTBILLINGPORTALSESSIONRESPONSE']._serialized_start=5460 + _globals['_GETACCOUNTBILLINGPORTALSESSIONRESPONSE']._serialized_end=5546 + _globals['_GETBILLINGACCOUNTSREQUEST']._serialized_start=5548 + _globals['_GETBILLINGACCOUNTSREQUEST']._serialized_end=5608 + _globals['_GETBILLINGACCOUNTSRESPONSE']._serialized_start=5610 + _globals['_GETBILLINGACCOUNTSRESPONSE']._serialized_end=5694 + _globals['_SETBILLINGMETEREVENTREQUEST']._serialized_start=5697 + _globals['_SETBILLINGMETEREVENTREQUEST']._serialized_end=5923 + _globals['_SETBILLINGMETEREVENTRESPONSE']._serialized_start=5925 + _globals['_SETBILLINGMETEREVENTRESPONSE']._serialized_end=5955 + _globals['_SETUSERROLEREQUEST']._serialized_start=5958 + _globals['_SETUSERROLEREQUEST']._serialized_end=6102 + _globals['_SETUSERROLERESPONSE']._serialized_start=6104 + _globals['_SETUSERROLERESPONSE']._serialized_end=6125 + _globals['_USERACCOUNTSERVICE']._serialized_start=6882 + _globals['_USERACCOUNTSERVICE']._serialized_end=9818 # @@protoc_insertion_point(module_scope) diff --git a/python/src/neosync/mgmt/v1alpha1/user_account_pb2.pyi b/python/src/neosync/mgmt/v1alpha1/user_account_pb2.pyi index 2543c2a14a..ca9f68dd21 100644 --- a/python/src/neosync/mgmt/v1alpha1/user_account_pb2.pyi +++ b/python/src/neosync/mgmt/v1alpha1/user_account_pb2.pyi @@ -193,16 +193,18 @@ class CreateTeamAccountResponse(_message.Message): def __init__(self, account_id: _Optional[str] = ..., checkout_session_url: _Optional[str] = ...) -> None: ... class AccountUser(_message.Message): - __slots__ = ("id", "name", "image", "email") + __slots__ = ("id", "name", "image", "email", "role") ID_FIELD_NUMBER: _ClassVar[int] NAME_FIELD_NUMBER: _ClassVar[int] IMAGE_FIELD_NUMBER: _ClassVar[int] EMAIL_FIELD_NUMBER: _ClassVar[int] + ROLE_FIELD_NUMBER: _ClassVar[int] id: str name: str image: str email: str - def __init__(self, id: _Optional[str] = ..., name: _Optional[str] = ..., image: _Optional[str] = ..., email: _Optional[str] = ...) -> None: ... + role: AccountRole + def __init__(self, id: _Optional[str] = ..., name: _Optional[str] = ..., image: _Optional[str] = ..., email: _Optional[str] = ..., role: _Optional[_Union[AccountRole, str]] = ...) -> None: ... class GetTeamAccountMembersRequest(_message.Message): __slots__ = ("account_id",) @@ -229,15 +231,17 @@ class RemoveTeamAccountMemberResponse(_message.Message): def __init__(self) -> None: ... class InviteUserToTeamAccountRequest(_message.Message): - __slots__ = ("account_id", "email") + __slots__ = ("account_id", "email", "role") ACCOUNT_ID_FIELD_NUMBER: _ClassVar[int] EMAIL_FIELD_NUMBER: _ClassVar[int] + ROLE_FIELD_NUMBER: _ClassVar[int] account_id: str email: str - def __init__(self, account_id: _Optional[str] = ..., email: _Optional[str] = ...) -> None: ... + role: AccountRole + def __init__(self, account_id: _Optional[str] = ..., email: _Optional[str] = ..., role: _Optional[_Union[AccountRole, str]] = ...) -> None: ... class AccountInvite(_message.Message): - __slots__ = ("id", "account_id", "sender_user_id", "email", "token", "accepted", "created_at", "updated_at", "expires_at") + __slots__ = ("id", "account_id", "sender_user_id", "email", "token", "accepted", "created_at", "updated_at", "expires_at", "role") ID_FIELD_NUMBER: _ClassVar[int] ACCOUNT_ID_FIELD_NUMBER: _ClassVar[int] SENDER_USER_ID_FIELD_NUMBER: _ClassVar[int] @@ -247,6 +251,7 @@ class AccountInvite(_message.Message): CREATED_AT_FIELD_NUMBER: _ClassVar[int] UPDATED_AT_FIELD_NUMBER: _ClassVar[int] EXPIRES_AT_FIELD_NUMBER: _ClassVar[int] + ROLE_FIELD_NUMBER: _ClassVar[int] id: str account_id: str sender_user_id: str @@ -256,7 +261,8 @@ class AccountInvite(_message.Message): created_at: _timestamp_pb2.Timestamp updated_at: _timestamp_pb2.Timestamp expires_at: _timestamp_pb2.Timestamp - def __init__(self, id: _Optional[str] = ..., account_id: _Optional[str] = ..., sender_user_id: _Optional[str] = ..., email: _Optional[str] = ..., token: _Optional[str] = ..., accepted: bool = ..., created_at: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ..., updated_at: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ..., expires_at: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ...) -> None: ... + role: AccountRole + def __init__(self, id: _Optional[str] = ..., account_id: _Optional[str] = ..., sender_user_id: _Optional[str] = ..., email: _Optional[str] = ..., token: _Optional[str] = ..., accepted: bool = ..., created_at: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ..., updated_at: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ..., expires_at: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ..., role: _Optional[_Union[AccountRole, str]] = ...) -> None: ... class InviteUserToTeamAccountResponse(_message.Message): __slots__ = ("invite",)