Skip to content

Commit

Permalink
refactor: remove unused dep hydra (#1096)
Browse files Browse the repository at this point in the history
Co-authored-by: takaro-ci-bot[bot] <138661031+takaro-ci-bot[bot]@users.noreply.github.com>
  • Loading branch information
niekcandaele and takaro-ci-bot[bot] authored Aug 13, 2024
1 parent 58ee001 commit 98cadae
Show file tree
Hide file tree
Showing 29 changed files with 80 additions and 462 deletions.
2 changes: 0 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ POSTGRES_PORT=5432
# TAKARO
#################################

# These are created in Hydra, see the docs.
ADMIN_CLIENT_ID="CHANGE_THIS"
ADMIN_CLIENT_SECRET="CHANGE_THIS"

# This is the secret used to sign the JWT tokens
Expand Down
3 changes: 1 addition & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@
"outFiles": ["${workspaceFolder}/dist/extension.js"],
"preLaunchTask": "${defaultBuildTask}",
"env": {
"DEBUG": "true",
"TAKARO_OAUTH_HOST": "http://127.0.0.1:14444"
"DEBUG": "true"
}
}
]
Expand Down
36 changes: 0 additions & 36 deletions deploy/compose/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -145,42 +145,6 @@ services:
networks:
- backend

hydra:
image: oryd/hydra:v2.0.3
ports:
- '127.0.0.1:4444:4444' # Public port
- '127.0.0.1:4445:4445' # Admin port
- '127.0.0.1:5555:5555' # Port for hydra token user
command: serve -c /etc/config/hydra/hydra.yml all --dev
volumes:
- ../../containers/ory/hydra:/etc/config/hydra
environment:
- DSN=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgresql_hydra:5432/hydra
- URLS_SELF_ISSUER=http://hydra:4444/
networks:
- backend
hydra-migrate:
image: oryd/hydra:v2.0.3
environment:
- DSN=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgresql_hydra:5432/hydra
command: migrate -c /etc/config/hydra/hydra.yml sql -e --yes
volumes:
- ../../containers/ory/hydra:/etc/config/hydra
networks:
- backend
postgresql_hydra:
image: postgres:15
ports:
- 127.0.0.1:13102:5432
volumes:
- ./_data/hydra-db:/var/lib/postgresql/data
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: hydra
networks:
- backend

prometheus:
image: prom/prometheus:v2.52.0
networks:
Expand Down
34 changes: 0 additions & 34 deletions docker-compose.test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,34 +34,6 @@ services:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}

hydra:
environment:
- DSN=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgresql_hydra:5432/${POSTGRES_DB}
extends:
file: docker-compose.yml
service: hydra

hydra-e2e:
environment:
- DSN=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgresql_hydra:5432/${POSTGRES_DB}
extends:
file: docker-compose.yml
service: hydra-e2e

hydra-migrate:
environment:
- DSN=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgresql_hydra:5432/${POSTGRES_DB}
extends:
file: docker-compose.yml
service: hydra-migrate

postgresql_hydra:
image: postgres:15
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}

takaro:
container_name: takaro
build:
Expand All @@ -76,9 +48,7 @@ services:
POSTGRES_HOST: 'postgresql'
POSTGRES_ENCRYPTION_KEY: ${POSTGRES_ENCRYPTION_KEY}
REDIS_HOST: 'redis'
ADMIN_CLIENT_ID: ${ADMIN_CLIENT_ID}
ADMIN_CLIENT_SECRET: ${ADMIN_CLIENT_SECRET}
TAKARO_OAUTH_HOST: http://hydra:4444
TAKARO_HOST: http://takaro_api:3000
KRATOS_ADMIN_URL: http://kratos:4434
TEST_HTTP_TARGET: http://takaro_api:3000
Expand All @@ -105,9 +75,7 @@ services:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_HOST: 'postgresql'
POSTGRES_ENCRYPTION_KEY: ${POSTGRES_ENCRYPTION_KEY}
ADMIN_CLIENT_ID: ${ADMIN_CLIENT_ID}
ADMIN_CLIENT_SECRET: ${ADMIN_CLIENT_SECRET}
TAKARO_OAUTH_HOST: http://hydra:4444
TAKARO_HOST: http://takaro_api:3000
MOCK_GAMESERVER_HOST: http://takaro_mock_gameserver:3002
CORS_ALLOWED_ORIGINS: http://127.0.0.1:13000,http://127.0.0.1:13001
Expand Down Expand Up @@ -147,9 +115,7 @@ services:
environment:
LOGGING_LEVEL: debug
REDIS_HOST: 'redis'
ADMIN_CLIENT_ID: ${ADMIN_CLIENT_ID}
ADMIN_CLIENT_SECRET: ${ADMIN_CLIENT_SECRET}
TAKARO_OAUTH_HOST: http://hydra:4444
TAKARO_HOST: http://takaro_api:3000
TRACING_ENABLED: ${TRACING_ENABLED}
TRACING_ENDPOINT: "http://grafana_agent:4317"
Expand Down
49 changes: 0 additions & 49 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ services:

