Skip to content

Commit

Permalink
Entitlements + license services (#4593)
Browse files Browse the repository at this point in the history
* first pass at two new modules for TemplatesManager, TemplateDefault

* added templates manager to space; removed the SpaceDefaults entity (module still present until move all data to be via defaults

* added templatesManager to platform

* moved creating of default innovatin flow input to space defaults

* back out space type on Template; tidy up Template module to use switch statements

* created template applier module

* tidy up naming

* updated set of default template types

* fixed circular dependency; moved logic for creating collaboration input to space defaults

* removed loading of defaults from files for collaboration content

* removed code based addition of callouts, innovation flow states

* tidy up naming

* added loading of default templates at platform level in to bootstrap

* removed option to create new innovation flow template

* added in migration:

* loading in templates on bootstrap

* added field for collaboration templates on templatesSet; added lookup for templatesManager

* added mutation to create template from collaboration; added logic to prevent template used as default to be deleted; fixed removal of template set on template manager

* initial creation of license + entitlements modules

* add license into account

* updated account to have license service + use that in mutations checking limits, removing notion of soft limits

* ensure data is loaded properly on account for license checking

* added mutation to reset the license calculations on account, including new auth privilege to be able to do so

* renamed Licensing module to LicensingFramework module; trigger license reset on Account after assigning / removing license

* removed usage of LicenseEngine outside of license services on space or account

* renamed entitlement to licenseEntitlement as entity; first pass at migration

* fixed issues in migration

* fixed issues related to auth reset; tidied up loader creator imports

* fixed auth cascade for templates of type post

* license reset running

* reset licenses on space after adding / removing license plans

* removed need for license check in community; added entitlement check in roleset when adding a VC

* remove auth reset when assigning / removing license plans

* added License to RoleSet

* added license to collaboration

* tidied up retrieval of license for whiteboard; added license to collaboration in migration

* fix typo; fix space spec file

* fix additional tests

* moved tempaltesManager to last migration in the list

* fixed retrieval of template when creating collaboration

* added logging

* fixed bootstrap setting of templates

* refactored inputCreator to do the data loading closer to usage; fixed picking up of templates; fixed bootstrap usage of templates

* added ability to retrieve limits on entitlements + current usage

* updated field names on entitlements

* updated field names on entitlements

* fixed account mutaiton logic bug

* ensure that licenses are reset when assigning beta tester or vc campaign role to a user

* added reset all account licenses mutation

* fixed bug on space entitlements; refactored code to reduce duplication

* fixed url generation for templates inside of TempaltesManager

* fixed bootstrap order to create forum earlier

* ensure collaboration creation on template provides some defaults for callouts

* fix deletion of templates of type post

* ensure more data is defaulted inside of template service for collaboration; add setting of isTemplate field on Collaboration, and also on contained Callouts

* ensure isTempalte is passed to Collaboration entity

* fixed groups in bootstrap space template; updated signature for creating callout from collaboration

* fixed missing field

* fixed type on mutation to create from collaboration

* fixed typo

* fixed groups in bootstrap space template; updated signature for creating callout from collaboration

* fixed missing field

* fixed type on mutation to create from collaboration

* fixed typo

* reworked applying collaboraiton template to collaboration

* improved error message in wrong type of ID passed in

* fixed build

* made migration last in the list

* rename migration to be last

* removed read check when looking up collaboration

* track free / plus / premium space entitlements separately

* updated migration order

* removed duplicate migration

* moved auth reset to mutation for applying the template to another collaboration

* extend lookup of entitlement usage to cover new types

* updaed license policy to reflect new entitlements; made license engine work with entitlements, not license privileges; removed license privilege (no longer relevant)

* updated migration to not drop indexes already removed

* fix for license reset on space

* added license policy rule for free space credential

* ensure license entitlements are reset as part of the bootstrap

* fixed typo

* extended reset all to include resetting licenses on accounts + AI server; moved migration to be last

* Address pr comment

* Address PR feedback

* Address PR comment

* Address PR comments

* Address PR comments

* Address PR comment

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Improved types & naming

* Address PR comments

* Fixed switch-case logic in entitlements

* Converge entitlements schema

* Remove unused AuthorizationPrivilege

---------

Co-authored-by: Carlos Cano <[email protected]>
Co-authored-by: Valentin Yanakiev <[email protected]>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
  • Loading branch information
4 people committed Nov 18, 2024
1 parent ae6ccd9 commit 367176a
Show file tree
Hide file tree
Showing 126 changed files with 3,342 additions and 776 deletions.
2 changes: 2 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ import { PlatformHubModule } from '@platform/platform.hub/platform.hub.module';
import { AdminContributorsModule } from '@platform/admin/avatars/admin.avatar.module';
import { InputCreatorModule } from '@services/api/input-creator/input.creator.module';
import { TemplateApplierModule } from '@domain/template/template-applier/template.applier.module';
import { LoaderCreatorModule } from '@core/dataloader/creators/loader.creator.module';
import { Cipher, EncryptionModule } from '@hedger/nestjs-encryption';
import { AdminUsersModule } from '@platform/admin/users/admin.users.module';

Expand Down Expand Up @@ -247,6 +248,7 @@ import { AdminUsersModule } from '@platform/admin/users/admin.users.module';
};
},
}),
LoaderCreatorModule,
ScalarsModule,
AuthenticationModule,
AuthorizationModule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ export const CREDENTIAL_RULE_TYPES_SPACE_COMMUNITY_APPLY_GLOBAL_REGISTERED =
'credentialRuleTypes-spaceCommunityApplyGlobalRegistered';
export const CREDENTIAL_RULE_TYPES_SPACE_COMMUNITY_JOIN_GLOBAL_REGISTERED =
'credentialRuleTypes-spaceCommunityJoinGlobalRegistered';
export const CREDENTIAL_RULE_TYPES_ACCESS_VIRTUAL_CONTRIBUTORS =
'credentialRuleTypes-accessVirtualContributors';
export const CREDENTIAL_RULE_TYPES_CALLOUT_SAVE_AS_TEMPLATE =
'credentialRuleTypes-calloutSaveAsTemplate';
export const CREDENTIAL_RULE_TYPES_CALLOUT_UPDATE_PUBLISHER_ADMINS =
Expand Down
2 changes: 2 additions & 0 deletions src/common/enums/alkemio.error.status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export enum AlkemioErrorStatus {
NOT_ENABLED = 'NOT_ENABLED',
USER_NOT_REGISTERED = 'USER_NOT_REGISTERED',
LICENSE_NOT_FOUND = 'LICENSE_NOT_FOUND',
LICENSE_ENTITLEMENT_NOT_AVAILABLE = 'LICENSE_ENTITLEMENT_NOT_AVAILABLE',
LICENSE_ENTITLEMENT_NOT_SUPPORTED = 'LICENSE_ENTITLEMENT_NOT_SUPPORTED',
MATRIX_ENTITY_NOT_FOUND_ERROR = 'MATRIX_ENTITY_NOT_FOUND_ERROR',
BOOTSTRAP_FAILED = 'BOOTSTRAP_FAILED',
NOTIFICATION_PAYLOAD_BUILDER_ERROR = 'NOTIFICATION_PAYLOAD_BUILDER_ERROR',
Expand Down
1 change: 1 addition & 0 deletions src/common/enums/authorization.policy.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export enum AuthorizationPolicyType {
LIBRARY = 'library',
IN_MEMORY = 'in-memory',
LICENSING = 'licensing',
LICENSE = 'license',
LICENSE_POLICY = 'license-policy',
UNKNOWN = 'unknown',
AI_PERSONA_SERVICE = 'ai-persona-service',
Expand Down
2 changes: 1 addition & 1 deletion src/common/enums/authorization.privilege.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export enum AuthorizationPrivilege {
GRANT = 'grant', // allow the issuing / revoking of credentials of the same type within a given scope
GRANT_GLOBAL_ADMINS = 'grant-global-admins',
AUTHORIZATION_RESET = 'authorization-reset',
LICENSE_RESET = 'license-reset',
PLATFORM_ADMIN = 'platform-admin', // To determine if the user should have access to the platform administration
CONTRIBUTE = 'contribute',
CREATE_CALLOUT = 'create-callout',
Expand Down Expand Up @@ -40,7 +41,6 @@ export enum AuthorizationPrivilege {
MOVE_POST = 'move-post',
MOVE_CONTRIBUTION = 'move-contribution',
ACCESS_INTERACTIVE_GUIDANCE = 'access-interactive-guidance',
ACCESS_VIRTUAL_CONTRIBUTOR = 'access-virtual-contributor',
UPDATE_CONTENT = 'update-content',
SAVE_AS_TEMPLATE = 'save-as-template',
TRANSFER_RESOURCE = 'transfer-resource',
Expand Down
10 changes: 10 additions & 0 deletions src/common/enums/license.entitlement.data.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { registerEnumType } from '@nestjs/graphql';

export enum LicenseEntitlementDataType {
LIMIT = 'limit',
FLAG = 'flag',
}

registerEnumType(LicenseEntitlementDataType, {
name: 'LicenseEntitlementDataType',
});
20 changes: 20 additions & 0 deletions src/common/enums/license.entitlement.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { registerEnumType } from '@nestjs/graphql';

export enum LicenseEntitlementType {
ACCOUNT_SPACE_FREE = 'account-space-free',
ACCOUNT_SPACE_PLUS = 'account-space-plus',
ACCOUNT_SPACE_PREMIUM = 'account-space-premium',
ACCOUNT_VIRTUAL_CONTRIBUTOR = 'account-virtual-contributor',
ACCOUNT_INNOVATION_PACK = 'account-innovation-pack',
ACCOUNT_INNOVATION_HUB = 'account-innovation-hub',
SPACE_FREE = 'space-free',
SPACE_PLUS = 'space-plus',
SPACE_PREMIUM = 'space-premium',
SPACE_FLAG_SAVE_AS_TEMPLATE = 'space-flag-save-as-template',
SPACE_FLAG_VIRTUAL_CONTRIBUTOR_ACCESS = 'space-flag-virtual-contributor-access',
SPACE_FLAG_WHITEBOARD_MULTI_USER = 'space-flag-whiteboard-multi-user',
}

registerEnumType(LicenseEntitlementType, {
name: 'LicenseEntitlementType',
});
15 changes: 0 additions & 15 deletions src/common/enums/license.privilege.ts

This file was deleted.

13 changes: 13 additions & 0 deletions src/common/enums/license.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { registerEnumType } from '@nestjs/graphql';

export enum LicenseType {
ACCOUNT = 'account',
SPACE = 'space',
WHITEBOARD = 'whiteboard',
ROLESET = 'roleset',
COLLABORATION = 'collaboration',
}

registerEnumType(LicenseType, {
name: 'LicenseType',
});
4 changes: 2 additions & 2 deletions src/common/exceptions/forbidden.license.policy.exception.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { AlkemioErrorStatus, LogContext } from '@common/enums';
import { BaseException } from './base.exception';
import { LicensePrivilege } from '@common/enums/license.privilege';
import { LicenseEntitlementType } from '@common/enums/license.entitlement.type';

export class ForbiddenLicensePolicyException extends BaseException {
constructor(
error: string,
public checkedPrivilege: LicensePrivilege,
public checkedEntitlement: LicenseEntitlementType,
public licensePolicyId: string,
public licenseId: string
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { LogContext, AlkemioErrorStatus } from '@common/enums';
import { BaseException } from './base.exception';

export class LicenseEntitlementNotAvailableException extends BaseException {
constructor(error: string, context: LogContext, code?: AlkemioErrorStatus) {
super(
error,
context,
code ?? AlkemioErrorStatus.LICENSE_ENTITLEMENT_NOT_AVAILABLE
);
}
}
12 changes: 12 additions & 0 deletions src/common/exceptions/license.entitlement.not.supported.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { LogContext, AlkemioErrorStatus } from '@common/enums';
import { BaseException } from './base.exception';

export class LicenseEntitlementNotSupportedException extends BaseException {
constructor(error: string, context: LogContext, code?: AlkemioErrorStatus) {
super(
error,
context,
code ?? AlkemioErrorStatus.LICENSE_ENTITLEMENT_NOT_SUPPORTED
);
}
}
6 changes: 4 additions & 2 deletions src/core/bootstrap/bootstrap.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,16 @@ import { ContributorModule } from '@domain/community/contributor/contributor.mod
import { TemplatesSetModule } from '@domain/template/templates-set/templates.set.module';
import { TemplatesManagerModule } from '@domain/template/templates-manager/templates.manager.module';
import { TemplateDefaultModule } from '@domain/template/template-default/template.default.module';
import { LicensingModule } from '@platform/licensing/licensing.module';
import { LicenseModule } from '@domain/common/license/license.module';
import { LicensePlanModule } from '@platform/license-plan/license.plan.module';
import { LicensingFrameworkModule } from '@platform/licensing-framework/licensing.framework.module';

@Module({
imports: [
AiServerModule,
AgentModule,
AuthorizationPolicyModule,
LicenseModule,
ContributorModule,
SpaceModule,
OrganizationModule,
Expand All @@ -43,7 +45,7 @@ import { LicensePlanModule } from '@platform/license-plan/license.plan.module';
TemplatesSetModule,
TemplatesManagerModule,
TemplateDefaultModule,
LicensingModule,
LicensingFrameworkModule,
LicensePlanModule,
],
providers: [BootstrapService],
Expand Down
21 changes: 17 additions & 4 deletions src/core/bootstrap/bootstrap.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,10 @@ import { bootstrapSpaceCallouts } from './platform-template-definitions/space/bo
import { bootstrapSpaceTutorialsInnovationFlowStates } from './platform-template-definitions/space-tutorials/bootstrap.space.tutorials.innovation.flow.states';
import { bootstrapSpaceTutorialsCalloutGroups } from './platform-template-definitions/space-tutorials/bootstrap.space.tutorials.callout.groups';
import { bootstrapSpaceTutorialsCallouts } from './platform-template-definitions/space-tutorials/bootstrap.space.tutorials.callouts';
import { LicensingService } from '@platform/licensing/licensing.service';
import { LicenseService } from '@domain/common/license/license.service';
import { AccountLicenseService } from '@domain/space/account/account.service.license';
import { LicensePlanService } from '@platform/license-plan/license.plan.service';
import { LicensingFrameworkService } from '@platform/licensing-framework/licensing.framework.service';

@Injectable()
export class BootstrapService {
Expand Down Expand Up @@ -84,7 +86,9 @@ export class BootstrapService {
private templatesManagerService: TemplatesManagerService,
private templatesSetService: TemplatesSetService,
private templateDefaultService: TemplateDefaultService,
private licensingService: LicensingService,
private accountLicenseService: AccountLicenseService,
private licenseService: LicenseService,
private licensingFrameworkService: LicensingFrameworkService,
private licensePlanService: LicensePlanService
) {}

Expand Down Expand Up @@ -273,14 +277,15 @@ export class BootstrapService {

async createLicensePlans(licensePlansData: any[]) {
try {
const licensing = await this.licensingService.getDefaultLicensingOrFail();
const licensing =
await this.licensingFrameworkService.getDefaultLicensingOrFail();
for (const licensePlanData of licensePlansData) {
const planExists =
await this.licensePlanService.licensePlanByNameExists(
licensePlanData.name
);
if (!planExists) {
await this.licensingService.createLicensePlan({
await this.licensingFrameworkService.createLicensePlan({
...licensePlanData,
licensingID: licensing.id,
});
Expand Down Expand Up @@ -454,6 +459,10 @@ export class BootstrapService {
account
);
await this.authorizationPolicyService.saveAll(accountAuthorizations);

const accountEntitlements =
await this.accountLicenseService.applyLicensePolicy(account.id);
await this.licenseService.saveAll(accountEntitlements);
}
}

Expand Down Expand Up @@ -508,6 +517,10 @@ export class BootstrapService {
await this.spaceAuthorizationService.applyAuthorizationPolicy(space);
await this.authorizationPolicyService.saveAll(spaceAuthorizations);

const accountEntitlements =
await this.accountLicenseService.applyLicensePolicy(account.id);
await this.licenseService.saveAll(accountEntitlements);

return this.spaceService.getSpaceOrFail(space.id);
}
}
Expand Down
1 change: 1 addition & 0 deletions src/core/dataloader/creators/loader.creators/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export * from './profile/profile.tagsets.loader.creator';
export * from './callout-framing/callout.framing.whiteboard.loader';

export * from './profile.loader.creator';
export * from './license.loader.creator';
export * from './preferences.loader.creator';
export * from './agent.loader.creator';
export * from './authorization.loader.creator';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { EntityManager } from 'typeorm';
import { Injectable } from '@nestjs/common';
import { InjectEntityManager } from '@nestjs/typeorm';
import { DataLoaderInitError } from '@common/exceptions/data-loader';
import { createTypedRelationDataLoader } from '../../utils';
import { DataLoaderCreator, DataLoaderCreatorOptions } from '../base';
import { ILicense } from '@domain/common/license/license.interface';
import { License } from '@domain/common/license/license.entity';

@Injectable()
export class LicenseLoaderCreator implements DataLoaderCreator<ILicense> {
constructor(@InjectEntityManager() private manager: EntityManager) {}

create(
options?: DataLoaderCreatorOptions<
ILicense,
{ id: string; license?: License }
>
) {
if (!options?.parentClassRef) {
throw new DataLoaderInitError(
`${this.constructor.name} requires the 'parentClassRef' to be provided.`
);
}

return createTypedRelationDataLoader(
this.manager,
options.parentClassRef,
{
license: true,
},
this.constructor.name,
options
);
}
}
Loading

0 comments on commit 367176a

Please sign in to comment.