Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,12 @@ rspec:
- EDITION:
- ce
- ee
- cloud
variables:
FPROF: '1'
script:
- '[[ "$EDITION" = "ee" ]] || rm -rf extensions/ee/'
- '[[ "$EDITION" = "ce" ]] && rm -rf extensions/{ee,cloud}/'
- '[[ "$EDITION" = "ee" ]] && rm -rf extensions/cloud'
- bundle exec rspec --format doc --format RspecJunitFormatter --out rspec.xml | tee output || exit_code=$?
- |
echo -e "\e[0Ksection_start:`date +%s`:glpa_summary\r\e[0KHeader of the summary"
Expand Down Expand Up @@ -115,14 +117,16 @@ boot:production-mode:
- EDITION:
- ce
- ee
- cloud
variables:
POSTGRES_DB: sagittarius_production
POSTGRES_USER: sagittarius
POSTGRES_PASSWORD: sagittarius
RAILS_ENV: production
BUNDLE_WITHOUT: 'development:test'
script:
- '[[ "$EDITION" = "ee" ]] || rm -rf extensions/ee/'
- '[[ "$EDITION" = "ce" ]] && rm -rf extensions/{ee,cloud}/'
- '[[ "$EDITION" = "ee" ]] && rm -rf extensions/cloud'
- bundle exec rake db:prepare db:seed_fu
- bin/rails s &
- curl --fail -sv --retry 20 --retry-delay 3 --retry-connrefused http://127.0.0.1:3000/health/liveness
Expand Down
3 changes: 3 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ RSpec/DescribeClass:
- extensions/ee/spec/graphql/**/*
- extensions/ee/spec/requests/graphql/**/*
- extensions/ee/spec/requests/grpc/**/*
- extensions/cloud/spec/graphql/**/*
- extensions/cloud/spec/requests/graphql/**/*
- extensions/cloud/spec/requests/grpc/**/*

RSpec/ExampleLength:
Enabled: false
Expand Down
2 changes: 2 additions & 0 deletions app/graphql/types/application_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,5 @@ def legal_notice_url
end
end
end

Types::ApplicationType.prepend_extensions
4 changes: 2 additions & 2 deletions app/models/audit_event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ class AuditEvent < ApplicationRecord
namespace_member_deleted: 11,
organization_deleted: 12,
namespace_role_deleted: 13,
namespace_license_created: 14, # EE-specific
license_created: 14, # EE-specific
namespace_project_created: 15,
namespace_license_deleted: 16, # EE-specific
license_deleted: 16, # EE-specific
namespace_project_deleted: 17,
namespace_project_updated: 18,
runtime_created: 19,
Expand Down
6 changes: 3 additions & 3 deletions app/models/namespace_role_ability.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ class NamespaceRoleAbility < ApplicationRecord
delete_organization: { db: 8, description: 'Allows to delete the organization' },
delete_namespace_role: { db: 9, description: 'Allows the deletion of roles in a namespace' },
namespace_administrator: { db: 10, description: 'Allows to perform any action in the namespace' },
create_namespace_license: { db: 11, description: 'Allows to create a license for the namespace' }, # EE-specific
read_namespace_license: { db: 12, description: 'Allows to read the license of the namespace' }, # EE-specific
create_license: { db: 11, description: 'Allows to create a license for the namespace' }, # Cloud-specific
read_license: { db: 12, description: 'Allows to read the license of the namespace' }, # Cloud-specific
create_namespace_project: { db: 13, description: 'Allows to create a project in the namespace' },
read_namespace_project: { db: 14, description: 'Allows to read the project of the namespace' },
delete_namespace_license: { db: 15, description: 'Allows to delete the license of the namespace' }, # EE-specific
delete_license: { db: 15, description: 'Allows to delete the license of the namespace' }, # Cloud-specific
update_namespace_project: { db: 16, description: 'Allows to update the project of the namespace' },
delete_namespace_project: { db: 17, description: 'Allows to delete the project of the namespace' },
create_runtime: { db: 18, description: 'Allows to create a runtime globally or for the namespace' },
Expand Down
2 changes: 2 additions & 0 deletions app/policies/global_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ class GlobalPolicy < BasePolicy
enable :create_user
end
end

