Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dheeraj_CTM_186 #201

Open
wants to merge 2 commits into
base: qa
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions apps/api/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,23 @@ KEYCLOAK_REALM=ctims
# The realm needs to have client authentication enabled to see the Credentials tab.
KEYCLOAK_CLIENT_SECRET=<secret>

# To disable key cloak change the KEYCLOAK_DISABLED value to true and use the below login details to login.
KEYCLOAK_DISABLED=false
KD_TRIALGROUP=default
KD_TRIALGROUP_ADMIN=default-admin
KD_USERNAME=ctims
KD_PASSWORD=ctims
KD_USERNAME_ADMIN=ctims-admin
KD_PASSWORD_ADMIN=ctims-admin
[email protected]
[email protected]
KD_FULLNAME=Ctims User
KD_FULLNAME_ADMIN=Ctims Admin
KD_KEYCLOAK_ID=1234
KD_KEYCLOAK_ID_ADMIN=5678
KD_TOKEN_ADMIN="env-based-token-admin"
KD_TOKEN_USER="env-based-token-user"

# A client with service account enabled.
# It does not need to be a separate client. If your above client already has service account enabled, use the same ID here.
KEYCLOAK_ADMIN_CLIENT_ID=ctims-admin
Expand Down
17 changes: 17 additions & 0 deletions apps/api/src/app/auth/KeycloakPasswordGuard.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,31 @@
import { ExecutionContext, Injectable, UnauthorizedException } from "@nestjs/common";
import { AuthGuard as PassportAuthGuard } from '@nestjs/passport';
import { keycloak_disabled_comfig } from "./keycloak-disabled-config";

