-
Notifications
You must be signed in to change notification settings - Fork 16
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
feat: Control plane #6
base: main
Are you sure you want to change the base?
Changes from 5 commits
7d71b81
59d2b40
72ae996
bf70f02
07af7a1
50abc84
df311a4
71c39ab
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from './logger-stub'; | ||
export * from './repo-querier-local-adapter copy'; | ||
export * from './repo-querier-stub-adapter'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { ForLogging } from "../../ports/drivens/for-logging"; | ||
|
||
export class LoggerStub implements ForLogging { | ||
log(event: string, message: string): void { | ||
console.log(event, message); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { userManagerProxy, userPermissionManagerProxy } from "../../../repository/app/composition-root"; | ||
import { RepoUser } from "../../../repository/app/schemas"; | ||
import { Permissions } from "../../app/schemas/auth"; | ||
import { ForRepoQuerying } from "../../ports/drivens"; | ||
|
||
export class RepoQuerierStubAdapter implements ForRepoQuerying { | ||
async getUser(email: string): Promise<RepoUser> { | ||
const user = userManagerProxy.getInternalUser(email) | ||
|
||
return user; | ||
} | ||
|
||
async getPermissions(userId: string): Promise<Permissions> { | ||
const userPermissions = await userPermissionManagerProxy.getUserPermissions(userId) | ||
|
||
return { | ||
admin: userPermissions.admin, | ||
user: userPermissions.user | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { RepoUser } from "../../../repository/app/schemas"; | ||
import { UserPermissions } from "../../app/schemas/auth"; | ||
import { ForRepoQuerying } from "../../ports/drivens"; | ||
|
||
export class RepoQuerierStubAdapter implements ForRepoQuerying { | ||
async getUser(_email: string): Promise<RepoUser> { | ||
return { | ||
id: "1", | ||
name: "John Doe", | ||
email: "[email protected]", | ||
password: "123", | ||
}; | ||
} | ||
|
||
async getPermissions(_userId: string): Promise<UserPermissions> { | ||
return Promise.resolve({ id: "1", userId: "1", admin: true, user: true }); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { ControlPlane } from "../../app/control-plane"; | ||
import { AuthDetails, Permissions } from "../../app/schemas/auth"; | ||
import { ForManagingAuthentication } from "../../ports/drivers"; | ||
|
||
export class AuthManagerProxyAdapter implements ForManagingAuthentication { | ||
constructor(private readonly controlPlane: ControlPlane) {} | ||
|
||
async getAuthDetails(email: string, password: string): Promise<AuthDetails> { | ||
return this.controlPlane.getAuthDetails(email, password); | ||
} | ||
|
||
async getPermissions(userId: string): Promise<Permissions> { | ||
return this.controlPlane.getPermissions(userId); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './auth-manager-proxy-adapter'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { LoggerStub, RepoQuerierStubAdapter } from "../adapters/drivens"; | ||
import { AuthManagerProxyAdapter } from "../adapters/drivers"; | ||
import { ControlPlane } from "./control-plane"; | ||
|
||
const compositionMock = () => { | ||
const repoQuerierstub = new RepoQuerierStubAdapter(); | ||
const loggerStub = new LoggerStub(); | ||
const controlPlane = new ControlPlane(repoQuerierstub, loggerStub); | ||
|
||
const authManagerProxy = new AuthManagerProxyAdapter(controlPlane); | ||
|
||
return { authManagerProxy }; | ||
}; | ||
|
||
export const { authManagerProxy } = compositionMock(); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { beforeEach, describe, expect, it } from "vitest"; | ||
import { LoggerStub, RepoQuerierStubAdapter } from "../adapters/drivens"; | ||
import { ControlPlane } from "./control-plane"; | ||
|
||
describe("ControlPlane", () => { | ||
const repoQuerierstub = new RepoQuerierStubAdapter(); | ||
const loggerStub = new LoggerStub(); | ||
let controlPlane = new ControlPlane(repoQuerierstub, loggerStub); | ||
|
||
beforeEach(() => { | ||
controlPlane = new ControlPlane(repoQuerierstub, loggerStub); | ||
}); | ||
|
||
it.concurrent("should get auth details", async () => { | ||
// GIVEN | ||
const mockEmail = "[email protected]"; | ||
const mockPassword = "123"; | ||
|
||
const resultExpected = { token: "token", refreshToken: "refreshToken" }; | ||
|
||
// WHEN | ||
const result = await controlPlane.getAuthDetails(mockEmail, mockPassword); | ||
|
||
// THEN | ||
expect(result).toEqual(resultExpected); | ||
}); | ||
|
||
it.concurrent("should get permissions", async () => { | ||
// GIVEN | ||
const mockUserId = "1"; | ||
|
||
const resultExpected = { admin: true, user: true }; | ||
|
||
// WHEN | ||
const result = await controlPlane.getPermissions(mockUserId); | ||
|
||
// THEN | ||
expect(result).toEqual(resultExpected); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { ForLogging } from "../ports/drivens/for-logging"; | ||
import { ForRepoQuerying } from "../ports/drivens/for-repo-querying"; | ||
import { ForManagingAuthentication } from "../ports/drivers"; | ||
import { AuthDetails, Permissions } from "./schemas/auth"; | ||
|
||
export class ControlPlane implements ForManagingAuthentication { | ||
constructor( | ||
private readonly repoQuerier: ForRepoQuerying, | ||
private readonly logger: ForLogging | ||
) {} | ||
|
||
async getAuthDetails(email: string, password: string): Promise<AuthDetails> { | ||
const user = await this.repoQuerier.getUser(email); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. realmente esta comprobacion de si existe el user o no, se podría hacer en el repoQuerier y esto englobarlo con un try catch, cosa que si entra por el catch envie el error There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tenés razón, ya lo corregí para que haga el catch del error.También vi que el logger era innecesario porque ya estaba en el repository asi que lo quité |
||
|
||
if (!user) { | ||
this.logger.log("GetAuthDetails", "Wrong email"); | ||
throw new Error("Wrong email"); | ||
} | ||
|
||
if (password !== user.password) { | ||
this.logger.log("GetAuthDetails", "Wrong password"); | ||
throw new Error("Wrong password"); | ||
} | ||
|
||
return { token: "token", refreshToken: "refreshToken" }; | ||
} | ||
|
||
async getPermissions(userId: string): Promise<Permissions> { | ||
const userPermissions = await this.repoQuerier.getPermissions(userId); | ||
|
||
if (!userPermissions) { | ||
this.logger.log("GetPermissions", "Permissions not found"); | ||
throw new Error("Permissions not found"); | ||
} | ||
|
||
const permissions = { | ||
admin: userPermissions.admin, | ||
user: userPermissions.user, | ||
}; | ||
|
||
return permissions; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
export interface UserPermissions { | ||
id: string; | ||
userId: string; | ||
admin: boolean; | ||
user: boolean; | ||
} | ||
|
||
export interface AuthDetails { | ||
token: string; | ||
refreshToken: string; | ||
} | ||
|
||
export interface Permissions { | ||
admin: boolean; | ||
user: boolean; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export interface ForLogging { | ||
log(event: string, message: string): void; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { RepoUser } from "../../../repository/app/schemas"; | ||
import { Permissions } from "../../app/schemas/auth"; | ||
|
||
export interface ForRepoQuerying { | ||
getUser(email: string): Promise<RepoUser>; | ||
getPermissions(userId: string): Promise<Permissions>; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./for-repo-querying"; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { AuthDetails, Permissions } from "../../app/schemas/auth"; | ||
|
||
export interface ForManagingAuthentication { | ||
getAuthDetails(email: string, password: string): Promise<AuthDetails>; | ||
getPermissions(userId: string): Promise<Permissions>; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./for-managing-authentication"; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export * from './control-authenticator-stub-adapter'; | ||
export * from './repo-querier-stub-adapter'; | ||
export * from './repo-querier-local-adapter'; | ||
export * from './repo-querier-stub-adapter'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { userManagerProxy } from "../../../repository/app/composition-root"; | ||
import { ExternalUser } from "../../../repository/app/schemas"; | ||
import { User } from "../../app/schemas"; | ||
import { ForRepoQuerying } from "../../ports/drivens"; | ||
|
||
export class RepoQuerierLocalAdapter implements ForRepoQuerying { | ||
async getUser(email: string): Promise<ExternalUser> { | ||
return await userManagerProxy.getUser(email) | ||
} | ||
|
||
async createUser(user: User): Promise<ExternalUser> { | ||
return await userManagerProxy.createUser(user) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ import { | |
authTRPCAdapter, | ||
} from "../adapters/drivers"; | ||
import { initTRPC } from "@trpc/server"; | ||
import { RepoQuerierLocalAdapter } from "../adapters/drivens"; | ||
|
||
const compositionMock = () => { | ||
// DRIVENS | ||
|
@@ -29,7 +30,7 @@ const compositionMock = () => { | |
}; | ||
|
||
export const { authenticatorProxyAdapter } = compositionMock(); | ||
/* | ||
/* | ||
const registerMock = { | ||
name: "John", | ||
email: "[email protected]", | ||
|
@@ -42,12 +43,12 @@ authenticatorProxyAdapter.register(registerMock); | |
export const localTRPCCompose = () => { | ||
// DRIVENS | ||
const controlAuthenticatorStub = new ControlAuthenticatorStub(); | ||
const repoQuerierStub = new RepoQuerierStub(); | ||
const repoQuerierLocal = new RepoQuerierLocalAdapter(); | ||
|
||
// APP | ||
const dashboardApiMock = new DashboardApi( | ||
controlAuthenticatorStub, | ||
repoQuerierStub | ||
repoQuerierLocal | ||
); | ||
|
||
// TRPC INSTANCE | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
export * from './user-manager-proxy'; | ||
export * from './user-permission-manager-proxy'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { Repository } from "../../app/repository"; | ||
import { Permissions, UserPermission } from "../../app/schemas"; | ||
import { ForManagingPermission } from "../../ports/drivers/for-managing-permission"; | ||
|
||
export class UserPermissionManagerProxy implements ForManagingPermission { | ||
constructor(private readonly repository: Repository) {} | ||
|
||
async getUserPermissions(userId: string): Promise<UserPermission> { | ||
return this.repository.getUserPermissions(userId) | ||
} | ||
|
||
async createUserPermissions(userId: string, permissions: Permissions): Promise<UserPermission> { | ||
return this.repository.createUserPermissions(userId, permissions) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Si es un stub no debería tener utilización real de los proxy u otros adapters. Debería de retornar un mock
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Creo que te has equivocado con el nombre del archivo y por eso sigue diciendo que es un stub, porque es una copia del RepoQuerierStubAdapter pero ha faltado modificar
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corregido!