UNPKG

@sourceloop/ctrl-plane-tenant-management-service

Version:

Tenant Management microservice for SaaS control plane

289 lines (276 loc) 7.02 kB
import { Count, CountSchema, Filter, repository, Where, } from '@loopback/repository'; import { del, get, getModelSchemaRef, param, patch, post, put, requestBody, } from '@loopback/rest'; import { CONTENT_TYPE, OPERATION_SECURITY_SPEC, STATUS_CODE, } from '@sourceloop/core'; import {authenticate, STRATEGY} from 'loopback4-authentication'; import {authorize} from 'loopback4-authorization'; import {TenantRepository} from '../repositories/tenant.repository'; import {SubscriptionDTO, Tenant, TenantOnboardDTO} from '../models'; import {PermissionKey} from '../permissions'; import {service} from '@loopback/core'; import {OnboardingService, ProvisioningService} from '../services'; import {IProvisioningService} from '../types'; const basePath = '/tenants'; export class TenantController { constructor( @repository(TenantRepository) private readonly tenantRepository: TenantRepository, @service(OnboardingService) private readonly onboarding: OnboardingService, @service(ProvisioningService) private readonly provisioningService: IProvisioningService<SubscriptionDTO>, ) {} @authorize({ permissions: [PermissionKey.CreateTenant], }) @authenticate(STRATEGY.BEARER, { passReqToCallback: true, }) @post(basePath, { security: OPERATION_SECURITY_SPEC, responses: { [STATUS_CODE.OK]: { description: 'Tenant model instance', content: { [CONTENT_TYPE.JSON]: {schema: getModelSchemaRef(Tenant)}, }, }, }, }) async create( @requestBody({ content: { [CONTENT_TYPE.JSON]: { schema: getModelSchemaRef(TenantOnboardDTO, { title: 'NewTenantOnboarding', exclude: [], }), }, }, }) dto: TenantOnboardDTO, ): Promise<Tenant> { return this.onboarding.onboard(dto); } @authorize({ permissions: [PermissionKey.ProvisionTenant], }) @authenticate(STRATEGY.BEARER, { passReqToCallback: true, }) @post(`${basePath}/{id}/provision`, { security: OPERATION_SECURITY_SPEC, responses: { [STATUS_CODE.NO_CONTENT]: { description: 'Provisioning success', }, }, }) async provision( @requestBody({ content: { [CONTENT_TYPE.JSON]: { schema: getModelSchemaRef(SubscriptionDTO, { title: 'SubscriptionDTO', }), }, }, }) subscription: SubscriptionDTO, @param.path.string('id') id: string, ): Promise<void> { const tenantDetails = await this.tenantRepository.findById(id, { include: ['contacts', 'address'], }); return this.provisioningService.provisionTenant( tenantDetails, subscription, ); } @authorize({ permissions: [PermissionKey.ViewTenant], }) @authenticate(STRATEGY.BEARER, { passReqToCallback: true, }) @get(`${basePath}/count`, { security: OPERATION_SECURITY_SPEC, responses: { [STATUS_CODE.OK]: { description: 'Tenant model count', content: {[CONTENT_TYPE.JSON]: {schema: CountSchema}}, }, }, }) async count(@param.where(Tenant) where?: Where<Tenant>): Promise<Count> { return this.tenantRepository.count(where); } @authorize({ permissions: [PermissionKey.ViewTenant], }) @authenticate(STRATEGY.BEARER, { passReqToCallback: true, }) @get(basePath, { security: OPERATION_SECURITY_SPEC, responses: { [STATUS_CODE.OK]: { description: 'Array of Tenant model instances', content: { [CONTENT_TYPE.JSON]: { schema: { type: 'array', items: getModelSchemaRef(Tenant, {includeRelations: true}), }, }, }, }, }, }) async find(@param.filter(Tenant) filter?: Filter<Tenant>): Promise<Tenant[]> { return this.tenantRepository.find(filter); } @authorize({ permissions: [PermissionKey.UpdateTenant], }) @authenticate(STRATEGY.BEARER, { passReqToCallback: true, }) @patch(basePath, { security: OPERATION_SECURITY_SPEC, responses: { [STATUS_CODE.OK]: { description: 'Tenant PATCH success', content: { [CONTENT_TYPE.JSON]: { schema: getModelSchemaRef(Tenant), }, }, }, }, }) async updateAll( @requestBody({ content: { [CONTENT_TYPE.JSON]: { schema: getModelSchemaRef(Tenant, {partial: true}), }, }, }) tenant: Tenant, @param.where(Tenant) where?: Where<Tenant>, ): Promise<Count> { return this.tenantRepository.updateAll(tenant, where); } @authorize({ permissions: [PermissionKey.ViewTenant], }) @authenticate(STRATEGY.BEARER, { passReqToCallback: true, }) @get(`${basePath}/{id}`, { security: OPERATION_SECURITY_SPEC, responses: { [STATUS_CODE.OK]: { description: 'Tenant model instance', content: { [CONTENT_TYPE.JSON]: {schema: getModelSchemaRef(Tenant)}, }, }, }, }) async findById( @param.path.string('id') id: string, @param.filter(Tenant, {exclude: 'where'}) filter?: Filter<Tenant>, ): Promise<Tenant> { return this.tenantRepository.findById(id, filter); } @authorize({ permissions: [PermissionKey.UpdateTenant], }) @authenticate(STRATEGY.BEARER, { passReqToCallback: true, }) @patch(`${basePath}/{id}`, { security: OPERATION_SECURITY_SPEC, responses: { [STATUS_CODE.NO_CONTENT]: { description: 'Tenant PATCH success', content: { [CONTENT_TYPE.JSON]: { schema: getModelSchemaRef(Tenant), }, }, }, }, }) async updateById( @param.path.string('id') id: string, @requestBody({ content: { [CONTENT_TYPE.JSON]: { schema: getModelSchemaRef(Tenant, {partial: true}), }, }, }) tenant: Tenant, ): Promise<void> { await this.tenantRepository.updateById(id, tenant); } @authorize({ permissions: [PermissionKey.UpdateTenant], }) @authenticate(STRATEGY.BEARER, { passReqToCallback: true, }) @put(`${basePath}/{id}`, { security: OPERATION_SECURITY_SPEC, responses: { [STATUS_CODE.NO_CONTENT]: { description: 'Tenant PUT success', }, }, }) async replaceById( @param.path.string('id') id: string, @requestBody() tenant: Tenant, ): Promise<void> { await this.tenantRepository.replaceById(id, tenant); } @authorize({ permissions: [PermissionKey.DeleteTenant], }) @authenticate(STRATEGY.BEARER, { passReqToCallback: true, }) @del(`${basePath}/{id}`, { security: OPERATION_SECURITY_SPEC, responses: { [STATUS_CODE.NO_CONTENT]: { description: 'Tenant DELETE success', }, }, }) async deleteById(@param.path.string('id') id: string): Promise<void> { await this.tenantRepository.deleteById(id); } }