TEST_HTTP_TARGET: http://takaro:3000
MAILHOG_URL: http://mailhog:8025
TAKARO_OAUTH_HOST: http://hydra:4444

VITE_API: http://127.0.0.1:13000
VITE_ORY_URL: http://127.0.0.1:4433
Expand Down Expand Up @@ -153,54 +152,6 @@ services:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: kratos
hydra-e2e:
image: oryd/hydra:v2.0.3
ports:
- '14444:4444' # Public port
- '14445:4445' # Admin port
- '15555:5555' # Port for hydra token user
command: serve -c /etc/config/hydra/hydra.yml all --dev
volumes:
- ./containers/ory/hydra:/etc/config/hydra
environment:
- DSN=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgresql_hydra:5432/hydra
- URLS_SELF_ISSUER=http://127.0.0.1:14444/
hydra:
image: oryd/hydra:v2.0.3
ports:
- '4444:4444' # Public port
- '4445:4445' # Admin port
- '5555:5555' # Port for hydra token user
command: serve -c /etc/config/hydra/hydra.yml all --dev
volumes:
- ./containers/ory/hydra:/etc/config/hydra
environment:
- DSN=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgresql_hydra:5432/hydra
- URLS_SELF_ISSUER=http://hydra:4444/
hydra-migrate:
image: oryd/hydra:v2.0.3
environment:
- DSN=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgresql_hydra:5432/hydra
command: migrate -c /etc/config/hydra/hydra.yml sql -e --yes
volumes:
- ./containers/ory/hydra:/etc/config/hydra
postgresql_hydra:
image: postgres:15
ports:
- 127.0.0.1:13102:5432
volumes:
- ./_data/hydra-db:/var/lib/postgresql/data
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: hydra
# mailslurper:
# image: oryd/mailslurper:latest-smtps
# ports:
# - '4436:4436'
# - '4437:4437'
# volumes:
# - ./containers/mailslurper/config.json:/go/src/github.com/mailslurper/mailslurper/cmd/mailslurper/config.json

mailhog:
image: mailhog/mailhog
Expand Down
6 changes: 4 additions & 2 deletions packages/app-api/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,11 @@ const configSchema = {
},
};

