Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/npm_and_yarn/axios-1.7.2
Browse files Browse the repository at this point in the history
  • Loading branch information
bischofmax authored Jul 18, 2024
2 parents 28e57a7 + 8a11bc9 commit b9fa3c0
Show file tree
Hide file tree
Showing 492 changed files with 8,150 additions and 7,348 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/migrations.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Reminder to update seed data after migration
# If this workflow fails, it is a hint that you forgot to update the seed data after a migration.
# It is only a hint, because it only checks if you updated the migration collection in the seed data.
# It is only a hint, because it only checks if you updated the migration collection in the seed data.
# It is not a check that you updated the whole seed data correctly.
# See the documentation for advice: https://documentation.dbildungscloud.dev/docs/schulcloud-server/Migrations#committing-a-migration

Expand All @@ -11,7 +11,7 @@ on:
branches: [ main ]

env:
MONGODB_VERSION: 5.0
MONGODB_VERSION: 6.0
NODE_VERSION: '18'
jobs:
migration:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ permissions:
contents: read

env:
MONGODB_VERSION: 5.0
MONGODB_VERSION: 6.0
NODE_VERSION: '18'
jobs:
feathers_tests_cov:
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,5 @@ build
/coverage
/.nyc_output
/.idea/
/apps/server/src/modules/board/loadtest/**/*.html
/apps/server/src/modules/board/loadtest/artilleryreport.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ spec:
git.branch: {{ SCHULCLOUD_SERVER_BRANCH_NAME }}
git.repo: {{ SCHULCLOUD_SERVER_REPO_NAME }}
spec:
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
runAsNonRoot: true
volumes:
- name: libraries-list
configMap:
Expand Down
6 changes: 0 additions & 6 deletions ansible/roles/schulcloud-server-core/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,6 @@
namespace: "{{ NAMESPACE }}"
template: api-files-deployment.yml.j2

- name: FileStorageDeployment
kubernetes.core.k8s:
kubeconfig: ~/.kube/config
namespace: "{{ NAMESPACE }}"
template: api-files-deployment.yml.j2