GlobalPolicy.prepend_extensions
2 changes: 0 additions & 2 deletions app/services/error_code.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ def self.error_codes
invalid_flow_setting: { description: 'The flow setting is invalid because of active model errors' },
invalid_namespace_member: { description: 'The namespace member is invalid because of active model errors' },
invalid_attachment: { description: 'The attachment is invalid because of active model errors' },
invalid_namespace_license: { description: 'The namespace license is invalid because of active model errors' },
invalid_flow: { description: 'The flow is invalid because of active model errors' },
project_not_found: { description: 'The namespace project with the given identifier was not found' },
runtime_not_found: { description: 'The runtime with the given identifier was not found' },
Expand All @@ -69,7 +68,6 @@ def self.error_codes
user_session_not_found: { description: 'The user session with the given identifier was not found' },
namespace_project_not_found: { description: 'The namespace project with the given identifier was not found' },
namespace_member_not_found: { description: 'The namespace member with the given identifier was not found' },
license_not_found: { description: 'The namespace license with the given identifier was not found' },
flow_type_not_found: { description: 'The flow type with the given identifier was not found' },
organization_not_found: { description: 'The organization with the given identifier was not found' },
invalid_function_id: { description: 'The function ID is invalid' },
Expand Down
2 changes: 1 addition & 1 deletion app/services/namespaces/members/invite_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def execute
protected

def validate_user_limit!(*)
# overridden in EE
# overridden in CLOUD
end
end
end
Expand Down
12 changes: 11 additions & 1 deletion app/services/users/create_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ def execute
return ServiceResponse.error(message: 'Missing permissions', error_code: :missing_permission)
end

transactional do
transactional do |t|
user = User.create(**params)
unless user.persisted?
return ServiceResponse.error(message: 'User is invalid', error_code: :invalid_user,
details: user.errors)
end

validate_user_limit!(t)

