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

N21-1968 schulconnex config fix #5002

Merged
merged 5 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
Original file line number Diff line number Diff line change
@@ -1,23 +1,37 @@
import { OauthAdapterService } from '@modules/oauth/service';
import { HttpModule, HttpService } from '@nestjs/axios';
import { DynamicModule, Module } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { Logger, LoggerModule } from '@src/core/logger';
import { SchulconnexRestClient } from './schulconnex-rest-client';
import { SchulconnexRestClientOptions } from './schulconnex-rest-client-options';

@Module({})
export class SchulconnexClientModule {
static register(options: SchulconnexRestClientOptions): DynamicModule {
static registerAsync(): DynamicModule {
return {
imports: [HttpModule, LoggerModule],
module: SchulconnexClientModule,
providers: [
OauthAdapterService,
{
provide: SchulconnexRestClient,
useFactory: (httpService: HttpService, oauthAdapterService: OauthAdapterService, logger: Logger) =>
new SchulconnexRestClient(options, httpService, oauthAdapterService, logger),
inject: [HttpService, OauthAdapterService, Logger],
useFactory: (
httpService: HttpService,
oauthAdapterService: OauthAdapterService,
logger: Logger,
configService: ConfigService
) => {
const options: SchulconnexRestClientOptions = {
apiUrl: configService.get<string>('SCHULCONNEX_CLIENT__API_URL'),
tokenEndpoint: configService.get<string>('SCHULCONNEX_CLIENT__TOKEN_ENDPOINT'),
clientId: configService.get<string>('SCHULCONNEX_CLIENT__CLIENT_ID'),
clientSecret: configService.get<string>('SCHULCONNEX_CLIENT__CLIENT_SECRET'),
personenInfoTimeoutInMs: configService.get<number>('SCHULCONNEX_CLIENT__PERSONEN_INFO_TIMEOUT_IN_MS'),
};
return new SchulconnexRestClient(options, httpService, oauthAdapterService, logger);
},
inject: [HttpService, OauthAdapterService, Logger, ConfigService],
},
],
exports: [SchulconnexRestClient],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
export interface SchulconnexRestClientOptions {
apiUrl: string;
apiUrl?: string;

tokenEndpoint: string;
tokenEndpoint?: string;

clientId: string;
clientId?: string;

clientSecret: string;
clientSecret?: string;

personenInfoTimeoutInMs?: number;
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class SchulconnexRestClient implements SchulconnexApiInterface {
private readonly logger: Logger
) {
this.checkOptions();
this.SCHULCONNEX_API_BASE_URL = options.apiUrl;
this.SCHULCONNEX_API_BASE_URL = options.apiUrl || '';
}

// TODO: N21-1678 use this in provisioning module
Expand Down Expand Up @@ -63,10 +63,12 @@ export class SchulconnexRestClient implements SchulconnexApiInterface {
return response;
}

private checkOptions(): void {
private checkOptions(): boolean {
if (!this.options.apiUrl || !this.options.clientId || !this.options.clientSecret || !this.options.tokenEndpoint) {
this.logger.debug(new SchulconnexConfigurationMissingLoggable());
return false;
}
return true;
}

private async getRequest<T>(url: URL, accessToken: string, timeout?: number): Promise<T> {
Expand All @@ -86,13 +88,17 @@ export class SchulconnexRestClient implements SchulconnexApiInterface {
private async requestClientCredentialToken(): Promise<OAuthTokenDto> {
const { tokenEndpoint, clientId, clientSecret } = this.options;

if (!this.checkOptions()) {
return Promise.reject(new Error('Missing configuration for SchulconnexRestClient'));
}

const payload: ClientCredentialsGrantTokenRequest = new ClientCredentialsGrantTokenRequest({
client_id: clientId,
client_secret: clientSecret,
client_id: clientId ?? '',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checkOptions above makes sure this is set, but ok...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but the ide complains... i am not happy about those checks everywhere. So i created a ticket to refactor it :)

client_secret: clientSecret ?? '',
grant_type: OAuthGrantType.CLIENT_CREDENTIALS_GRANT,
});

const tokenDto: OAuthTokenDto = await this.oauthAdapterService.sendTokenRequest(tokenEndpoint, payload);
const tokenDto: OAuthTokenDto = await this.oauthAdapterService.sendTokenRequest(tokenEndpoint ?? '', payload);

return tokenDto;
}
Expand Down
27 changes: 10 additions & 17 deletions apps/server/src/modules/idp-console/idp-console.module.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,23 @@
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { Configuration } from '@hpi-schul-cloud/commons/lib';
import { ConsoleWriterModule } from '@infra/console';
import { RabbitMQWrapperModule } from '@infra/rabbitmq';
import { SchulconnexClientModule } from '@infra/schulconnex-client';
import { SynchronizationEntity, SynchronizationModule } from '@modules/synchronization';
import { defaultMikroOrmOptions } from '@modules/server';
import { DB_PASSWORD, DB_URL, DB_USERNAME } from '@src/config';
import { ALL_ENTITIES } from '@shared/domain/entity';
import { MikroOrmModule } from '@mikro-orm/nestjs';
import { defaultMikroOrmOptions } from '@modules/server';
import { SynchronizationEntity, SynchronizationModule } from '@modules/synchronization';
import { UserModule } from '@modules/user';
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { ALL_ENTITIES } from '@shared/domain/entity';
import { DB_PASSWORD, DB_URL, DB_USERNAME } from '@src/config';
import { LoggerModule } from '@src/core/logger';
import { RabbitMQWrapperModule } from '@infra/rabbitmq';
import { ConsoleWriterModule } from '@infra/console';
import { ConsoleModule } from 'nestjs-console';
import { SynchronizationUc } from './uc';
import { IdpSyncConsole } from './idp-sync-console';
import { SynchronizationUc } from './uc';

@Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
SchulconnexClientModule.register({
apiUrl: Configuration.get('SCHULCONNEX_CLIENT__API_URL') as string,
tokenEndpoint: Configuration.get('SCHULCONNEX_CLIENT__TOKEN_ENDPOINT') as string,
clientId: Configuration.get('SCHULCONNEX_CLIENT__CLIENT_ID') as string,
clientSecret: Configuration.get('SCHULCONNEX_CLIENT__CLIENT_SECRET') as string,
personenInfoTimeoutInMs: Configuration.get('SCHULCONNEX_CLIENT__PERSONEN_INFO_TIMEOUT_IN_MS') as number,
}),
SchulconnexClientModule.registerAsync(),
SynchronizationModule,
MikroOrmModule.forRoot({
...defaultMikroOrmOptions,
Expand Down
9 changes: 1 addition & 8 deletions apps/server/src/modules/provisioning/provisioning.module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Configuration } from '@hpi-schul-cloud/commons/lib';
import { AccountModule } from '@modules/account';
import { GroupModule } from '@modules/group';
import { LearnroomModule } from '@modules/learnroom';
Expand Down Expand Up @@ -39,13 +38,7 @@ import {
LoggerModule,
GroupModule,
LearnroomModule,
SchulconnexClientModule.register({
apiUrl: Configuration.get('SCHULCONNEX_CLIENT__API_URL') as string,
tokenEndpoint: Configuration.get('SCHULCONNEX_CLIENT__TOKEN_ENDPOINT') as string,
clientId: Configuration.get('SCHULCONNEX_CLIENT__CLIENT_ID') as string,
clientSecret: Configuration.get('SCHULCONNEX_CLIENT__CLIENT_SECRET') as string,
personenInfoTimeoutInMs: Configuration.get('SCHULCONNEX_CLIENT__PERSONEN_INFO_TIMEOUT_IN_MS') as number,
}),
SchulconnexClientModule.registerAsync(),
UserLicenseModule,
],
providers: [
Expand Down
20 changes: 18 additions & 2 deletions apps/server/src/modules/server/server.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Configuration } from '@hpi-schul-cloud/commons';
import type { IdentityManagementConfig } from '@infra/identity-management';
import type { SchulconnexClientConfig } from '@infra/schulconnex-client';
import type { AccountConfig } from '@modules/account';
import { AlertConfig } from '@modules/alert';
import type { AuthenticationConfig, XApiKeyConfig } from '@modules/authentication';
import type { BoardConfig } from '@modules/board';
import type { MediaBoardConfig } from '@modules/board/media-board.config';
Expand All @@ -21,10 +22,9 @@ import { type IUserImportFeatures, UserImportConfiguration } from '@modules/user
import type { UserLoginMigrationConfig } from '@modules/user-login-migration';
import { type IVideoConferenceSettings, VideoConferenceConfiguration } from '@modules/video-conference';
import { LanguageType } from '@shared/domain/interface';
import { SchulcloudTheme } from '@shared/domain/types';
import type { CoreModuleConfig } from '@src/core';
import type { MailConfig } from '@src/infra/mail/interfaces/mail-config';
import { AlertConfig } from '@modules/alert';
import { SchulcloudTheme } from '@shared/domain/types';
import { Timezone } from './types/timezone.enum';

export enum NodeEnvType {
Expand Down Expand Up @@ -112,6 +112,10 @@ export interface ServerConfig
I18N__DEFAULT_TIMEZONE: Timezone;
BOARD_COLLABORATION_URI: string;
FEATURE_NEW_LAYOUT_ENABLED: boolean;
SCHULCONNEX_CLIENT__API_URL: string | undefined;
SCHULCONNEX_CLIENT__TOKEN_ENDPOINT: string | undefined;
SCHULCONNEX_CLIENT__CLIENT_ID: string | undefined;
SCHULCONNEX_CLIENT__CLIENT_SECRET: string | undefined;
}

const config: ServerConfig = {
Expand Down Expand Up @@ -223,6 +227,18 @@ const config: ServerConfig = {
I18N__DEFAULT_LANGUAGE: Configuration.get('I18N__DEFAULT_LANGUAGE') as unknown as LanguageType,
I18N__FALLBACK_LANGUAGE: Configuration.get('I18N__FALLBACK_LANGUAGE') as unknown as LanguageType,
I18N__DEFAULT_TIMEZONE: Configuration.get('I18N__DEFAULT_TIMEZONE') as Timezone,
SCHULCONNEX_CLIENT__API_URL: Configuration.has('SCHULCONNEX_CLIENT__API_URL')
? (Configuration.get('SCHULCONNEX_CLIENT__API_URL') as string)
: undefined,
SCHULCONNEX_CLIENT__TOKEN_ENDPOINT: Configuration.has('SCHULCONNEX_CLIENT__TOKEN_ENDPOINT')
? (Configuration.get('SCHULCONNEX_CLIENT__TOKEN_ENDPOINT') as string)
: undefined,
SCHULCONNEX_CLIENT__CLIENT_ID: Configuration.has('SCHULCONNEX_CLIENT__CLIENT_ID')
? (Configuration.get('SCHULCONNEX_CLIENT__CLIENT_ID') as string)
: undefined,
SCHULCONNEX_CLIENT__CLIENT_SECRET: Configuration.has('SCHULCONNEX_CLIENT__CLIENT_SECRET')
? (Configuration.get('SCHULCONNEX_CLIENT__CLIENT_SECRET') as string)
: undefined,
SCHULCONNEX_CLIENT__PERSONEN_INFO_TIMEOUT_IN_MS: Configuration.get(
'SCHULCONNEX_CLIENT__PERSONEN_INFO_TIMEOUT_IN_MS'
) as number,
Expand Down
10 changes: 2 additions & 8 deletions apps/server/src/modules/server/server.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { SchulconnexClientModule } from '@infra/schulconnex-client';
import { Dictionary, IPrimaryKey } from '@mikro-orm/core';
import { MikroOrmModule, MikroOrmModuleSyncOptions } from '@mikro-orm/nestjs';
import { AccountApiModule } from '@modules/account/account-api.module';
import { AlertModule } from '@modules/alert/alert.module';
import { AuthenticationApiModule } from '@modules/authentication/authentication-api.module';
import { BoardApiModule } from '@modules/board/board-api.module';
import { MediaBoardApiModule } from '@modules/board/media-board-api.module';
Expand Down Expand Up @@ -40,7 +41,6 @@ import { ALL_ENTITIES } from '@shared/domain/entity';
import { createConfigModuleOptions, DB_PASSWORD, DB_URL, DB_USERNAME } from '@src/config';
import { CoreModule } from '@src/core';
import { LoggerModule } from '@src/core/logger';
import { AlertModule } from '@modules/alert/alert.module';
import { UserLicenseModule } from '../user-license';
import { ServerConfigController, ServerController, ServerUc } from './api';
import { SERVER_CONFIG_TOKEN, serverConfig } from './server.config';
Expand All @@ -58,13 +58,7 @@ const serverModules = [
NewsModule,
UserApiModule,
UsersAdminApiModule,
SchulconnexClientModule.register({
apiUrl: Configuration.get('SCHULCONNEX_CLIENT__API_URL') as string,
tokenEndpoint: Configuration.get('SCHULCONNEX_CLIENT__TOKEN_ENDPOINT') as string,
clientId: Configuration.get('SCHULCONNEX_CLIENT__CLIENT_ID') as string,
clientSecret: Configuration.get('SCHULCONNEX_CLIENT__CLIENT_SECRET') as string,
personenInfoTimeoutInMs: Configuration.get('SCHULCONNEX_CLIENT__PERSONEN_INFO_TIMEOUT_IN_MS') as number,
}),
SchulconnexClientModule.registerAsync(),
ImportUserModule,
UserImportConfigModule,
LearnroomApiModule,
Expand Down
9 changes: 1 addition & 8 deletions apps/server/src/modules/user-import/user-import.module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Configuration } from '@hpi-schul-cloud/commons/lib';
import { SchulconnexClientModule } from '@infra/schulconnex-client';
import { AccountModule } from '@modules/account';
import { AuthorizationModule } from '@modules/authorization';
Expand All @@ -25,13 +24,7 @@ import { UserImportConfigModule } from './user-import-config.module';
HttpModule,
UserModule,
OauthModule,
SchulconnexClientModule.register({
apiUrl: Configuration.get('SCHULCONNEX_CLIENT__API_URL') as string,
tokenEndpoint: Configuration.get('SCHULCONNEX_CLIENT__TOKEN_ENDPOINT') as string,
clientId: Configuration.get('SCHULCONNEX_CLIENT__CLIENT_ID') as string,
clientSecret: Configuration.get('SCHULCONNEX_CLIENT__CLIENT_SECRET') as string,
personenInfoTimeoutInMs: Configuration.get('SCHULCONNEX_CLIENT__PERSONEN_INFO_TIMEOUT_IN_MS') as number,
}),
SchulconnexClientModule.registerAsync(),
UserLoginMigrationModule,
],
controllers: [ImportUserController],
Expand Down
4 changes: 1 addition & 3 deletions config/development.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,7 @@
"FEATURE_BOARD_LAYOUT_ENABLED": true,
"SCHULCONNEX_CLIENT": {
"API_URL": "http://localhost:8888/v1/",
"TOKEN_ENDPOINT": "http://localhost:8888/realms/SANIS/protocol/openid-connect/token",
"CLIENT_ID": "schulcloud",
"CLIENT_SECRET": "secret"
"TOKEN_ENDPOINT": "http://localhost:8888/realms/SANIS/protocol/openid-connect/token"
},
"ETHERPAD_URI": "http://localhost:9001/api/1/",
"ETHERPAD": {
Expand Down
Loading