-
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 a895365
Showing
21 changed files
with
1,186 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; |
17 changes: 17 additions & 0 deletions
17
...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,17 @@ | ||
CREATE TABLE IF NOT EXISTS main.tenant_configs | ||
( | ||
id uuid NOT NULL DEFAULT (md5(((random())::text || (clock_timestamp())::text)))::uuid, | ||
config_key varchar(100) NOT NULL, | ||
config_value jsonb NOT NULL, | ||
created_on timestamptz DEFAULT CURRENT_TIMESTAMP, | ||
modified_on timestamptz, | ||
created_by uuid, | ||
modified_by uuid, | ||
deleted boolean DEFAULT FALSE NOT NULL, | ||
deleted_by uuid, | ||
deleted_on timestamptz, | ||
tenant_id uuid NOT NULL, | ||
CONSTRAINT pk_tenant_configs_id PRIMARY KEY (id), | ||
CONSTRAINT fk_tenant_configs_tenants FOREIGN KEY (tenant_id) | ||
REFERENCES main.tenants(id) | ||
) |
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 GitHub Actions / npm_test
|
||
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.