Skip to content

Commit

Permalink
Merge branch 'develop' into server-4772
Browse files Browse the repository at this point in the history
  • Loading branch information
techsmyth authored Dec 21, 2024
2 parents c144bd2 + 1a249ca commit d285280
Show file tree
Hide file tree
Showing 12 changed files with 282 additions and 98 deletions.
2 changes: 2 additions & 0 deletions src/domain/space/account/account.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { TemporaryStorageModule } from '@services/infrastructure/temporary-stora
import { LicenseModule } from '@domain/common/license/license.module';
import { AccountLicenseService } from './account.service.license';
import { LicensingFrameworkModule } from '@platform/licensing/credential-based/licensing-framework/licensing.framework.module';
import { LicensingWingbackSubscriptionModule } from '@platform/licensing/wingback-subscription/licensing.wingback.subscription.module';

@Module({
imports: [
Expand All @@ -40,6 +41,7 @@ import { LicensingFrameworkModule } from '@platform/licensing/credential-based/l
LicensingFrameworkModule,
LicenseIssuerModule,
LicensingCredentialBasedModule,
LicensingWingbackSubscriptionModule,
LicenseModule,
SpaceModule,
InnovationHubModule,
Expand Down
116 changes: 39 additions & 77 deletions src/domain/space/account/account.service.license.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,20 @@ import { IAgent } from '@domain/agent/agent/agent.interface';
import { LicenseService } from '@domain/common/license/license.service';
import { ILicense } from '@domain/common/license/license.interface';
import { LicensingCredentialBasedService } from '@platform/licensing/credential-based/licensing-credential-based-entitlements-engine/licensing.credential.based.service';
import { LicenseEntitlementType } from '@common/enums/license.entitlement.type';
import { IAccount } from './account.interface';
import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston';
import { SpaceLicenseService } from '../space/space.service.license';
import { LicensingWingbackSubscriptionService } from '@platform/licensing/wingback-subscription/licensing.wingback.subscription.service';
import { ILicenseEntitlement } from '@domain/common/license-entitlement/license.entitlement.interface';

@Injectable()
export class AccountLicenseService {
constructor(
private licenseService: LicenseService,
private accountService: AccountService,
private licenseEngineService: LicensingCredentialBasedService,
private spaceLicenseService: SpaceLicenseService,
private licensingCredentialBasedService: LicensingCredentialBasedService,
private licensingWingbackSubscriptionService: LicensingWingbackSubscriptionService,
@Inject(WINSTON_MODULE_NEST_PROVIDER) private readonly logger: LoggerService
) {}

Expand Down Expand Up @@ -81,90 +83,50 @@ export class AccountLicenseService {
LogContext.LICENSE
);
}

// First check the credential based licensing based on the Agent held credentials
for (const entitlement of license.entitlements) {
switch (entitlement.type) {
case LicenseEntitlementType.ACCOUNT_SPACE_FREE:
const createSpace =
await this.licenseEngineService.isEntitlementGranted(
LicenseEntitlementType.ACCOUNT_SPACE_FREE,
accountAgent
);
if (createSpace) {
entitlement.limit = 3;
entitlement.enabled = true;
}
break;
case LicenseEntitlementType.ACCOUNT_SPACE_PLUS:
const createSpacePLus =
await this.licenseEngineService.isEntitlementGranted(
LicenseEntitlementType.ACCOUNT_SPACE_PLUS,
accountAgent
);
if (createSpacePLus) {
entitlement.limit = 0;
entitlement.enabled = true;
}
break;
case LicenseEntitlementType.ACCOUNT_SPACE_PREMIUM:
const createSpacePremium =
await this.licenseEngineService.isEntitlementGranted(
LicenseEntitlementType.ACCOUNT_SPACE_PREMIUM,
accountAgent
);
if (createSpacePremium) {
entitlement.limit = 0;
entitlement.enabled = true;
}
break;
case LicenseEntitlementType.ACCOUNT_VIRTUAL_CONTRIBUTOR:
const createVirtualContributor =
await this.licenseEngineService.isEntitlementGranted(
LicenseEntitlementType.ACCOUNT_VIRTUAL_CONTRIBUTOR,
accountAgent
);
if (createVirtualContributor) {
entitlement.limit = 3;
entitlement.enabled = true;
}
break;
case LicenseEntitlementType.ACCOUNT_INNOVATION_HUB:
const createInnovationHub =
await this.licenseEngineService.isEntitlementGranted(
LicenseEntitlementType.ACCOUNT_INNOVATION_HUB,
accountAgent
);
if (createInnovationHub) {
entitlement.limit = 1;
entitlement.enabled = true;
}
break;
case LicenseEntitlementType.ACCOUNT_INNOVATION_PACK:
const createInnovationPack =
await this.licenseEngineService.isEntitlementGranted(
LicenseEntitlementType.ACCOUNT_INNOVATION_PACK,
accountAgent
);
if (createInnovationPack) {
entitlement.limit = 3;
entitlement.enabled = true;
}
break;
default:
throw new EntityNotInitializedException(
`Unknown entitlement type for license: ${entitlement.type}`,
LogContext.LICENSE
);
}
await this.checkAndAssignGrantedEntitlement(entitlement, accountAgent);
}

// Then check the Wingback subscription service for any granted entitlements
if (account.externalSubscriptionID) {
// TODO: get subscription details from the WingBack api + set the entitlements accordingly
const wingbackGrantedLicenseEntitlements =
await this.licensingWingbackSubscriptionService.getEntitlements(
account.externalSubscriptionID
);
this.logger.verbose?.(
`Invoking external subscription service for account ${account.id}`,
`Invoking external subscription service for account ${account.id}, entitlements ${wingbackGrantedLicenseEntitlements}`,
LogContext.ACCOUNT
);
for (const entitlement of license.entitlements) {
const wingbackGrantedEntitlement =
wingbackGrantedLicenseEntitlements.find(
e => e.type === entitlement.type
);
// Note: for now overwrite the credential based entitlements with the Wingback entitlements
if (wingbackGrantedEntitlement) {
entitlement.limit = wingbackGrantedEntitlement.limit;
entitlement.enabled = true;
}
}
}

return license;
}

private async checkAndAssignGrantedEntitlement(
entitlement: ILicenseEntitlement,
accountAgent: IAgent
): Promise<void> {
const grantedEntitlement =
await this.licensingCredentialBasedService.getEntitlementIfGranted(
entitlement.type,
accountAgent
);
if (grantedEntitlement) {
entitlement.limit = grantedEntitlement.limit;
entitlement.enabled = true;
}
}
}
2 changes: 1 addition & 1 deletion src/migrations/1731500015640-licenseEntitlements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,7 @@ const licenseCredentialRules = [
{
credentialType: 'space-feature-save-as-template',
grantedEntitlements: [LicenseEntitlementType.SPACE_FLAG_SAVE_AS_TEMPLATE],
name: 'Space Save As Templatet',
name: 'Space Save As Template',
},
{
credentialType: 'space-license-free',
Expand Down
155 changes: 155 additions & 0 deletions src/migrations/1734708463555-licensePolicyLimits.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class LicensePolicyLimits1734708463555 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
const [licensePolicy]: {
id: string;
}[] = await queryRunner.query(`SELECT id FROM license_policy`);
await queryRunner.query(
`UPDATE license_policy SET credentialRulesStr = ? WHERE id = ?`,
[`${JSON.stringify(licenseCredentialRules)}`, licensePolicy.id]
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
console.log('No down migration needed');
}
}

type CredentialRule = {
credentialType: LicenseCredential;
grantedEntitlements: GrantedEntitlement[];
name: string;
};

type GrantedEntitlement = {
type: LicenseEntitlementType;
limit: number;
};

enum LicenseCredential {
SPACE_LICENSE_FREE = 'space-license-free',
SPACE_LICENSE_PLUS = 'space-license-plus',
SPACE_LICENSE_PREMIUM = 'space-license-premium',
SPACE_LICENSE_ENTERPRISE = 'space-license-enterprise', // todo: remove for space
SPACE_FEATURE_SAVE_AS_TEMPLATE = 'space-feature-save-as-template',
SPACE_FEATURE_VIRTUAL_CONTRIBUTORS = 'space-feature-virtual-contributors',
SPACE_FEATURE_WHITEBOARD_MULTI_USER = 'space-feature-whiteboard-multi-user',
ACCOUNT_LICENSE_PLUS = 'account-license-plus',
}

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',
}

const licenseCredentialRules: CredentialRule[] = [
{
credentialType: LicenseCredential.SPACE_FEATURE_VIRTUAL_CONTRIBUTORS,
grantedEntitlements: [
{
type: LicenseEntitlementType.SPACE_FLAG_VIRTUAL_CONTRIBUTOR_ACCESS,
limit: 1,
},
],
name: 'Space Virtual Contributors',
},
{
credentialType: LicenseCredential.SPACE_FEATURE_WHITEBOARD_MULTI_USER,
grantedEntitlements: [
{
type: LicenseEntitlementType.SPACE_FLAG_WHITEBOARD_MULTI_USER,
limit: 1,
},
],
name: 'Space Multi-user whiteboards',
},
{
credentialType: LicenseCredential.SPACE_FEATURE_SAVE_AS_TEMPLATE,
grantedEntitlements: [
{
type: LicenseEntitlementType.SPACE_FLAG_SAVE_AS_TEMPLATE,
limit: 1,
},
],
name: 'Space Save As Template',
},
{
credentialType: LicenseCredential.SPACE_LICENSE_FREE,
grantedEntitlements: [
{
type: LicenseEntitlementType.SPACE_FREE,
limit: 1,
},
],
name: 'Space License Free',
},
{
credentialType: LicenseCredential.SPACE_LICENSE_PLUS,
grantedEntitlements: [
{
type: LicenseEntitlementType.SPACE_PLUS,
limit: 1,
},
{
type: LicenseEntitlementType.SPACE_FLAG_WHITEBOARD_MULTI_USER,
limit: 1,
},
{
type: LicenseEntitlementType.SPACE_FLAG_SAVE_AS_TEMPLATE,
limit: 1,
},
],
name: 'Space License Plus',
},
{
credentialType: LicenseCredential.SPACE_LICENSE_PREMIUM,
grantedEntitlements: [
{
type: LicenseEntitlementType.SPACE_PREMIUM,
limit: 1,
},
{
type: LicenseEntitlementType.SPACE_FLAG_WHITEBOARD_MULTI_USER,
limit: 1,
},
{
type: LicenseEntitlementType.SPACE_FLAG_SAVE_AS_TEMPLATE,
limit: 1,
},
],
name: 'Space License Premium',
},
{
credentialType: LicenseCredential.ACCOUNT_LICENSE_PLUS,
grantedEntitlements: [
{
type: LicenseEntitlementType.ACCOUNT_SPACE_FREE,
limit: 3,
},
{
type: LicenseEntitlementType.ACCOUNT_VIRTUAL_CONTRIBUTOR,
limit: 3,
},
{
type: LicenseEntitlementType.ACCOUNT_INNOVATION_HUB,
limit: 1,
},
{
type: LicenseEntitlementType.ACCOUNT_INNOVATION_PACK,
limit: 3,
},
],
name: 'Account License Plus',
},
];
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { LicensingCredentialBasedService } from '@platform/licensing/credential-
import { LogContext } from '@common/enums/logging.context';
import { ILicensingCredentialBasedPolicyCredentialRule } from '@platform/licensing/credential-based/licensing-credential-based-entitlements-engine';
import { LicensingCredentialBasedCredentialType } from '@common/enums/licensing.credential.based.credential.type';
import { LicenseEntitlementType } from '@common/enums/license.entitlement.type';
import { LicensingGrantedEntitlement } from '@platform/licensing/dto/licensing.dto.granted.entitlement';

@Injectable()
export class LicensePolicyService {
Expand All @@ -22,7 +22,7 @@ export class LicensePolicyService {
) {}

createCredentialRule(
grantedEntitlements: LicenseEntitlementType[],
grantedEntitlements: LicensingGrantedEntitlement[],
credentialType: LicensingCredentialBasedCredentialType,
name: string
): ILicensingCredentialBasedPolicyCredentialRule {
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './licensing.credential.based.policy.rule.credential.interface';
export * from './licensing.credential.based.policy.credential.rule.interface';
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { LicensingCredentialBasedCredentialType } from '@common/enums/licensing.credential.based.credential.type';
import { LicenseEntitlementType } from '@common/enums/license.entitlement.type';
import { Field, ObjectType } from '@nestjs/graphql';
import { LicensingGrantedEntitlement } from '@platform/licensing/dto/licensing.dto.granted.entitlement';

@ObjectType('LicensingCredentialBasedPolicyCredentialRule')
export abstract class ILicensingCredentialBasedPolicyCredentialRule {
@Field(() => LicensingCredentialBasedCredentialType)
credentialType!: LicensingCredentialBasedCredentialType;

@Field(() => [LicenseEntitlementType])
grantedEntitlements!: LicenseEntitlementType[];
@Field(() => [LicensingGrantedEntitlement])
grantedEntitlements!: LicensingGrantedEntitlement[];

@Field(() => String, { nullable: true })
name?: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { LicensingCredentialBasedCredentialType } from '@common/enums/licensing.credential.based.credential.type';
import { ILicensingCredentialBasedPolicyCredentialRule } from './licensing.credential.based.policy.rule.credential.interface';
import { LicenseEntitlementType } from '@common/enums/license.entitlement.type';
import { ILicensingCredentialBasedPolicyCredentialRule } from './licensing.credential.based.policy.credential.rule.interface';
import { LicensingGrantedEntitlement } from '@platform/licensing/dto/licensing.dto.granted.entitlement';

export class LicensingCredentialBasedPolicyCredentialRule
implements ILicensingCredentialBasedPolicyCredentialRule
{
credentialType: LicensingCredentialBasedCredentialType;
grantedEntitlements: LicenseEntitlementType[];
grantedEntitlements: LicensingGrantedEntitlement[];
name: string;

constructor(
grantedEntitlements: LicenseEntitlementType[],
grantedEntitlements: LicensingGrantedEntitlement[],
credentialType: LicensingCredentialBasedCredentialType,
name: string
) {
Expand Down
Loading

0 comments on commit d285280

Please sign in to comment.