mirror of https://github.com/portainer/portainer
100 lines
2.4 KiB
TypeScript
100 lines
2.4 KiB
TypeScript
import { Transition, TransitionService } from '@uirouter/angularjs';
|
|
|
|
import { IAuthenticationService } from './services/types';
|
|
|
|
export enum AccessHeaders {
|
|
Restricted = 'restricted',
|
|
Admin = 'admin',
|
|
EdgeAdmin = 'edge-admin',
|
|
}
|
|
|
|
type Authorizations = string[];
|
|
type Access =
|
|
| AccessHeaders.Restricted
|
|
| AccessHeaders.Admin
|
|
| AccessHeaders.EdgeAdmin
|
|
| Authorizations;
|
|
|
|
export function requiresAuthHook(transitionService: TransitionService) {
|
|
transitionService.onBefore({}, checkAuthorizations);
|
|
}
|
|
|
|
// exported for tests
|
|
export async function checkAuthorizations(transition: Transition) {
|
|
const authService: IAuthenticationService = transition
|
|
.injector()
|
|
.get('Authentication');
|
|
const stateTo = transition.to();
|
|
const $state = transition.router.stateService;
|
|
|
|
const { access } = stateTo.data || {};
|
|
if (!isAccess(access)) {
|
|
return undefined;
|
|
}
|
|
|
|
const isLoggedIn = await authService.init();
|
|
|
|
if (!isLoggedIn) {
|
|
// eslint-disable-next-line no-console
|
|
console.info(
|
|
'User is not authenticated, redirecting to login, access:',
|
|
access
|
|
);
|
|
return $state.target('portainer.logout');
|
|
}
|
|
|
|
if (typeof access === 'string') {
|
|
if (access === 'restricted') {
|
|
return undefined;
|
|
}
|
|
|
|
if (access === 'admin') {
|
|
if (authService.isPureAdmin()) {
|
|
return undefined;
|
|
}
|
|
|
|
// eslint-disable-next-line no-console
|
|
console.info(
|
|
'User is not an admin, redirecting to home, access:',
|
|
access
|
|
);
|
|
return $state.target('portainer.home');
|
|
}
|
|
|
|
if (access === 'edge-admin') {
|
|
if (authService.isAdmin(true)) {
|
|
return undefined;
|
|
}
|
|
|
|
// eslint-disable-next-line no-console
|
|
console.info(
|
|
'User is not an edge admin, redirecting to home, access:',
|
|
access
|
|
);
|
|
return $state.target('portainer.home');
|
|
}
|
|
}
|
|
|
|
if (access.length > 0 && !authService.hasAuthorizations(access)) {
|
|
// eslint-disable-next-line no-console
|
|
console.info(
|
|
'User does not have the required authorizations, redirecting to home'
|
|
);
|
|
return $state.target('portainer.home');
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
|
|
function isAccess(access: unknown): access is Access {
|
|
if (!access || (typeof access !== 'string' && !Array.isArray(access))) {
|
|
return false;
|
|
}
|
|
|
|
if (Array.isArray(access)) {
|
|
return access.every((a) => typeof a === 'string');
|
|
}
|
|
|
|
return ['restricted', 'admin', 'edge-admin'].includes(access);
|
|
}
|