From e15978af14ba74d77897679cef979f1c387e49ac Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Thu, 16 Apr 2026 13:47:02 +0200 Subject: [PATCH] feat: add billing account resource type and roles to membership model Signed-off-by: Sylwester Piskozub --- app/controlplane/pkg/authz/authz.go | 10 ++++++++++ app/controlplane/pkg/authz/membership.go | 12 +++++++----- .../pkg/data/ent/membership/membership.go | 4 ++-- app/controlplane/pkg/data/ent/migrate/schema.go | 6 +++--- .../pkg/data/ent/orginvitation/orginvitation.go | 2 +- 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/app/controlplane/pkg/authz/authz.go b/app/controlplane/pkg/authz/authz.go index d6e9aa228..090e38a75 100644 --- a/app/controlplane/pkg/authz/authz.go +++ b/app/controlplane/pkg/authz/authz.go @@ -106,6 +106,10 @@ const ( RoleProductViewer Role = "role:product:viewer" RoleProductAdmin Role = "role:product:admin" + // BillingAccount roles + RoleBillingAccountOwner Role = "role:billing_account:owner" + RoleBillingAccountAdmin Role = "role:billing_account:admin" + // Scope for instance admin tokens ScopeInstanceAdmin = "INSTANCE_ADMIN" ) @@ -356,6 +360,10 @@ var RolesMap = map[Role][]*Policy{ PolicyGroupRemoveMemberships, PolicyGroupUpdateMemberships, }, + + // BillingAccount roles + RoleBillingAccountOwner: {}, + RoleBillingAccountAdmin: {}, } // ServerOperationsMap is a map of server operations to their authorization requirements. @@ -484,6 +492,8 @@ func (Role) Values() (roles []string) { RoleGroupMaintainer, RoleProductAdmin, RoleProductViewer, + RoleBillingAccountOwner, + RoleBillingAccountAdmin, } { roles = append(roles, string(s)) } diff --git a/app/controlplane/pkg/authz/membership.go b/app/controlplane/pkg/authz/membership.go index 1733d36de..946c3b9b2 100644 --- a/app/controlplane/pkg/authz/membership.go +++ b/app/controlplane/pkg/authz/membership.go @@ -25,11 +25,12 @@ const ( MembershipTypeUser MembershipType = "user" MembershipTypeGroup MembershipType = "group" - ResourceTypeInstance ResourceType = "instance" - ResourceTypeOrganization ResourceType = "organization" - ResourceTypeProject ResourceType = "project" - ResourceTypeProduct ResourceType = "product" - ResourceTypeGroup ResourceType = "group" + ResourceTypeInstance ResourceType = "instance" + ResourceTypeOrganization ResourceType = "organization" + ResourceTypeProject ResourceType = "project" + ResourceTypeProduct ResourceType = "product" + ResourceTypeGroup ResourceType = "group" + ResourceTypeBillingAccount ResourceType = "billing_account" ) // Values implement https://pkg.go.dev/entgo.io/ent/schema/field#EnumValues @@ -50,6 +51,7 @@ func (ResourceType) Values() (values []string) { string(ResourceTypeProject), string(ResourceTypeGroup), string(ResourceTypeProduct), + string(ResourceTypeBillingAccount), ) return diff --git a/app/controlplane/pkg/data/ent/membership/membership.go b/app/controlplane/pkg/data/ent/membership/membership.go index 16defe85e..85c8cb7ef 100644 --- a/app/controlplane/pkg/data/ent/membership/membership.go +++ b/app/controlplane/pkg/data/ent/membership/membership.go @@ -119,7 +119,7 @@ var ( // RoleValidator is a validator for the "role" field enum values. It is called by the builders before save. func RoleValidator(r authz.Role) error { switch r { - case "role:instance:admin", "role:org:owner", "role:org:admin", "role:org:viewer", "role:org:member", "role:org:contributor", "role:project:admin", "role:project:viewer", "role:group:maintainer", "role:product:admin", "role:product:viewer": + case "role:instance:admin", "role:org:owner", "role:org:admin", "role:org:viewer", "role:org:member", "role:org:contributor", "role:project:admin", "role:project:viewer", "role:group:maintainer", "role:product:admin", "role:product:viewer", "role:billing_account:owner", "role:billing_account:admin": return nil default: return fmt.Errorf("membership: invalid enum value for role field: %q", r) @@ -139,7 +139,7 @@ func MembershipTypeValidator(mt authz.MembershipType) error { // ResourceTypeValidator is a validator for the "resource_type" field enum values. It is called by the builders before save. func ResourceTypeValidator(rt authz.ResourceType) error { switch rt { - case "instance", "organization", "project", "group", "product": + case "instance", "organization", "project", "group", "product", "billing_account": return nil default: return fmt.Errorf("membership: invalid enum value for resource_type field: %q", rt) diff --git a/app/controlplane/pkg/data/ent/migrate/schema.go b/app/controlplane/pkg/data/ent/migrate/schema.go index 8da75ff6b..8755feba6 100644 --- a/app/controlplane/pkg/data/ent/migrate/schema.go +++ b/app/controlplane/pkg/data/ent/migrate/schema.go @@ -331,10 +331,10 @@ var ( {Name: "current", Type: field.TypeBool, Default: false}, {Name: "created_at", Type: field.TypeTime, Default: "CURRENT_TIMESTAMP"}, {Name: "updated_at", Type: field.TypeTime, Default: "CURRENT_TIMESTAMP"}, - {Name: "role", Type: field.TypeEnum, Enums: []string{"role:instance:admin", "role:org:owner", "role:org:admin", "role:org:viewer", "role:org:member", "role:org:contributor", "role:project:admin", "role:project:viewer", "role:group:maintainer", "role:product:admin", "role:product:viewer"}}, + {Name: "role", Type: field.TypeEnum, Enums: []string{"role:instance:admin", "role:org:owner", "role:org:admin", "role:org:viewer", "role:org:member", "role:org:contributor", "role:project:admin", "role:project:viewer", "role:group:maintainer", "role:product:admin", "role:product:viewer", "role:billing_account:owner", "role:billing_account:admin"}}, {Name: "membership_type", Type: field.TypeEnum, Nullable: true, Enums: []string{"user", "group"}}, {Name: "member_id", Type: field.TypeUUID, Nullable: true}, - {Name: "resource_type", Type: field.TypeEnum, Nullable: true, Enums: []string{"instance", "organization", "project", "group", "product"}}, + {Name: "resource_type", Type: field.TypeEnum, Nullable: true, Enums: []string{"instance", "organization", "project", "group", "product", "billing_account"}}, {Name: "resource_id", Type: field.TypeUUID, Nullable: true}, {Name: "parent_id", Type: field.TypeUUID, Nullable: true}, {Name: "organization_memberships", Type: field.TypeUUID, Nullable: true}, @@ -396,7 +396,7 @@ var ( {Name: "status", Type: field.TypeEnum, Enums: []string{"accepted", "pending"}, Default: "pending"}, {Name: "created_at", Type: field.TypeTime, Default: "CURRENT_TIMESTAMP"}, {Name: "deleted_at", Type: field.TypeTime, Nullable: true}, - {Name: "role", Type: field.TypeEnum, Nullable: true, Enums: []string{"role:instance:admin", "role:org:owner", "role:org:admin", "role:org:viewer", "role:org:member", "role:org:contributor", "role:project:admin", "role:project:viewer", "role:group:maintainer", "role:product:admin", "role:product:viewer"}}, + {Name: "role", Type: field.TypeEnum, Nullable: true, Enums: []string{"role:instance:admin", "role:org:owner", "role:org:admin", "role:org:viewer", "role:org:member", "role:org:contributor", "role:project:admin", "role:project:viewer", "role:group:maintainer", "role:product:admin", "role:product:viewer", "role:billing_account:owner", "role:billing_account:admin"}}, {Name: "context", Type: field.TypeJSON, Nullable: true}, {Name: "organization_id", Type: field.TypeUUID}, {Name: "sender_id", Type: field.TypeUUID, Nullable: true}, diff --git a/app/controlplane/pkg/data/ent/orginvitation/orginvitation.go b/app/controlplane/pkg/data/ent/orginvitation/orginvitation.go index 4ac60b516..9d0b3109a 100644 --- a/app/controlplane/pkg/data/ent/orginvitation/orginvitation.go +++ b/app/controlplane/pkg/data/ent/orginvitation/orginvitation.go @@ -101,7 +101,7 @@ func StatusValidator(s biz.OrgInvitationStatus) error { // RoleValidator is a validator for the "role" field enum values. It is called by the builders before save. func RoleValidator(r authz.Role) error { switch r { - case "role:instance:admin", "role:org:owner", "role:org:admin", "role:org:viewer", "role:org:member", "role:org:contributor", "role:project:admin", "role:project:viewer", "role:group:maintainer", "role:product:admin", "role:product:viewer": + case "role:instance:admin", "role:org:owner", "role:org:admin", "role:org:viewer", "role:org:member", "role:org:contributor", "role:project:admin", "role:project:viewer", "role:group:maintainer", "role:product:admin", "role:product:viewer", "role:billing_account:owner", "role:billing_account:admin": return nil default: return fmt.Errorf("orginvitation: invalid enum value for role field: %q", r)