- name: File Storage Ingress
kubernetes.core.k8s:
kubeconfig: ~/.kube/config
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,10 @@ data:
CALENDAR_URI: "{{ CALENDAR_URI }}"
ROCKET_CHAT_URI: "{{ ROCKET_CHAT_URI }}"
ETHERPAD__PAD_URI: "https://{{ DOMAIN }}/etherpad/p"
FEATURE_IDENTITY_MANAGEMENT_ENABLED: "{{ FEATURE_IDENTITY_MANAGEMENT_ENABLED }}"
FEATURE_IDENTITY_MANAGEMENT_STORE_ENABLED: "{{ FEATURE_IDENTITY_MANAGEMENT_STORE_ENABLED }}"
FEATURE_IDENTITY_MANAGEMENT_LOGIN_ENABLED: "{{ FEATURE_IDENTITY_MANAGEMENT_LOGIN_ENABLED }}"
IDENTITY_MANAGEMENT__INTERNAL_URI: "{{ IDENTITY_MANAGEMENT__INTERNAL_URI }}"
IDENTITY_MANAGEMENT__EXTERNAL_URI: "{{ IDENTITY_MANAGEMENT__EXTERNAL_URI }}"
IDENTITY_MANAGEMENT__TENANT: "{{ IDENTITY_MANAGEMENT__TENANT }}"
IDENTITY_MANAGEMENT__CLIENTID: "{{ IDENTITY_MANAGEMENT__CLIENTID }}"
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ spec:
spec:
template:
spec:
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
runAsNonRoot: true
containers:
- name: delete-s3-files-cronjob
image: {{ SCHULCLOUD_SERVER_IMAGE }}:{{ SCHULCLOUD_SERVER_IMAGE_TAG }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ spec:
spec:
template:
spec:
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
runAsNonRoot: true
containers:
- name: data-deletion-trigger-cronjob
image: {{ SCHULCLOUD_SERVER_IMAGE }}:{{ SCHULCLOUD_SERVER_IMAGE_TAG }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ spec:
labels:
app: api-migration
spec:
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
runAsNonRoot: true
containers:
- name: api-migration-job
image: {{ SCHULCLOUD_SERVER_IMAGE }}:{{ SCHULCLOUD_SERVER_IMAGE_TAG }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ spec:
spec:
template:
spec:
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
runAsNonRoot: true
containers:
- name: tldraw-delete-files-cronjob
image: {{ SCHULCLOUD_SERVER_IMAGE }}:{{ SCHULCLOUD_SERVER_IMAGE_TAG }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,21 @@ data:
# the additional namespace intended for use for the testing (and development) purposes if one want
# to test anything that includes signing in with the IServ on nbc instance, but don't want to use
# the default dev nbc instance as it would require merging the code to the main branch first.
# Removed oauth config
# "oauthConfig": {
# "clientId": "'$ISERV_OAUTH_CLIENT_ID'",
# "clientSecret": "'$ISERV_OAUTH_CLIENT_SECRET'",
# "tokenEndpoint": "'$ISERV_URL'/iserv/auth/public/token",
# "grantType": "authorization_code",
# "scope": "openid uuid",
# "responseType": "code",
# "redirectUri": "https://'$NS'.nbc.dbildungscloud.dev/api/v3/sso/oauth",
# "authEndpoint": "'$ISERV_URL'/iserv/auth/auth",
# "provider": "iserv",
# "logoutEndpoint": "'$ISERV_URL'/iserv/auth/logout",
# "jwksEndpoint": "'$ISERV_URL'/iserv/public/jwk",
# "issuer": "'$ISERV_URL'"
# }

if [ "$SC_THEME" = "n21" ] && [[ "$NS" =~ ^(main|iserv-test)$ ]]; then
ISERV_SYSTEM_ID=0000d186816abba584714c92
Expand Down Expand Up @@ -235,20 +250,6 @@ data:
},
"type": "ldap",
"provisioningStrategy": "iserv",
"oauthConfig": {
"clientId": "'$ISERV_OAUTH_CLIENT_ID'",
"clientSecret": "'$ISERV_OAUTH_CLIENT_SECRET'",
"tokenEndpoint": "'$ISERV_URL'/iserv/auth/public/token",
"grantType": "authorization_code",
"scope": "openid uuid",
"responseType": "code",
"redirectUri": "https://'$NS'.nbc.dbildungscloud.dev/api/v3/sso/oauth",
"authEndpoint": "'$ISERV_URL'/iserv/auth/auth",
"provider": "iserv",
"logoutEndpoint": "'$ISERV_URL'/iserv/auth/logout",
"jwksEndpoint": "'$ISERV_URL'/iserv/public/jwk",
"issuer": "'$ISERV_URL'"
}
},
{
"upsert": true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ spec:
mountPath: /update.sh
subPath: update.sh
command: ['/bin/sh','-c']
args: ['cp /update.sh /update.run.sh && chmod +x /update.run.sh &&./update.run.sh']
args: ['cp /update.sh /update.run.sh && chmod +x /update.run.sh && ./update.run.sh']
resources:
limits:
cpu: "3000m"
Expand Down
3 changes: 0 additions & 3 deletions apps/server/src/apps/server.app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { Mail, MailService } from '@infra/mail';
/* eslint-disable no-console */
import { MikroORM } from '@mikro-orm/core';
import { AccountService } from '@modules/account';
import { AccountValidationService } from '@src/modules/account/domain/services/account.validation.service';
import { AccountUc } from '@src/modules/account/api/account.uc';
import { SystemRule } from '@modules/authorization/domain/rules';

Check warning on line 8 in apps/server/src/apps/server.app.ts

View workflow job for this annotation

GitHub Actions / nest_lint

'@modules/authorization/domain/rules' import is restricted from being used by a pattern. Do not deep import from a module

Check warning on line 8 in apps/server/src/apps/server.app.ts

View workflow job for this annotation

GitHub Actions / nest_lint

'@modules/authorization/domain/rules' import is restricted from being used by a pattern. Do not deep import from a module
import { CollaborativeStorageUc } from '@modules/collaborative-storage/uc/collaborative-storage.uc';

Check warning on line 9 in apps/server/src/apps/server.app.ts

View workflow job for this annotation

GitHub Actions / nest_lint

'@modules/collaborative-storage/uc/collaborative-storage.uc' import is restricted from being used by a pattern. Do not deep import from a module

Check warning on line 9 in apps/server/src/apps/server.app.ts

View workflow job for this annotation

GitHub Actions / nest_lint

'@modules/collaborative-storage/uc/collaborative-storage.uc' import is restricted from being used by a pattern. Do not deep import from a module
Expand Down Expand Up @@ -83,8 +82,6 @@ async function bootstrap() {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
feathersExpress.services['nest-account-service'] = nestApp.get(AccountService);
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
feathersExpress.services['nest-account-validation-service'] = nestApp.get(AccountValidationService);
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
feathersExpress.services['nest-account-uc'] = nestApp.get(AccountUc);
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
feathersExpress.services['nest-collaborative-storage-uc'] = nestApp.get(CollaborativeStorageUc);
Expand Down
5 changes: 4 additions & 1 deletion apps/server/src/core/logger/types/logging.types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/**
* Information inside this file should be placed in shared, type are copied to it.
*/
export type LogMessage = {
message: string;
data?: LogMessageData;
Expand All @@ -7,7 +10,7 @@ export type ErrorLogMessage = {
error?: Error;
type: string; // TODO: use enum
stack?: string;
data?: { [key: string]: string | number | boolean | undefined };
data?: LogMessageDataObject;
};

export type ValidationErrorLogMessage = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Inject, Injectable } from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { RawAxiosRequestConfig } from 'axios';
import cookie from 'cookie';
import { Request } from 'express';
import { ExtractJwt, JwtFromRequestFunction } from 'passport-jwt';
import { extractJwtFromHeader } from '@shared/common';
import { AuthorizationApi, AuthorizationBodyParams } from './authorization-api-client';
import { AuthorizationErrorLoggableException, AuthorizationForbiddenLoggableException } from './error';

Expand All @@ -19,9 +18,9 @@ export class AuthorizationClientAdapter {
}

public async hasPermissionsByReference(params: AuthorizationBodyParams): Promise<boolean> {
const options = this.createOptionParams(params);

try {
const options = this.createOptionParams();

const response = await this.authorizationApi.authorizationReferenceControllerAuthorizeByReference(
params,
options
Expand All @@ -34,34 +33,20 @@ export class AuthorizationClientAdapter {
}
}

private createOptionParams(params: AuthorizationBodyParams): RawAxiosRequestConfig<any> {
const jwt = this.getJWT(params);
private createOptionParams(): RawAxiosRequestConfig<any> {
const jwt = this.getJwt();
const options: RawAxiosRequestConfig<any> = { headers: { authorization: `Bearer ${jwt}` } };

return options;
}

private getJWT(params: AuthorizationBodyParams): string {
const getJWT = ExtractJwt.fromExtractors([ExtractJwt.fromAuthHeaderAsBearerToken(), this.fromCookie('jwt')]);
const jwt = getJWT(this.request) || this.request.headers.authorization;
private getJwt(): string {
const jwt = extractJwtFromHeader(this.request) || this.request.headers.authorization;

if (!jwt) {
const error = new Error('Authentication is required.');
throw new AuthorizationErrorLoggableException(error, params);
throw new Error('Authentication is required.');
}

return jwt;
}

private fromCookie(name: string): JwtFromRequestFunction {
return (request: Request) => {
let token: string | null = null;
const cookies = cookie.parse(request.headers.cookie || '');
if (cookies && cookies[name]) {
token = cookies[name];
}

return token;
};
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { OauthConfigDto } from '@modules/system/service/dto';
import type { OauthConfig } from '@modules/system';

export abstract class IdentityManagementOauthService {
/**
* Returns the oauth config of the IDM.
* @returns the oauth config of the IDM.
* @throws an error if the IDM oauth config is not available.
*/
abstract getOauthConfig(): Promise<OauthConfigDto>;
abstract getOauthConfig(): Promise<OauthConfig>;

/**
* Checks if the IDM oauth config is available.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { HttpModule } from '@nestjs/axios';
import { Module } from '@nestjs/common';
import { LoggerModule } from '@src/core/logger';
import { EncryptionModule } from '../encryption';
import { IdentityManagementOauthService } from './identity-management-oauth.service';
import { IdentityManagementService } from './identity-management.service';
Expand All @@ -9,7 +10,7 @@ import { KeycloakIdentityManagementOauthService } from './keycloak/service/keycl
import { KeycloakIdentityManagementService } from './keycloak/service/keycloak-identity-management.service';

@Module({
imports: [KeycloakModule, KeycloakAdministrationModule, HttpModule, EncryptionModule],
imports: [KeycloakModule, KeycloakAdministrationModule, HttpModule, EncryptionModule, LoggerModule],
providers: [
{ provide: IdentityManagementService, useClass: KeycloakIdentityManagementService },
{ provide: IdentityManagementOauthService, useClass: KeycloakIdentityManagementOauthService },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
export const KeycloakSettings = Symbol('KeycloakSettings');

export interface IKeycloakSettings {
baseUrl: string;
internalBaseUrl: string;
externalBaseUrl: string;
realmName: string;
clientId: string;
credentials: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { IKeycloakSettings } from './interface/keycloak-settings.interface';
export default class KeycloakAdministration {
static keycloakSettings = (Configuration.get('FEATURE_IDENTITY_MANAGEMENT_ENABLED') as boolean)
? ({
baseUrl: Configuration.get('IDENTITY_MANAGEMENT__URI') as string,
internalBaseUrl: Configuration.get('IDENTITY_MANAGEMENT__INTERNAL_URI') as string,
externalBaseUrl: Configuration.get('IDENTITY_MANAGEMENT__EXTERNAL_URI') as string,
realmName: Configuration.get('IDENTITY_MANAGEMENT__TENANT') as string,
clientId: Configuration.get('IDENTITY_MANAGEMENT__CLIENTID') as string,
credentials: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ describe('KeycloakAdministrationService', () => {

const getSettings = (): IKeycloakSettings => {
return {
baseUrl: 'http://localhost:8080',
internalBaseUrl: 'http://localhost:8080',
externalBaseUrl: 'http://localhost:8080',
realmName: 'master',
clientId: 'client',
credentials: {
Expand Down Expand Up @@ -110,7 +111,7 @@ describe('KeycloakAdministrationService', () => {
describe('getWellKnownUrl', () => {
it('should return the well known URL', () => {
const wellKnownUrl = service.getWellKnownUrl();
expect(wellKnownUrl).toContain(settings.baseUrl);
expect(wellKnownUrl).toContain(settings.internalBaseUrl);
expect(wellKnownUrl).toContain(settings.realmName);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export class KeycloakAdministrationService {
@Inject(KeycloakSettings) private readonly kcSettings: IKeycloakSettings
) {
this.kcAdminClient.setConfig({
baseUrl: kcSettings.baseUrl,
baseUrl: kcSettings.internalBaseUrl,
realmName: kcSettings.realmName,
});
}
Expand All @@ -33,7 +33,7 @@ export class KeycloakAdministrationService {
}

public getWellKnownUrl(): string {
return `${this.kcSettings.baseUrl}/realms/${this.kcSettings.realmName}/.well-known/openid-configuration`;
return `${this.kcSettings.externalBaseUrl}/realms/${this.kcSettings.realmName}/.well-known/openid-configuration`;
}

public getAdminUser(): string {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { createMock } from '@golevelup/ts-jest';
import { DefaultEncryptionService, SymetricKeyEncryptionService } from '@infra/encryption';
import IdentityProviderRepresentation from '@keycloak/keycloak-admin-client/lib/defs/identityProviderRepresentation';
import { ObjectId } from '@mikro-orm/mongodb';
import { OidcConfig } from '@modules/system/domain';
import { Test, TestingModule } from '@nestjs/testing';
import { DefaultEncryptionService, SymetricKeyEncryptionService } from '@infra/encryption';
import { OidcConfigDto } from '@modules/system/service';
import { OidcIdentityProviderMapper } from './identity-provider.mapper';

describe('OidcIdentityProviderMapper', () => {
Expand Down Expand Up @@ -32,8 +31,7 @@ describe('OidcIdentityProviderMapper', () => {

describe('mapToKeycloakIdentityProvider', () => {
const brokerFlowAlias = 'flow';
const internalRepresentation: OidcConfigDto = {
parentSystemId: new ObjectId(0).toString(),
const internalRepresentation: OidcConfig = {
clientId: 'clientId',
clientSecret: 'clientSecret',
idpHint: 'alias',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { DefaultEncryptionService, EncryptionService } from '@infra/encryption';
import IdentityProviderRepresentation from '@keycloak/keycloak-admin-client/lib/defs/identityProviderRepresentation';
import { OidcConfigDto } from '@modules/system/service';
import type { OidcConfig } from '@modules/system';
import { Inject } from '@nestjs/common';

export class OidcIdentityProviderMapper {
constructor(@Inject(DefaultEncryptionService) private readonly defaultEncryptionService: EncryptionService) {}

public mapToKeycloakIdentityProvider(oidcConfig: OidcConfigDto, flowAlias: string): IdentityProviderRepresentation {
public mapToKeycloakIdentityProvider(oidcConfig: OidcConfig, flowAlias: string): IdentityProviderRepresentation {
return {
providerId: 'oidc',
alias: oidcConfig.idpHint,
Expand Down
Loading

0 comments on commit b9fa3c0

Please sign in to comment.