Skip to content

Commit

Permalink
Merge pull request #80 from Zolo-Ryan/oidcDev
Browse files Browse the repository at this point in the history
refactor: make nest-oidc-provider to handle login
  • Loading branch information
techsavvyash authored Sep 24, 2024
2 parents c01791f + ad9612b commit 094b1d4
Show file tree
Hide file tree
Showing 18 changed files with 555 additions and 145 deletions.
86 changes: 67 additions & 19 deletions kickstart.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@
"applicationId": "myminioadmin",
"clientSecret": "minio-secret-key-change-me",
"tenantId": "minio-tenant",
"roleId": "adminRoleId",
"groupId": "agroup",
"roleId1": "userRoleId",
"roleId2": "adminRoleId",
"groupId2": "agroup",
"groupId1": "ugroup",
"adminUsername": "admin",
"adminPassword": "adminPassword12#",
"userEmail": "[email protected]",
"userEmail2": "[email protected]",
"userEmail1": "[email protected]",
"userPassword": "userPassword12#"
},
"apiKey": {
Expand Down Expand Up @@ -98,17 +101,18 @@
],
"roles": [
{
"name": "Admin",
"description": "This is admin role",
"isDefault": false,
"isSuperRole": true,
"id": "#{roleId}"
},
{
"name": "user",
"name": "urn:myminioadmin:policy:'readwrite'",
"description": "This is user role",
"isDefault": true,
"isSuperRole": false
"isSuperRole": false,
"id": "#{roleId1}"
},
{
"name": "urn:myminioadmin:policy:['consoleAdmin','readwrite']",
"description": "This is special role assigned to admin users",
"isDefault": false,
"isSuperRole": true,
"id": "#{roleId2}"
}
],
"oauthConfiguration": {
Expand All @@ -121,26 +125,45 @@
"http://localhost:9001/oauth_callback",
"http://192.168.233.157:9001/oauth_callback",
"http://localhost:4180/oauth2/callback",
"http://localhost:3000"
"http://localhost:3001",
"http://localhost:9001",
"http://localhost:3001/callback",
"http://192.168.250.157:9001/oauth_callback"
],
"clientSecret": "#{clientSecret}",
"enabledGrants": ["authorization_code", "refresh_token"],
"logoutURL": "http://localhost:3000/logout"
"logoutURL": "http://localhost:3001/logout",
"enablePKCE": false,
"skipConsentScreen": true
}
}
}
},
{
"method": "POST",
"url": "/group/#{groupId}",
"url": "/group/#{groupId2}",
"headers": {
"authorization": "#{apiKeyValue}",
"x-stencil-tenantid": "#{tenantId}"
},
"body": {
"group": {
"name": "Admin group",
"roleIDs": ["#{roleId}"]
"roleIDs": ["#{roleId2}"]
}
}
},
{
"method": "POST",
"url": "/group/#{groupId1}",
"headers": {
"authorization": "#{apiKeyValue}",
"x-stencil-tenantid": "#{tenantId}"
},
"body": {
"group": {
"name": "user group",
"roleIDs": ["#{roleId1}"]
}
}
},
Expand All @@ -156,17 +179,42 @@
"userInfo": {
"active": true,
"applicationId": "#{applicationId}",
"membership": ["#{groupId}"],
"membership": ["#{groupId2}"],
"userData": {
"username": "AdminUser",
"password": "#{userPassword}"
},
"email": "#{userEmail}"
"email": "#{userEmail2}"
},
"registrationInfo": {
"generateAuthenticationToken": true,
"applicationId": "#{applicationId}"
}
}
}
},
{
"method": "POST",
"url": "/user/registration/combined/",
"headers": {
"x-stencil-tenantid": "#{tenantId}",
"authorization": "#{apiKeyValue}"
},
"body": {
"data": {
"userInfo": {
"active": true,
"applicationId": "#{applicationId}",
"roles": ["user"]
"membership": ["#{groupId1}"],
"userData": {
"username": "normalUser",
"password": "#{userPassword}"
},
"email": "#{userEmail1}"
},
"registrationInfo": {
"generateAuthenticationToken": true,
"applicationId": "#{applicationId}"
}
}
}
Expand Down
36 changes: 19 additions & 17 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ model Application {
updatedAt DateTime @updatedAt
name String
tenantId String
logo_uri String? @default("https://www.flaticon.com/free-icon/application_2833637")
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
accessTokenSigningKey Key? @relation("ApplicationAccessTokenSigningKey", fields: [accessTokenSigningKeysId], references: [id])
Expand Down Expand Up @@ -137,14 +138,14 @@ model Tenant {
}

model UserRegistration {
id String @id @default(uuid())
applicationsId String
password String
data String?
createdAt DateTime @default(now())
lastLoginInstant DateTime?
updatedAt DateTime @updatedAt
usersId String
id String @id @default(uuid())
applicationsId String
password String
data String?
createdAt DateTime @default(now())
lastLoginInstant DateTime?
updatedAt DateTime @updatedAt
usersId String
application Application @relation(fields: [applicationsId], references: [id], onDelete: Cascade)
user User @relation(fields: [usersId], references: [id])
Expand All @@ -154,15 +155,15 @@ model UserRegistration {
}

model User {
id String @id @default(uuid())
active Boolean
data String
expiry Int?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenantId String
email String @unique
// claims JSON we should add this or not?
id String @id @default(uuid())
active Boolean
data String
expiry Int?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenantId String
email String @unique
// claims JSON we should add this or not?
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
groupMembers GroupMember[]
userRegistrations UserRegistration[]
Expand Down Expand Up @@ -208,6 +209,7 @@ model OidcModel {
consumedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
consumed Boolean @default(false)
@@unique([id, type])
@@map("oidc_model")
Expand Down
Empty file modified reset-db.sh
100644 → 100755
Empty file.
4 changes: 2 additions & 2 deletions sample/oauth2proxy.cfg
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
provider = "oidc"
redirect_url = "http://localhost:4180/oauth2/callback"
oidc_issuer_url = "http://localhost:3000/oidc"
oidc_issuer_url = "http://localhost:3001/oidc"
upstreams = [
"http://localhost:3000/health","http://localhost:3000"
"http://localhost:3001/health","http://localhost:3001/admin"
]
email_domains = [
"*"
Expand Down
6 changes: 3 additions & 3 deletions src/app.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class AppController {
oidc: { provider },
} = ctx;
const session = await provider.Session.get(ctx);

//HERE
const res: Record<string, any> = {
query: ctx.query,
accountId: null,
Expand Down Expand Up @@ -78,11 +78,11 @@ export class AppController {

try {
await axios.post(
'http://localhost:3001/oidc/token',
`${process.env.ISSUER_URL}/token`,
new URLSearchParams({
client_id: 'test',
grant_type: 'authorization_code',
redirect_uri: 'http://localhost:3001/callback',
redirect_uri: `${process.env.FULL_URL}/callback`,
code,
}).toString(),
{
Expand Down
18 changes: 18 additions & 0 deletions src/application/application.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,24 @@ class OauthConfiguration {
// @IsUrl({}, { message: 'Logout URL must be a valid URL' })
@IsNotEmpty({ message: 'Logout URL must not be empty' })
logoutURL: string;

@ApiProperty({
default: false,
type: Boolean,
example: 'true',
description: "Whether to ask user's consent for getting user claims or not",
})
@IsBoolean()
skipConsentScreen: boolean = false;

@ApiProperty({
default: false,
type: Boolean,
example: 'false',
description: 'enable proof key for code exchange for an application',
})
@IsBoolean()
enablePKCE: boolean = false;
}

export class JwtConfiguration {
Expand Down
36 changes: 24 additions & 12 deletions src/oidc/adapters/prisma.adapter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Adapter, AdapterPayload } from 'oidc-provider';
import { PrismaService } from '../../prisma/prisma.service';
import { Injectable } from '@nestjs/common';
import { expiresAt, types } from '../oidc.adapter';

@Injectable()
export class PrismaAdapter implements Adapter {
Expand All @@ -14,56 +15,67 @@ export class PrismaAdapter implements Adapter {
payload: AdapterPayload,
expiresIn: number,
): Promise<void> {
await this.prisma[this.modelName].upsert({
where: { id },
// console.log(this.modelName);
const data = {
type: types[this.modelName],
payload: JSON.stringify(payload),
grantId: payload.grantId,
userCode: payload.userCode,
uid: payload.uid,
expiresAt: expiresAt(expiresIn),
};
await this.prisma.oidcModel.upsert({
where: { id_type: { id, type: types[this.modelName] } },
update: {
...payload,
expiresAt: expiresIn ? new Date(Date.now() + expiresIn * 1000) : null,
...data,
},
create: {
id,
...payload,
expiresAt: expiresIn ? new Date(Date.now() + expiresIn * 1000) : null,
...data,
},
});
}

async find(id: string): Promise<void | AdapterPayload> {
const result = await this.prisma[this.modelName].findUnique({
let result = await this.prisma.oidcModel.findUnique({
where: { id },
});
result = { ...result, ...JSON.parse(result.payload) };
console.log(result);
return result || undefined;
}

async findByUserCode(userCode: string): Promise<void | AdapterPayload> {
const result = await this.prisma[this.modelName].findFirst({
let result = await this.prisma.oidcModel.findFirst({
where: { userCode },
});
result = { ...result, ...JSON.parse(result.payload) };
return result || undefined;
}

async findByUid(uid: string): Promise<void | AdapterPayload> {
const result = await this.prisma[this.modelName].findFirst({
let result = await this.prisma.oidcModel.findFirst({
where: { uid },
});
result = { ...result, ...JSON.parse(result.payload) };
return result || undefined;
}

async consume(id: string): Promise<void> {
await this.prisma[this.modelName].update({
await this.prisma.oidcModel.update({
where: { id },
data: { consumed: true },
});
}

async destroy(id: string): Promise<void> {
await this.prisma[this.modelName].delete({
await this.prisma.oidcModel.delete({
where: { id },
});
}

async revokeByGrantId(grantId: string): Promise<void> {
await this.prisma[this.modelName].deleteMany({
await this.prisma.oidcModel.deleteMany({
where: { grantId },
});
}
Expand Down
Loading

0 comments on commit 094b1d4

Please sign in to comment.