fix(core): Improve saml endpoints and audit events (#6107)

* update saml endpoints and login audit

* fix(core): Skip auth for controllers/routes that don't use the `Authorized` decorator

* fix linting

* lint fix

* add tests and fix endpoint permission

* add hook test

---------

Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <aditya@netroy.in>
This commit is contained in:
Michael Auerswald
2023-04-28 18:11:33 +02:00
committed by GitHub
parent 701105edcf
commit c0b1cddc91
7 changed files with 300 additions and 5 deletions

View File

@@ -1,6 +1,6 @@
import express from 'express';
import { getInstanceBaseUrl } from '@/UserManagement/UserManagementHelper';
import { Authorized, Get, Post, RestController } from '@/decorators';
import { Authorized, Get, NoAuthRequired, Post, RestController } from '@/decorators';
import { SamlUrls } from '../constants';
import {
samlLicensedAndEnabledMiddleware,
@@ -23,11 +23,14 @@ import {
} from '../serviceProvider.ee';
import { getSamlConnectionTestSuccessView } from '../views/samlConnectionTestSuccess';
import { getSamlConnectionTestFailedView } from '../views/samlConnectionTestFailed';
import Container from 'typedi';
import { InternalHooks } from '@/InternalHooks';
@RestController('/sso/saml')
export class SamlController {
constructor(private samlService: SamlService) {}
@NoAuthRequired()
@Get(SamlUrls.metadata)
async getServiceProviderMetadata(req: express.Request, res: express.Response) {
return res
@@ -39,7 +42,7 @@ export class SamlController {
* GET /sso/saml/config
* Return SAML config
*/
@Authorized(['global', 'owner'])
@Authorized('any')
@Get(SamlUrls.config, { middlewares: [samlLicensedMiddleware] })
async configGet() {
const prefs = this.samlService.samlPreferences;
@@ -87,6 +90,7 @@ export class SamlController {
* GET /sso/saml/acs
* Assertion Consumer Service endpoint
*/
@NoAuthRequired()
@Get(SamlUrls.acs, { middlewares: [samlLicensedMiddleware] })
async acsGet(req: SamlConfiguration.AcsRequest, res: express.Response) {
return this.acsHandler(req, res, 'redirect');
@@ -96,6 +100,7 @@ export class SamlController {
* POST /sso/saml/acs
* Assertion Consumer Service endpoint
*/
@NoAuthRequired()
@Post(SamlUrls.acs, { middlewares: [samlLicensedMiddleware] })
async acsPost(req: SamlConfiguration.AcsRequest, res: express.Response) {
return this.acsHandler(req, res, 'post');
@@ -122,6 +127,10 @@ export class SamlController {
}
}
if (loginResult.authenticatedUser) {
void Container.get(InternalHooks).onUserLoginSuccess({
user: loginResult.authenticatedUser,
authenticationMethod: 'saml',
});
// Only sign in user if SAML is enabled, otherwise treat as test connection
if (isSamlLicensedAndEnabled()) {
await issueCookie(res, loginResult.authenticatedUser);
@@ -134,11 +143,19 @@ export class SamlController {
return res.status(202).send(loginResult.attributes);
}
}
void Container.get(InternalHooks).onUserLoginFailed({
user: loginResult.attributes.email ?? 'unknown',
authenticationMethod: 'saml',
});
throw new AuthError('SAML Authentication failed');
} catch (error) {
if (isConnectionTestRequest(req)) {
return res.send(getSamlConnectionTestFailedView((error as Error).message));
}
void Container.get(InternalHooks).onUserLoginFailed({
user: 'unknown',
authenticationMethod: 'saml',
});
throw new AuthError('SAML Authentication failed: ' + (error as Error).message);
}
}
@@ -148,6 +165,7 @@ export class SamlController {
* Access URL for implementing SP-init SSO
* This endpoint is available if SAML is licensed and enabled
*/
@NoAuthRequired()
@Get(SamlUrls.initSSO, { middlewares: [samlLicensedAndEnabledMiddleware] })
async initSsoGet(req: express.Request, res: express.Response) {
return this.handleInitSSO(res);