feat(core): Add SAML login setup (#5515)

* initial commit with sample data

* basic saml setup

* cleanup console logs

* limit saml endpoints through middleware

* basic login and token issue

* saml service and cleanup

* refactor and create user

* get/set saml prefs

* fix authentication issue

* redirect to user details

* merge fix

* add generated password to saml user

* update user from attributes where possible

* refactor and fix creating new user

* rename saml prefs key

* minor cleanup

* Update packages/cli/src/config/schema.ts

Co-authored-by: Omar Ajoue <krynble@gmail.com>

* Update packages/cli/src/config/schema.ts

Co-authored-by: Omar Ajoue <krynble@gmail.com>

* Update packages/cli/src/controllers/auth.controller.ts

Co-authored-by: Omar Ajoue <krynble@gmail.com>

* code review changes

* fix default saml enabled

* remove console.log

* fix isSamlLicensed

---------

Co-authored-by: Omar Ajoue <krynble@gmail.com>
This commit is contained in:
Michael Auerswald
2023-02-24 20:37:19 +01:00
committed by GitHub
parent d09ca875ec
commit 40a934bbb4
24 changed files with 745 additions and 21 deletions

View File

@@ -19,6 +19,8 @@ import type {
} from '@/Interfaces';
import { handleEmailLogin, handleLdapLogin } from '@/auth';
import type { PostHogClient } from '@/posthog';
import { isSamlCurrentAuthenticationMethod } from '../sso/ssoHelpers';
import { SamlUrls } from '../sso/saml/constants';
@RestController()
export class AuthController {
@@ -57,14 +59,34 @@ export class AuthController {
* Authless endpoint.
*/
@Post('/login')
async login(req: LoginRequest, res: Response): Promise<PublicUser> {
async login(req: LoginRequest, res: Response): Promise<PublicUser | undefined> {
const { email, password } = req.body;
if (!email) throw new Error('Email is required to log in');
if (!password) throw new Error('Password is required to log in');
const user =
(await handleLdapLogin(email, password)) ?? (await handleEmailLogin(email, password));
let user: User | undefined;
if (isSamlCurrentAuthenticationMethod()) {
// attempt to fetch user data with the credentials, but don't log in yet
const preliminaryUser = await handleEmailLogin(email, password);
// if the user is an owner, continue with the login
if (preliminaryUser?.globalRole?.name === 'owner') {
user = preliminaryUser;
} else {
// TODO:SAML - uncomment this block when we have a way to redirect users to the SSO flow
// if (doRedirectUsersFromLoginToSsoFlow()) {
res.redirect(SamlUrls.restInitSSO);
return;
// return withFeatureFlags(this.postHog, sanitizeUser(preliminaryUser));
// } else {
// throw new AuthError(
// 'Login with username and password is disabled due to SAML being the default authentication method. Please use SAML to log in.',
// );
// }
}
} else {
user = (await handleLdapLogin(email, password)) ?? (await handleEmailLogin(email, password));
}
if (user) {
await issueCookie(res, user);
return withFeatureFlags(this.postHog, sanitizeUser(user));