@Injectable()
export class KeycloakPasswordGuard extends PassportAuthGuard('keycloak') {
private keycloakDisabled: boolean;
private envTokenAdmin: string;

constructor() {
super();
this.keycloakDisabled = process.env.KEYCLOAK_DISABLED === 'true';
this.envTokenAdmin = process.env.KD_TOKEN_ADMIN;
}
getRequest(context: ExecutionContext) {
const req = context.switchToHttp().getRequest();
return req;
}

handleRequest(err: any, user: any, info: any, context: ExecutionContext) {
if (this.keycloakDisabled) {
const req = context.switchToHttp().getRequest();
const authHeader = req.headers.authorization;
const token = authHeader ? authHeader.split(' ')[1] : null;
const isAdmin = (token == this.envTokenAdmin) ? "admin" : "notadmin";
const user = keycloak_disabled_comfig(isAdmin);
return user;
}
if (err || !user) {
console.log('Error:', err);
console.log('Info:', info);
Expand Down
54 changes: 54 additions & 0 deletions apps/api/src/app/auth/keycloak-disabled-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
function keycloak_disabled_comfig(role: string) {

const envUsername = adminStatus(role) ? process.env.KD_USERNAME_ADMIN : process.env.KD_USERNAME;
const envTrialGroup = adminStatus(role) ? process.env.KD_TRIALGROUP_ADMIN : process.env.KD_TRIALGROUP;
const envKeycloakId = adminStatus(role) ? process.env.KD_KEYCLOAK_ID_ADMIN : process.env.KD_KEYCLOAK_ID;
const envEmail = adminStatus(role) ? process.env.KD_EMAIL_ADMIN : process.env.KD_EMAIL
const envFullName = adminStatus(role) ? process.env.KD_FULLNAME_ADMIN : process.env.KD_FULLNAME;
const roles = envTrialGroup;
const userId = adminStatus(role) ? 100 : 99;

const user = {
id: userId,
email: envEmail,
name: envFullName,
username: envUsername,
first_name: envUsername,
email_verified: true,
last_name: '',
keycloak_id: envKeycloakId,
createdAt: "",
updatedAt: "",
roles: [roles]
}
return user;
}
function keycloak_disabled_fetch_by_KeycloakId(role: string) {

const envUsername = adminStatus(role) ? process.env.KD_USERNAME_ADMIN : process.env.KD_USERNAME;
const envTrialGroup = adminStatus(role) ? process.env.KD_TRIALGROUP_ADMIN : process.env.KD_TRIALGROUP;
const envKeycloakId = adminStatus(role) ? process.env.KD_KEYCLOAK_ID_ADMIN : process.env.KD_KEYCLOAK_ID;
const envEmail = adminStatus(role) ? process.env.KD_EMAIL_ADMIN : process.env.KD_EMAIL
const envFullName = adminStatus(role) ? process.env.KD_FULLNAME_ADMIN : process.env.KD_FULLNAME;
const roles = envTrialGroup;

const user = {
id: envKeycloakId,
email: envEmail,
name: envFullName,
username: envUsername,
first_name: envUsername,
email_verified: true,
last_name: '',
keycloak_id: envKeycloakId,
createdAt: "",
updatedAt: "",
roles: [roles]
}
return user;
}
function adminStatus(role: string){
return (role=="admin") ? true : false;
}
export { keycloak_disabled_comfig, keycloak_disabled_fetch_by_KeycloakId, adminStatus};

39 changes: 39 additions & 0 deletions apps/api/src/app/auth/keycloak-password.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ const keycloakConfig = {
"confidential-port": 0
}

const isKeycloakDisabled = process.env.KEYCLOAK_DISABLED === 'true';
const envUsername = process.env.KD_USERNAME;
const envPassword = process.env.KD_PASSWORD;
const envUsernameAdmin = process.env.KD_USERNAME_ADMIN;
const envPasswordAdmin = process.env.KD_PASSWORD_ADMIN;
const envKeycloakId = process.env.KD_KEYCLOAK_ID;
const envKeycloakIdAdmin = process.env.KD_KEYCLOAK_ID_ADMIN;
const envTokenUser= process.env.KD_TOKEN_USER;
const envTokenAdmin= process.env.KD_TOKEN_ADMIN;

@Injectable()
export class KeycloakPasswordStrategy extends PassportStrategy(KeycloakBearerStrategy, 'keycloak') implements OnModuleInit {
Expand All @@ -39,6 +48,10 @@ export class KeycloakPasswordStrategy extends PassportStrategy(KeycloakBearerStr
}

async login(username: string, password: string): Promise<any> {
if (isKeycloakDisabled==true) {
return this.loginWithEnvCredentials(username, password);
}
else{
let grant: Grant = null;
try {
grant = await this.keycloak.grantManager.obtainDirectly(username, password);
Expand Down Expand Up @@ -90,9 +103,34 @@ export class KeycloakPasswordStrategy extends PassportStrategy(KeycloakBearerStr
accessToken: keycloakToken['token'],
user
};
}
}
private async loginWithEnvCredentials(username: string, password: string): Promise<any> {
if (username === envUsername && password === envPassword) {
let user = await this.userService.findUserBySub(envKeycloakId)
if(!user){
user = await this.userService.createUserWithoutKeycloak("notAdmin")
}
const roles= ['default']
user['roles'] = roles;
return { accessToken: envTokenUser, user };
}
else if(username === envUsernameAdmin && password === envPasswordAdmin){
let user = await this.userService.findUserBySub(envKeycloakIdAdmin)
if(!user){
user = await this.userService.createUserWithoutKeycloak("admin")
}
const roles= ['default-admin']
user['roles'] = roles;
return { accessToken: envTokenAdmin, user };
}
}

async refreshToken(access_token: Token): Promise<any> {
if (isKeycloakDisabled==true) {
return {accessToken: access_token};
}
else{
const decoded: any = jwt_decode(access_token as unknown as string);

const user = await this.userService.findUserBySub(decoded.sub)
Expand All @@ -113,6 +151,7 @@ export class KeycloakPasswordStrategy extends PassportStrategy(KeycloakBearerStr

return {accessToken: keycloakToken['token']};
}
}

async validate(accessToken: any, done: (err: any, user: any, info?: any) => void): Promise<void> {
// Here you can implement additional validation or store the user information in your application.
Expand Down
9 changes: 9 additions & 0 deletions apps/api/src/app/trial/trial-group.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import axios, {AxiosResponse} from 'axios';
import { PrismaService } from '../prisma.service';
import { ModuleRef } from '@nestjs/core';
import { trial } from '@prisma/client';
import { keycloak_disabled_fetch_by_KeycloakId } from "../auth/keycloak-disabled-config";

export interface TrialGroup {
id: string;
Expand Down Expand Up @@ -95,6 +96,13 @@ export class TrialGroupService {

async getUsersInTrialGroup(trialGroupId: string): Promise<any[]> {

const isKeycloakDisabled = process.env.KEYCLOAK_DISABLED === 'true';
if (isKeycloakDisabled) {
const user = keycloak_disabled_fetch_by_KeycloakId("notadmin");
const adminUser = keycloak_disabled_fetch_by_KeycloakId("admin");
return [user, adminUser];
}
else {
try {
const accessToken = await this.getToken();
const getUsersInTrialGroupConfig = {
Expand Down Expand Up @@ -126,6 +134,7 @@ export class TrialGroupService {
} catch (error) {
this.logger.error(`Error while getting users in trial group from Keycloak: ${error}`)
throw new HttpException('Error while getting users in trial group from Keycloak', HttpStatus.BAD_REQUEST)
}
}
}

Expand Down
24 changes: 24 additions & 0 deletions apps/api/src/app/user/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {PrismaService} from "../prisma.service";
import {KeycloakPasswordStrategy} from "../auth/keycloak-password.strategy";
import {ModuleRef} from "@nestjs/core";
import { PrismaPromise, user } from "@prisma/client";
import {adminStatus} from "../auth/keycloak-disabled-config";

@Injectable()
export class UserService {
Expand Down Expand Up @@ -36,6 +37,29 @@ export class UserService {
return newUserFromKeycloak;
}

async createUserWithoutKeycloak(role: string) {
const envUsername = adminStatus(role) ? process.env.KD_USERNAME_ADMIN : process.env.KD_USERNAME;
const envKeycloakId = adminStatus(role) ? process.env.KD_KEYCLOAK_ID_ADMIN : process.env.KD_KEYCLOAK_ID;
const envEmail = adminStatus(role) ? process.env.KD_EMAIL_ADMIN : process.env.KD_EMAIL;
const envFullName = adminStatus(role) ? process.env.KD_FULLNAME_ADMIN : process.env.KD_FULLNAME;
const Id = adminStatus(role) ? 100 : 99;
const token = adminStatus(role) ? process.env.KD_TOKEN_ADMIN : process.env.KD_TOKEN_USER ;
const newUserWithoutKeycloak = await this.prismaService.user.create({
data: {
id: Id,
email: envEmail,
keycloak_id: envKeycloakId,
first_name: envUsername,
last_name: "",
name: envFullName,
username: envUsername,
email_verified: true,
refresh_token: token
}
});
return newUserWithoutKeycloak;
}

findAll() {
return `This action returns all user`;
}
Expand Down