export const config = new Config<IHttpConfig & IQueuesConfig & IDbConfig & Pick<IAuthConfig, 'kratos' | 'hydra'>>([
export const config = new Config<
IHttpConfig & IQueuesConfig & IDbConfig & Pick<IAuthConfig, 'kratos' | 'adminClientSecret'>
>([
configSchema,
queuesConfigSchema,
dbConfigSchema,
{ kratos: authConfigSchema.kratos, hydra: authConfigSchema.hydra },
{ kratos: authConfigSchema.kratos, adminClientSecret: authConfigSchema.adminClientSecret },
]);
4 changes: 2 additions & 2 deletions packages/app-api/src/controllers/DomainController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
DomainUpdateInputDTO,
DOMAIN_STATES,
} from '../service/DomainService.js';
import { apiResponse, APIOutput, adminAuthMiddleware } from '@takaro/http';
import { apiResponse, APIOutput } from '@takaro/http';

import { Param, Body, Get, Post, Put, Delete, JsonController, UseBefore, Req, Res } from 'routing-controllers';

Expand Down Expand Up @@ -63,7 +63,7 @@ export class TokenOutputDTOAPI extends APIOutput<TokenOutputDTO> {
@OpenAPI({
security: [{ adminAuth: [] }],
})
@UseBefore(adminAuthMiddleware)
@UseBefore(AuthService.adminAuthMiddleware)
@JsonController()
export class DomainController {
@Post('/domain/search')
Expand Down
4 changes: 1 addition & 3 deletions packages/app-api/src/executors/executeFunction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,8 @@ const log = logger('worker:function');
const takaro = new AdminClient({
url: config.get('takaro.url'),
auth: {
clientId: config.get('hydra.adminClientId'),
clientSecret: config.get('hydra.adminClientSecret'),
clientSecret: config.get('adminClientSecret'),
},
OAuth2URL: config.get('hydra.publicUrl'),
log: logger('adminClient'),
});

Expand Down
28 changes: 27 additions & 1 deletion packages/app-api/src/service/AuthService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ export class AuthService extends DomainScoped {

// Either the user is authenticated via the IDP or via a JWT (api client)
// The token check is 'cheaper' than a request to the IDP so we do it first
// TODO: At some point we should refactor our custom JWT and use Ory (Hydra) fully or something...
// TODO: At some point we should refactor our custom JWT and/or use Ory (Hydra) fully or something...
if (req.headers['x-takaro-token']) {
const token = req.headers['x-takaro-token'] as string;
const payload = await this.verifyJwt(token);
Expand Down Expand Up @@ -264,6 +264,32 @@ export class AuthService extends DomainScoped {
return fn;
}

static adminAuthMiddleware(request: Request, response: Response, next: NextFunction) {
try {
const rawToken = request.headers['x-takaro-admin-token'];

if (!rawToken) {
log.warn('No token provided');
return next(new errors.UnauthorizedError());
}

if (!config.get('adminClientSecret')) {
log.warn('No admin client secret provided');
return next(new errors.UnauthorizedError());
}

if (rawToken !== config.get('adminClientSecret')) {
log.warn('Invalid admin token');
return next(new errors.UnauthorizedError());
}

return next();
} catch (error) {
log.error('Unexpected error', { error });
next(new errors.ForbiddenError());
}
}

static initPassport(): string[] {
const initializedStrategies: string[] = [];
const discordClientId = config.get('auth.discord.clientId');
Expand Down
4 changes: 1 addition & 3 deletions packages/app-connector/src/lib/GameServerManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@ const SYNC_INTERVAL_MS = config.get('gameServerManager.syncIntervalMs');
const takaro = new AdminClient({
url: config.get('takaro.url'),
auth: {
clientId: config.get('hydra.adminClientId'),
clientSecret: config.get('hydra.adminClientSecret'),
clientSecret: config.get('adminClientSecret'),
},
OAuth2URL: config.get('hydra.publicUrl'),
log: logger('adminClient'),
});

Expand Down
11 changes: 4 additions & 7 deletions packages/lib-apiclient/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# @takaro/apiclient

Automatically generated API client for Takaro.
Automatically generated API client for Takaro.

## Usage

Expand All @@ -12,10 +12,8 @@ const url = 'http://localhost:13000';
const adminClient = new AdminClient({
url,
auth: {
clientId: config.get('hydra.adminClientId'),
clientSecret: config.get('hydra.adminClientSecret'),
clientSecret: config.get('adminClientSecret'),
},
OAuth2URL: config.get('hydra.publicUrl'),
});

const createdDomain = await this.adminClient.domain.domainControllerCreate({
Expand All @@ -26,10 +24,9 @@ const client = new Client({
url,
auth: {
username: createdDomain.data.data.rootUser.email,
password: createdDomain.data.data.password
password: createdDomain.data.data.password,
},
});

await client.login();

```
```
53 changes: 3 additions & 50 deletions packages/lib-apiclient/src/lib/adminClient.ts
Original file line number Diff line number Diff line change
@@ -1,71 +1,24 @@
import { DomainApi } from '../generated/index.js';
import { BaseApiClient, IBaseApiClientConfig } from './baseClient.js';
import type { Client as OpenIdClient, Issuer, TokenSet } from 'openid-client';
import { AxiosInstance } from 'axios';

export interface IAdminApiClientConfig extends IBaseApiClientConfig {
auth: {
clientId: string;
clientSecret: string;
};
OAuth2URL: string;
}

export class AdminClient extends BaseApiClient<IAdminApiClientConfig> {
private cachedIssuer: Issuer | null = null;
private cachedClient: OpenIdClient;
private token: TokenSet;

constructor(config: IAdminApiClientConfig) {
super(config);
this.addAuthInterceptor(this.axios);
}

private async getIssuer() {
const { Issuer, custom } = await import('openid-client');

if (!this.cachedIssuer) {
custom.setHttpOptionsDefaults({
timeout: 10000,
});
this.cachedIssuer = await Issuer.discover(this.config.OAuth2URL);
this.log.debug(`Discovered issuer at ${this.config.OAuth2URL}`);
}

if (!this.cachedClient) {
this.cachedClient = new this.cachedIssuer.Client({
client_id: this.config.auth.clientId,
client_secret: this.config.auth.clientSecret,
});
}

return { issuer: this.cachedIssuer, client: this.cachedClient };
}

public async getOidcToken(): Promise<TokenSet> {
const { client } = await this.getIssuer();
const grantRes = await client.grant({
grant_type: 'client_credentials',
audience: 't:api:admin',
});

if (!grantRes.access_token) {
this.log.error('Failed to get access token');
throw new Error('Failed to get access token');
}

return grantRes;
this.addAuthInterceptor(config.auth.clientSecret, this.axios);
}

private addAuthInterceptor(axios: AxiosInstance): AxiosInstance {
private addAuthInterceptor(token: string, axios: AxiosInstance): AxiosInstance {
axios.interceptors.request.use(async (request) => {
if (request.url?.includes('health')) return request;
if (!this.token || this.token.expired()) {
this.log.debug('Token expired, getting new token');
this.token = await this.getOidcToken();
}

request.headers['Authorization'] = `Bearer ${this.token.access_token}`;
request.headers['X-Takaro-Admin-Token'] = token;
return request;
});

Expand Down
Loading

0 comments on commit 98cadae

Please sign in to comment.