-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(tenant-management): add keycloak idp configuration
add keycloak idp configuration BREAKING CHANGE: yes 43
- Loading branch information
1 parent
5e03dcb
commit 9a1ab00
Showing
21 changed files
with
1,188 additions
and
601 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
53 changes: 53 additions & 0 deletions
53
...nt-management-service/migrations/pg/migrations/20240925102459-add-table-tenant-configs.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
'use strict'; | ||
|
||
var dbm; | ||
var type; | ||
var seed; | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
var Promise; | ||
|
||
/** | ||
* We receive the dbmigrate dependency from dbmigrate initially. | ||
* This enables us to not have to rely on NODE_PATH. | ||
*/ | ||
exports.setup = function(options, seedLink) { | ||
dbm = options.dbmigrate; | ||
type = dbm.dataType; | ||
seed = seedLink; | ||
Promise = options.Promise; | ||
}; | ||
|
||
exports.up = function(db) { | ||
var filePath = path.join(__dirname, 'sqls', '20240925102459-add-table-tenant-configs-up.sql'); | ||
return new Promise( function( resolve, reject ) { | ||
fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ | ||
if (err) return reject(err); | ||
console.log('received data: ' + data); | ||
|
||
resolve(data); | ||
}); | ||
}) | ||
.then(function(data) { | ||
return db.runSql(data); | ||
}); | ||
}; | ||
|
||
exports.down = function(db) { | ||
var filePath = path.join(__dirname, 'sqls', '20240925102459-add-table-tenant-configs-down.sql'); | ||
return new Promise( function( resolve, reject ) { | ||
fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ | ||
if (err) return reject(err); | ||
console.log('received data: ' + data); | ||
|
||
resolve(data); | ||
}); | ||
}) | ||
.then(function(data) { | ||
return db.runSql(data); | ||
}); | ||
}; | ||
|
||
exports._meta = { | ||
"version": 1 | ||
}; |
1 change: 1 addition & 0 deletions
1
...nt-service/migrations/pg/migrations/sqls/20240925102459-add-table-tenant-configs-down.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
drop table main.tenant_configs; |
19 changes: 19 additions & 0 deletions
19
...ment-service/migrations/pg/migrations/sqls/20240925102459-add-table-tenant-configs-up.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
CREATE TABLE IF NOT EXISTS main.tenant_configs | ||
( | ||
id uuid NOT NULL DEFAULT (md5(((random())::text || (clock_timestamp())::text)))::uuid, | ||
config_key character varying(100) COLLATE pg_catalog."default" NOT NULL, | ||
config_value jsonb NOT NULL, | ||
created_on timestamp with time zone NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
modified_on timestamp with time zone NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
created_by integer, | ||
modified_by integer, | ||
deleted boolean NOT NULL DEFAULT false, | ||
tenant_id uuid NOT NULL, | ||
deleted_by uuid, | ||
deleted_on timestamp with time zone, | ||
CONSTRAINT pk_tenant_configs_id PRIMARY KEY (id), | ||
CONSTRAINT fk_tenant_configs_tenants FOREIGN KEY (tenant_id) | ||
REFERENCES main.tenants (id) MATCH SIMPLE | ||
ON UPDATE NO ACTION | ||
ON DELETE NO ACTION | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 66 additions & 0 deletions
66
services/tenant-management-service/src/controllers/idp.controller.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { extensions, Getter, inject, intercept } from '@loopback/core'; | ||
Check failure on line 1 in services/tenant-management-service/src/controllers/idp.controller.ts
|
||
import { getModelSchemaRef, post, requestBody } from '@loopback/rest'; | ||
import { | ||
CONTENT_TYPE, | ||
OPERATION_SECURITY_SPEC, | ||
rateLimitKeyGenPublic, | ||
STATUS_CODE, | ||
} from '@sourceloop/core'; | ||
import { authorize } from 'loopback4-authorization'; | ||
import { ratelimit } from 'loopback4-ratelimiter'; | ||
import { TenantManagementServiceBindings, WEBHOOK_VERIFIER } from '../keys'; | ||
import { IdpDetailsDTO } from '../models/dtos/idp-details-dto.model'; | ||
import { ConfigureIdpFunc, IdPKey, IWebhookHandler } from '../types'; | ||
import { KeycloakIdpProvider } from '../providers/idp/idp-keycloak.provider'; | ||
|
||
const basePath = '/manage/users'; | ||
export class IdpController { | ||
constructor( | ||
@inject(TenantManagementServiceBindings.IDP_KEYCLOAK) | ||
private readonly idpKeycloakProvider:ConfigureIdpFunc<IdpDetailsDTO> | ||
) { } | ||
@intercept(WEBHOOK_VERIFIER) | ||
@ratelimit(true, { | ||
max: parseInt(process.env.WEBHOOK_API_MAX_ATTEMPTS ?? '10'), | ||
keyGenerator: rateLimitKeyGenPublic, | ||
}) | ||
@authorize({ | ||
permissions: ['*'], | ||
}) | ||
@post(`${basePath}`, { | ||
security: OPERATION_SECURITY_SPEC, | ||
responses: { | ||
[STATUS_CODE.NO_CONTENT]: { | ||
description: 'Webhook success', | ||
}, | ||
}, | ||
}) | ||
async idpConfigure( | ||
@requestBody({ | ||
content: { | ||
[CONTENT_TYPE.JSON]: { | ||
schema: getModelSchemaRef(IdpDetailsDTO, { | ||
title: 'IdpDetailsDTO', | ||
}), | ||
}, | ||
}, | ||
}) | ||
payload: IdpDetailsDTO, | ||
): Promise<void> { | ||
switch (payload.identityProvider) { | ||
case IdPKey.AUTH0: | ||
|
||
break; | ||
case IdPKey.COGNITO: | ||
|
||
break; | ||
case IdPKey.KEYCLOAK: | ||
await this.idpKeycloakProvider(payload); | ||
break; | ||
|
||
default: | ||
break; | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
services/tenant-management-service/src/controllers/tenant-config-tenant.controller.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { | ||
repository, | ||
} from '@loopback/repository'; | ||
import { | ||
param, | ||
get, | ||
getModelSchemaRef, | ||
} from '@loopback/rest'; | ||
import { | ||
TenantConfig, | ||
Tenant, | ||
} from '../models'; | ||
import {TenantConfigRepository} from '../repositories'; | ||
|
||
export class TenantConfigTenantController { | ||
constructor( | ||
@repository(TenantConfigRepository) | ||
public tenantConfigRepository: TenantConfigRepository, | ||
) { } | ||
|
||
@get('/tenant-configs/{id}/tenant', { | ||
responses: { | ||
'200': { | ||
description: 'Tenant belonging to TenantConfig', | ||
content: { | ||
'application/json': { | ||
schema: getModelSchemaRef(Tenant), | ||
}, | ||
}, | ||
}, | ||
}, | ||
}) | ||
async getTenant( | ||
@param.path.string('id') id: typeof TenantConfig.prototype.id, | ||
): Promise<Tenant> { | ||
return this.tenantConfigRepository.tenant(id); | ||
} | ||
} |
150 changes: 150 additions & 0 deletions
150
services/tenant-management-service/src/controllers/tenant-config.controller.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
import { | ||
Count, | ||
CountSchema, | ||
Filter, | ||
FilterExcludingWhere, | ||
repository, | ||
Where, | ||
} from '@loopback/repository'; | ||
import { | ||
post, | ||
param, | ||
get, | ||
getModelSchemaRef, | ||
patch, | ||
put, | ||
del, | ||
requestBody, | ||
response, | ||
} from '@loopback/rest'; | ||
import {TenantConfig} from '../models'; | ||
import {TenantConfigRepository} from '../repositories'; | ||
|
||
export class TenantConfigController { | ||
constructor( | ||
@repository(TenantConfigRepository) | ||
public tenantConfigRepository : TenantConfigRepository, | ||
) {} | ||
|
||
@post('/tenant-configs') | ||
@response(200, { | ||
description: 'TenantConfig model instance', | ||
content: {'application/json': {schema: getModelSchemaRef(TenantConfig)}}, | ||
}) | ||
async create( | ||
@requestBody({ | ||
content: { | ||
'application/json': { | ||
schema: getModelSchemaRef(TenantConfig, { | ||
title: 'NewTenantConfig', | ||
exclude: ['id'], | ||
}), | ||
}, | ||
}, | ||
}) | ||
tenantConfig: Omit<TenantConfig, 'id'>, | ||
): Promise<TenantConfig> { | ||
return this.tenantConfigRepository.create(tenantConfig); | ||
} | ||
|
||
@get('/tenant-configs/count') | ||
@response(200, { | ||
description: 'TenantConfig model count', | ||
content: {'application/json': {schema: CountSchema}}, | ||
}) | ||
async count( | ||
@param.where(TenantConfig) where?: Where<TenantConfig>, | ||
): Promise<Count> { | ||
return this.tenantConfigRepository.count(where); | ||
} | ||
|
||
@get('/tenant-configs') | ||
@response(200, { | ||
description: 'Array of TenantConfig model instances', | ||
content: { | ||
'application/json': { | ||
schema: { | ||
type: 'array', | ||
items: getModelSchemaRef(TenantConfig, {includeRelations: true}), | ||
}, | ||
}, | ||
}, | ||
}) | ||
async find( | ||
@param.filter(TenantConfig) filter?: Filter<TenantConfig>, | ||
): Promise<TenantConfig[]> { | ||
return this.tenantConfigRepository.find(filter); | ||
} | ||
|
||
@patch('/tenant-configs') | ||
@response(200, { | ||
description: 'TenantConfig PATCH success count', | ||
content: {'application/json': {schema: CountSchema}}, | ||
}) | ||
async updateAll( | ||
@requestBody({ | ||
content: { | ||
'application/json': { | ||
schema: getModelSchemaRef(TenantConfig, {partial: true}), | ||
}, | ||
}, | ||
}) | ||
tenantConfig: TenantConfig, | ||
@param.where(TenantConfig) where?: Where<TenantConfig>, | ||
): Promise<Count> { | ||
return this.tenantConfigRepository.updateAll(tenantConfig, where); | ||
} | ||
|
||
@get('/tenant-configs/{id}') | ||
@response(200, { | ||
description: 'TenantConfig model instance', | ||
content: { | ||
'application/json': { | ||
schema: getModelSchemaRef(TenantConfig, {includeRelations: true}), | ||
}, | ||
}, | ||
}) | ||
async findById( | ||
@param.path.string('id') id: string, | ||
@param.filter(TenantConfig, {exclude: 'where'}) filter?: FilterExcludingWhere<TenantConfig> | ||
): Promise<TenantConfig> { | ||
return this.tenantConfigRepository.findById(id, filter); | ||
} | ||
|
||
@patch('/tenant-configs/{id}') | ||
@response(204, { | ||
description: 'TenantConfig PATCH success', | ||
}) | ||
async updateById( | ||
@param.path.string('id') id: string, | ||
@requestBody({ | ||
content: { | ||
'application/json': { | ||
schema: getModelSchemaRef(TenantConfig, {partial: true}), | ||
}, | ||
}, | ||
}) | ||
tenantConfig: TenantConfig, | ||
): Promise<void> { | ||
await this.tenantConfigRepository.updateById(id, tenantConfig); | ||
} | ||
|
||
@put('/tenant-configs/{id}') | ||
@response(204, { | ||
description: 'TenantConfig PUT success', | ||
}) | ||
async replaceById( | ||
@param.path.string('id') id: string, | ||
@requestBody() tenantConfig: TenantConfig, | ||
): Promise<void> { | ||
await this.tenantConfigRepository.replaceById(id, tenantConfig); | ||
} | ||
|
||
@del('/tenant-configs/{id}') | ||
@response(204, { | ||
description: 'TenantConfig DELETE success', | ||
}) | ||
async deleteById(@param.path.string('id') id: string): Promise<void> { | ||
await this.tenantConfigRepository.deleteById(id); | ||
} | ||
} |
Oops, something went wrong.