AuditService.audit(
:user_created,
author_id: current_authentication.user.id,
Expand All @@ -34,5 +36,13 @@ def execute
ServiceResponse.success(payload: user)
end
end

protected

def validate_user_limit!(*)
# overridden in EE
end
end
end

Users::CreateService.prepend_extensions
10 changes: 10 additions & 0 deletions app/services/users/identity/register_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ def execute
user.ensure_namespace
return ServiceResponse.error(error_code: :invalid_user, details: user.errors) unless user.persisted?

validate_user_limit!(t)

user_identity = UserIdentity.create(user: user, provider_id: provider_id, identifier: identifier)
unless user_identity.persisted?
t.rollback_and_return! ServiceResponse.error(error_code: :invalid_user_identity,
Expand All @@ -75,6 +77,14 @@ def execute
ServiceResponse.success(payload: user_session)
end
end

protected

def validate_user_limit!(*)
# overridden in EE
end
end
end
end

Users::Identity::RegisterService.prepend_extensions
10 changes: 10 additions & 0 deletions app/services/users/register_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ def execute
return ServiceResponse.error(message: 'User is invalid', error_code: :invalid_user, details: user.errors)
end

validate_user_limit!(t)

user_session = UserSession.create(user: user)
unless user_session.persisted?
t.rollback_and_return! ServiceResponse.error(message: 'UserSession is invalid',
Expand Down Expand Up @@ -55,5 +57,13 @@ def execute
ServiceResponse.success(payload: user_session)
end
end

protected

def validate_user_limit!(*)
# overridden in EE
end
end
end

Users::RegisterService.prepend_extensions
1 change: 1 addition & 0 deletions config/initializers/inflections.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@

ActiveSupport::Inflector.inflections do |inflect|
inflect.acronym 'EE'
inflect.acronym 'CLOUD'
end
8 changes: 8 additions & 0 deletions db/migrate/20260427172623_change_license_to_global_object.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

class ChangeLicenseToGlobalObject < Code0::ZeroTrack::Database::Migration[1.0]
def change
rename_table :namespace_licenses, :licenses
change_column_null :licenses, :namespace_id, true
end
end
1 change: 1 addition & 0 deletions db/schema_migrations/20260427172623
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
d331bc990e7fbe15476ae12a6be85dd89d0b1a8495ca49cf6ad817b06704a18f
18 changes: 9 additions & 9 deletions db/structure.sql
Original file line number Diff line number Diff line change
Expand Up @@ -394,22 +394,22 @@ CREATE TABLE good_jobs (
locked_at timestamp with time zone
);

CREATE TABLE namespace_licenses (
CREATE TABLE licenses (
id bigint NOT NULL,
data text NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
namespace_id bigint NOT NULL
namespace_id bigint
);

CREATE SEQUENCE namespace_licenses_id_seq
CREATE SEQUENCE licenses_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;

ALTER SEQUENCE namespace_licenses_id_seq OWNED BY namespace_licenses.id;
ALTER SEQUENCE licenses_id_seq OWNED BY licenses.id;

CREATE TABLE namespace_member_roles (
id bigint NOT NULL,
Expand Down Expand Up @@ -923,7 +923,7 @@ ALTER TABLE ONLY flows ALTER COLUMN id SET DEFAULT nextval('flows_id_seq'::regcl

ALTER TABLE ONLY function_definitions ALTER COLUMN id SET DEFAULT nextval('function_definitions_id_seq'::regclass);

ALTER TABLE ONLY namespace_licenses ALTER COLUMN id SET DEFAULT nextval('namespace_licenses_id_seq'::regclass);
ALTER TABLE ONLY licenses ALTER COLUMN id SET DEFAULT nextval('licenses_id_seq'::regclass);

ALTER TABLE ONLY namespace_member_roles ALTER COLUMN id SET DEFAULT nextval('namespace_member_roles_id_seq'::regclass);

Expand Down Expand Up @@ -1041,8 +1041,8 @@ ALTER TABLE ONLY good_job_settings
ALTER TABLE ONLY good_jobs
ADD CONSTRAINT good_jobs_pkey PRIMARY KEY (id);

ALTER TABLE ONLY namespace_licenses
ADD CONSTRAINT namespace_licenses_pkey PRIMARY KEY (id);
ALTER TABLE ONLY licenses
ADD CONSTRAINT licenses_pkey PRIMARY KEY (id);

ALTER TABLE ONLY namespace_member_roles
ADD CONSTRAINT namespace_member_roles_pkey PRIMARY KEY (id);
Expand Down Expand Up @@ -1212,7 +1212,7 @@ CREATE INDEX index_good_jobs_on_queue_name_and_scheduled_at ON good_jobs USING b

CREATE INDEX index_good_jobs_on_scheduled_at ON good_jobs USING btree (scheduled_at) WHERE (finished_at IS NULL);

CREATE INDEX index_namespace_licenses_on_namespace_id ON namespace_licenses USING btree (namespace_id);
CREATE INDEX index_licenses_on_namespace_id ON licenses USING btree (namespace_id);

CREATE INDEX index_namespace_member_roles_on_member_id ON namespace_member_roles USING btree (member_id);

Expand Down Expand Up @@ -1307,7 +1307,7 @@ ALTER TABLE ONLY node_parameters
ALTER TABLE ONLY flow_type_data_type_links
ADD CONSTRAINT fk_rails_38698de52d FOREIGN KEY (referenced_data_type_id) REFERENCES data_types(id) ON DELETE RESTRICT;

ALTER TABLE ONLY namespace_licenses
ALTER TABLE ONLY licenses
ADD CONSTRAINT fk_rails_38f693332d FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;

ALTER TABLE ONLY runtime_features
Expand Down
4 changes: 2 additions & 2 deletions docs/graphql/enum/errorcodeenum.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ Represents the available error responses
| `INVALID_FLOW_SETTING` | The flow setting is invalid because of active model errors |
| `INVALID_FLOW_TYPE` | The flow type is invalid because of active model errors |
| `INVALID_FUNCTION_ID` | The function ID is invalid |
| `INVALID_LICENSE` | The license is invalid because of active model errors |
| `INVALID_LOGIN_DATA` | Invalid login data provided |
| `INVALID_NAMESPACE_LICENSE` | The namespace license is invalid because of active model errors |
| `INVALID_NAMESPACE_MEMBER` | The namespace member is invalid because of active model errors |
| `INVALID_NAMESPACE_PROJECT` | The namespace project is invalid because of active model errors |
| `INVALID_NAMESPACE_ROLE` | The namespace role is invalid because of active model errors |
Expand All @@ -56,7 +56,7 @@ Represents the available error responses
| `INVALID_USER_SESSION` | The user session is invalid because of active model errors |
| `INVALID_VERIFICATION_CODE` | Invalid verification code provided |
| `IS_PRIMARY_RUNTIME` | This runtime is the primary runtime of a project |
| `LICENSE_NOT_FOUND` | The namespace license with the given identifier was not found |
| `LICENSE_NOT_FOUND` | The license with the given identifier was not found |
| `LOADING_IDENTITY_FAILED` | Failed to load user identity from external provider |
| `MFA_FAILED` | Invalid MFA data provided |
| `MFA_REQUIRED` | MFA is required |
Expand Down
6 changes: 3 additions & 3 deletions docs/graphql/enum/namespaceroleability.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@ Represents abilities that can be granted to roles in namespaces.
| `ASSIGN_ROLE_ABILITIES` | Allows to change the abilities of a namespace role |
| `ASSIGN_ROLE_PROJECTS` | Allows to change the assigned projects of a namespace role |
| `CREATE_FLOW` | Allows to create flows in a namespace project |
| `CREATE_NAMESPACE_LICENSE` | Allows to create a license for the namespace |
| `CREATE_LICENSE` | Allows to create a license for the namespace |
| `CREATE_NAMESPACE_PROJECT` | Allows to create a project in the namespace |
| `CREATE_NAMESPACE_ROLE` | Allows the creation of roles in a namespace |
| `CREATE_RUNTIME` | Allows to create a runtime globally or for the namespace |
| `DELETE_FLOW` | Allows to delete flows in a namespace project |
| `DELETE_LICENSE` | Allows to delete the license of the namespace |
| `DELETE_MEMBER` | Allows to remove members of a namespace |
| `DELETE_NAMESPACE_LICENSE` | Allows to delete the license of the namespace |
| `DELETE_NAMESPACE_PROJECT` | Allows to delete the project of the namespace |
| `DELETE_NAMESPACE_ROLE` | Allows the deletion of roles in a namespace |
| `DELETE_ORGANIZATION` | Allows to delete the organization |
| `DELETE_RUNTIME` | Allows to delete a runtime |
| `INVITE_MEMBER` | Allows to invite new members to a namespace |
| `NAMESPACE_ADMINISTRATOR` | Allows to perform any action in the namespace |
| `READ_NAMESPACE_LICENSE` | Allows to read the license of the namespace |
| `READ_LICENSE` | Allows to read the license of the namespace |
| `READ_NAMESPACE_PROJECT` | Allows to read the project of the namespace |
| `ROTATE_RUNTIME_TOKEN` | Allows to regenerate a runtime token |
| `UPDATE_FLOW` | Allows to update flows in the project |
Expand Down
20 changes: 20 additions & 0 deletions docs/graphql/mutation/licensescreate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
title: licensesCreate
---

(EE only) Create a new license.

## Arguments

| Name | Type | Description |
|------|------|-------------|
| `clientMutationId` | [`String`](../scalar/string.md) | A unique identifier for the client performing the mutation. |
| `data` | [`String!`](../scalar/string.md) | The license data. |

## Fields

| Name | Type | Description |
|------|------|-------------|
| `clientMutationId` | [`String`](../scalar/string.md) | A unique identifier for the client performing the mutation. |
| `errors` | [`[Error!]!`](../object/error.md) | Errors encountered during execution of the mutation. |
| `license` | [`License`](../object/license.md) | The newly created license. |
20 changes: 20 additions & 0 deletions docs/graphql/mutation/licensesdelete.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
title: licensesDelete
---

(EE only) Deletes an license.

## Arguments

| Name | Type | Description |
|------|------|-------------|
| `clientMutationId` | [`String`](../scalar/string.md) | A unique identifier for the client performing the mutation. |
| `licenseId` | [`LicenseID!`](../scalar/licenseid.md) | The license id to delete. |

## Fields

| Name | Type | Description |
|------|------|-------------|
| `clientMutationId` | [`String`](../scalar/string.md) | A unique identifier for the client performing the mutation. |
| `errors` | [`[Error!]!`](../object/error.md) | Errors encountered during execution of the mutation. |
| `license` | [`License`](../object/license.md) | The deleted license. |
4 changes: 2 additions & 2 deletions docs/graphql/mutation/namespaceslicensescreate.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: namespacesLicensesCreate
---

(EE only) Create a new namespace license.
(Cloud only) Create a new namespace license.

## Arguments

Expand All @@ -18,4 +18,4 @@ title: namespacesLicensesCreate
|------|------|-------------|
| `clientMutationId` | [`String`](../scalar/string.md) | A unique identifier for the client performing the mutation. |
| `errors` | [`[Error!]!`](../object/error.md) | Errors encountered during execution of the mutation. |
| `namespaceLicense` | [`NamespaceLicense`](../object/namespacelicense.md) | The newly created license. |
| `license` | [`License`](../object/license.md) | The newly created license. |
6 changes: 3 additions & 3 deletions docs/graphql/mutation/namespaceslicensesdelete.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@
title: namespacesLicensesDelete
---

(EE only) Deletes an namespace license.
(Cloud only) Deletes an namespace license.

## Arguments

| Name | Type | Description |
|------|------|-------------|
| `clientMutationId` | [`String`](../scalar/string.md) | A unique identifier for the client performing the mutation. |
| `namespaceLicenseId` | [`NamespaceLicenseID!`](../scalar/namespacelicenseid.md) | The license id to delete. |
| `licenseId` | [`LicenseID!`](../scalar/licenseid.md) | The license id to delete. |

## Fields

| Name | Type | Description |
|------|------|-------------|
| `clientMutationId` | [`String`](../scalar/string.md) | A unique identifier for the client performing the mutation. |
| `errors` | [`[Error!]!`](../object/error.md) | Errors encountered during execution of the mutation. |
| `namespaceLicense` | [`NamespaceLicense`](../object/namespacelicense.md) | The deleted namespace license. |
| `license` | [`License`](../object/license.md) | The deleted license. |
2 changes: 2 additions & 0 deletions docs/graphql/object/application.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ Represents the application instance

| Name | Type | Description |
|------|------|-------------|
| `currentLicense` | [`License`](../object/license.md) | (EE only) Currently active license of the instance |
| `legalNoticeUrl` | [`String`](../scalar/string.md) | URL to the legal notice page |
| `licenses` | [`LicenseConnection!`](../object/licenseconnection.md) | (EE only) Licenses of the instance |
| `metadata` | [`Metadata`](../object/metadata.md) | Metadata about the application |
| `privacyUrl` | [`String`](../scalar/string.md) | URL to the privacy policy page |
| `settings` | [`ApplicationSettings`](../object/applicationsettings.md) | Global application settings |
Expand Down
Loading