cls._task_post("/api/pool", data)
@classmethod
- def login(cls, username, password):
+ def login(cls, username, password, set_cookies=False):
if cls._loggedin:
cls.logout()
- cls._post('/api/auth', {'username': username, 'password': password})
+ cls._post('/api/auth', {'username': username,
+ 'password': password}, set_cookies=set_cookies)
cls._assertEq(cls._resp.status_code, 201)
cls._token = cls.jsonBody()['token']
cls._loggedin = True
@classmethod
- def logout(cls):
+ def logout(cls, set_cookies=False):
if cls._loggedin:
- cls._post('/api/auth/logout')
+ cls._post('/api/auth/logout', set_cookies=set_cookies)
cls._assertEq(cls._resp.status_code, 200)
cls._token = None
cls._loggedin = False
def tearDownClass(cls):
super(DashboardTestCase, cls).tearDownClass()
- # pylint: disable=inconsistent-return-statements, too-many-arguments
+ # pylint: disable=inconsistent-return-statements, too-many-arguments, too-many-branches
@classmethod
- def _request(cls, url, method, data=None, params=None, version=DEFAULT_VERSION):
+ def _request(cls, url, method, data=None, params=None, version=DEFAULT_VERSION,
+ set_cookies=False):
url = "{}{}".format(cls._base_uri, url)
log.info("Request %s to %s", method, url)
headers = {}
+ cookies = {}
if cls._token:
- headers['Authorization'] = "Bearer {}".format(cls._token)
-
+ if set_cookies:
+ cookies['token'] = cls._token
+ else:
+ headers['Authorization'] = "Bearer {}".format(cls._token)
if version is None:
headers['Accept'] = 'application/json'
else:
headers['Accept'] = 'application/vnd.ceph.api.v{}+json'.format(version)
- if method == 'GET':
- cls._resp = cls._session.get(url, params=params, verify=False,
- headers=headers)
- elif method == 'POST':
- cls._resp = cls._session.post(url, json=data, params=params,
- verify=False, headers=headers)
- elif method == 'DELETE':
- cls._resp = cls._session.delete(url, json=data, params=params,
- verify=False, headers=headers)
- elif method == 'PUT':
- cls._resp = cls._session.put(url, json=data, params=params,
- verify=False, headers=headers)
+
+ if set_cookies:
+ if method == 'GET':
+ cls._resp = cls._session.get(url, params=params, verify=False,
+ headers=headers, cookies=cookies)
+ elif method == 'POST':
+ cls._resp = cls._session.post(url, json=data, params=params,
+ verify=False, headers=headers, cookies=cookies)
+ elif method == 'DELETE':
+ cls._resp = cls._session.delete(url, json=data, params=params,
+ verify=False, headers=headers, cookies=cookies)
+ elif method == 'PUT':
+ cls._resp = cls._session.put(url, json=data, params=params,
+ verify=False, headers=headers, cookies=cookies)
+ else:
+ assert False
else:
- assert False
+ if method == 'GET':
+ cls._resp = cls._session.get(url, params=params, verify=False,
+ headers=headers)
+ elif method == 'POST':
+ cls._resp = cls._session.post(url, json=data, params=params,
+ verify=False, headers=headers)
+ elif method == 'DELETE':
+ cls._resp = cls._session.delete(url, json=data, params=params,
+ verify=False, headers=headers)
+ elif method == 'PUT':
+ cls._resp = cls._session.put(url, json=data, params=params,
+ verify=False, headers=headers)
+ else:
+ assert False
try:
if not cls._resp.ok:
# Output response for easier debugging.
raise ex
@classmethod
- def _get(cls, url, params=None, version=DEFAULT_VERSION):
- return cls._request(url, 'GET', params=params, version=version)
+ def _get(cls, url, params=None, version=DEFAULT_VERSION, set_cookies=False):
+ return cls._request(url, 'GET', params=params, version=version, set_cookies=set_cookies)
@classmethod
def _view_cache_get(cls, url, retries=5):
return res
@classmethod
- def _post(cls, url, data=None, params=None, version=DEFAULT_VERSION):
- cls._request(url, 'POST', data, params, version=version)
+ def _post(cls, url, data=None, params=None, version=DEFAULT_VERSION, set_cookies=False):
+ cls._request(url, 'POST', data, params, version=version, set_cookies=set_cookies)
@classmethod
- def _delete(cls, url, data=None, params=None, version=DEFAULT_VERSION):
- cls._request(url, 'DELETE', data, params, version=version)
+ def _delete(cls, url, data=None, params=None, version=DEFAULT_VERSION, set_cookies=False):
+ cls._request(url, 'DELETE', data, params, version=version, set_cookies=set_cookies)
@classmethod
- def _put(cls, url, data=None, params=None, version=DEFAULT_VERSION):
- cls._request(url, 'PUT', data, params, version=version)
+ def _put(cls, url, data=None, params=None, version=DEFAULT_VERSION, set_cookies=False):
+ cls._request(url, 'PUT', data, params, version=version, set_cookies=set_cookies)
@classmethod
def _assertEq(cls, v1, v2):
# pylint: disable=too-many-arguments
@classmethod
- def _task_request(cls, method, url, data, timeout, version=DEFAULT_VERSION):
- res = cls._request(url, method, data, version=version)
+ def _task_request(cls, method, url, data, timeout, version=DEFAULT_VERSION, set_cookies=False):
+ res = cls._request(url, method, data, version=version, set_cookies=set_cookies)
cls._assertIn(cls._resp.status_code, [200, 201, 202, 204, 400, 403, 404])
if cls._resp.status_code == 403:
return res_task['exception']
@classmethod
- def _task_post(cls, url, data=None, timeout=60, version=DEFAULT_VERSION):
- return cls._task_request('POST', url, data, timeout, version=version)
+ def _task_post(cls, url, data=None, timeout=60, version=DEFAULT_VERSION, set_cookies=False):
+ return cls._task_request('POST', url, data, timeout, version=version,
+ set_cookies=set_cookies)
@classmethod
- def _task_delete(cls, url, timeout=60, version=DEFAULT_VERSION):
- return cls._task_request('DELETE', url, None, timeout, version=version)
+ def _task_delete(cls, url, timeout=60, version=DEFAULT_VERSION, set_cookies=False):
+ return cls._task_request('DELETE', url, None, timeout, version=version,
+ set_cookies=set_cookies)
@classmethod
- def _task_put(cls, url, data=None, timeout=60, version=DEFAULT_VERSION):
- return cls._task_request('PUT', url, data, timeout, version=version)
+ def _task_put(cls, url, data=None, timeout=60, version=DEFAULT_VERSION, set_cookies=False):
+ return cls._task_request('PUT', url, data, timeout, version=version,
+ set_cookies=set_cookies)
@classmethod
def cookies(cls):
self.create_user('admin2', '', ['administrator'], force_password=True)
def test_a_set_login_credentials(self):
+ # test with Authorization header
self.create_user('admin2', 'admin2', ['administrator'])
self._post("/api/auth", {'username': 'admin2', 'password': 'admin2'})
self.assertStatus(201)
self._validate_jwt_token(data['token'], "admin2", data['permissions'])
self.delete_user('admin2')
+ # test with Cookies set
+ self.create_user('admin2', 'admin2', ['administrator'])
+ self._post("/api/auth", {'username': 'admin2', 'password': 'admin2'}, set_cookies=True)
+ self.assertStatus(201)
+ data = self.jsonBody()
+ self._validate_jwt_token(data['token'], "admin2", data['permissions'])
+ self.delete_user('admin2')
+
def test_login_valid(self):
+ # test with Authorization header
self._post("/api/auth", {'username': 'admin', 'password': 'admin'})
self.assertStatus(201)
data = self.jsonBody()
}, allow_unknown=False))
self._validate_jwt_token(data['token'], "admin", data['permissions'])
+ # test with Cookies set
+ self._post("/api/auth", {'username': 'admin', 'password': 'admin'}, set_cookies=True)
+ self.assertStatus(201)
+ data = self.jsonBody()
+ self.assertSchema(data, JObj(sub_elems={
+ 'token': JLeaf(str),
+ 'username': JLeaf(str),
+ 'permissions': JObj(sub_elems={}, allow_unknown=True),
+ 'sso': JLeaf(bool),
+ 'pwdExpirationDate': JLeaf(int, none=True),
+ 'pwdUpdateRequired': JLeaf(bool)
+ }, allow_unknown=False))
+ self._validate_jwt_token(data['token'], "admin", data['permissions'])
+
def test_login_invalid(self):
+ # test with Authorization header
self._post("/api/auth", {'username': 'admin', 'password': 'inval'})
self.assertStatus(400)
self.assertJsonBody({
})
def test_lockout_user(self):
+ # test with Authorization header
self._ceph_cmd(['dashboard', 'set-account-lockout-attempts', '3'])
for _ in range(3):
self._post("/api/auth", {'username': 'admin', 'password': 'inval'})
}, allow_unknown=False))
self._validate_jwt_token(data['token'], "admin", data['permissions'])
+ # test with Cookies set
+ self._ceph_cmd(['dashboard', 'set-account-lockout-attempts', '3'])
+ for _ in range(3):
+ self._post("/api/auth", {'username': 'admin', 'password': 'inval'}, set_cookies=True)
+ self._post("/api/auth", {'username': 'admin', 'password': 'admin'}, set_cookies=True)
+ self.assertStatus(400)
+ self.assertJsonBody({
+ "component": "auth",
+ "code": "invalid_credentials",
+ "detail": "Invalid credentials"
+ })
+ self._ceph_cmd(['dashboard', 'ac-user-enable', 'admin'])
+ self._post("/api/auth", {'username': 'admin', 'password': 'admin'}, set_cookies=True)
+ self.assertStatus(201)
+ data = self.jsonBody()
+ self.assertSchema(data, JObj(sub_elems={
+ 'token': JLeaf(str),
+ 'username': JLeaf(str),
+ 'permissions': JObj(sub_elems={}, allow_unknown=True),
+ 'sso': JLeaf(bool),
+ 'pwdExpirationDate': JLeaf(int, none=True),
+ 'pwdUpdateRequired': JLeaf(bool)
+ }, allow_unknown=False))
+ self._validate_jwt_token(data['token'], "admin", data['permissions'])
+
def test_logout(self):
+ # test with Authorization header
self._post("/api/auth", {'username': 'admin', 'password': 'admin'})
self.assertStatus(201)
data = self.jsonBody()
self.assertStatus(401)
self.set_jwt_token(None)
+ # test with Cookies set
+ self._post("/api/auth", {'username': 'admin', 'password': 'admin'}, set_cookies=True)
+ self.assertStatus(201)
+ data = self.jsonBody()
+ self._validate_jwt_token(data['token'], "admin", data['permissions'])
+ self.set_jwt_token(data['token'])
+ self._post("/api/auth/logout", set_cookies=True)
+ self.assertStatus(200)
+ self.assertJsonBody({
+ "redirect_url": "#/login"
+ })
+ self._get("/api/host", set_cookies=True)
+ self.assertStatus(401)
+ self.set_jwt_token(None)
+
def test_token_ttl(self):
+ # test with Authorization header
self._ceph_cmd(['dashboard', 'set-jwt-token-ttl', '5'])
self._post("/api/auth", {'username': 'admin', 'password': 'admin'})
self.assertStatus(201)
self._ceph_cmd(['dashboard', 'set-jwt-token-ttl', '28800'])
self.set_jwt_token(None)
+ # test with Cookies set
+ self._ceph_cmd(['dashboard', 'set-jwt-token-ttl', '5'])
+ self._post("/api/auth", {'username': 'admin', 'password': 'admin'}, set_cookies=True)
+ self.assertStatus(201)
+ self.set_jwt_token(self.jsonBody()['token'])
+ self._get("/api/host", set_cookies=True)
+ self.assertStatus(200)
+ time.sleep(6)
+ self._get("/api/host", set_cookies=True)
+ self.assertStatus(401)
+ self._ceph_cmd(['dashboard', 'set-jwt-token-ttl', '28800'])
+ self.set_jwt_token(None)
+
def test_remove_from_blocklist(self):
+ # test with Authorization header
self._ceph_cmd(['dashboard', 'set-jwt-token-ttl', '5'])
self._post("/api/auth", {'username': 'admin', 'password': 'admin'})
self.assertStatus(201)
self._post("/api/auth/logout")
self.assertStatus(200)
+ # test with Cookies set
+ self._ceph_cmd(['dashboard', 'set-jwt-token-ttl', '5'])
+ self._post("/api/auth", {'username': 'admin', 'password': 'admin'}, set_cookies=True)
+ self.assertStatus(201)
+ self.set_jwt_token(self.jsonBody()['token'])
+ # the following call adds the token to the blocklist
+ self._post("/api/auth/logout", set_cookies=True)
+ self.assertStatus(200)
+ self._get("/api/host", set_cookies=True)
+ self.assertStatus(401)
+ time.sleep(6)
+ self._ceph_cmd(['dashboard', 'set-jwt-token-ttl', '28800'])
+ self.set_jwt_token(None)
+ self._post("/api/auth", {'username': 'admin', 'password': 'admin'}, set_cookies=True)
+ self.assertStatus(201)
+ self.set_jwt_token(self.jsonBody()['token'])
+ # the following call removes expired tokens from the blocklist
+ self._post("/api/auth/logout", set_cookies=True)
+ self.assertStatus(200)
+
def test_unauthorized(self):
+ # test with Authorization header
self._get("/api/host")
self.assertStatus(401)
+ # test with Cookies set
+ self._get("/api/host", set_cookies=True)
+ self.assertStatus(401)
+
def test_invalidate_token_by_admin(self):
+ # test with Authorization header
self._get("/api/host")
self.assertStatus(401)
self.create_user('user', 'user', ['read-only'])
self.assertStatus(200)
self.delete_user("user")
+ # test with Cookies set
+ self._get("/api/host", set_cookies=True)
+ self.assertStatus(401)
+ self.create_user('user', 'user', ['read-only'])
+ time.sleep(1)
+ self._post("/api/auth", {'username': 'user', 'password': 'user'}, set_cookies=True)
+ self.assertStatus(201)
+ self.set_jwt_token(self.jsonBody()['token'])
+ self._get("/api/host", set_cookies=True)
+ self.assertStatus(200)
+ time.sleep(1)
+ self._ceph_cmd_with_secret(['dashboard', 'ac-user-set-password', '--force-password',
+ 'user'],
+ 'user2')
+ time.sleep(1)
+ self._get("/api/host", set_cookies=True)
+ self.assertStatus(401)
+ self.set_jwt_token(None)
+ self._post("/api/auth", {'username': 'user', 'password': 'user2'}, set_cookies=True)
+ self.assertStatus(201)
+ self.set_jwt_token(self.jsonBody()['token'])
+ self._get("/api/host", set_cookies=True)
+ self.assertStatus(200)
+ self.delete_user("user")
+
def test_check_token(self):
+ # test with Authorization header
self.login("admin", "admin")
self._post("/api/auth/check", {"token": self.jsonBody()["token"]})
self.assertStatus(200)
}, allow_unknown=False))
self.logout()
+ # test with Cookies set
+ self.login("admin", "admin", set_cookies=True)
+ self._post("/api/auth/check", {"token": self.jsonBody()["token"]}, set_cookies=True)
+ self.assertStatus(200)
+ data = self.jsonBody()
+ self.assertSchema(data, JObj(sub_elems={
+ "username": JLeaf(str),
+ "permissions": JObj(sub_elems={}, allow_unknown=True),
+ "sso": JLeaf(bool),
+ "pwdUpdateRequired": JLeaf(bool)
+ }, allow_unknown=False))
+ self.logout(set_cookies=True)
+
def test_check_wo_token(self):
+ # test with Authorization header
self.login("admin", "admin")
self._post("/api/auth/check", {"token": ""})
self.assertStatus(200)
"login_url": JLeaf(str)
}, allow_unknown=False))
self.logout()
+
+ # test with Cookies set
+ self.login("admin", "admin", set_cookies=True)
+ self._post("/api/auth/check", {"token": ""}, set_cookies=True)
+ self.assertStatus(200)
+ data = self.jsonBody()
+ self.assertSchema(data, JObj(sub_elems={
+ "login_url": JLeaf(str)
+ }, allow_unknown=False))
+ self.logout(set_cookies=True)
return func(*args, **kwargs)
return validate_args
return decorator
+
+
+def set_cookies(url_prefix, token):
+ cherrypy.response.cookie['token'] = token
+ if url_prefix == 'https':
+ cherrypy.response.cookie['token']['secure'] = True
+ cherrypy.response.cookie['token']['HttpOnly'] = True
+ cherrypy.response.cookie['token']['path'] = '/'
+ cherrypy.response.cookie['token']['SameSite'] = 'Strict'
# -*- coding: utf-8 -*-
from __future__ import absolute_import
+import http.cookies
import logging
-
-import cherrypy
+import sys
from .. import mgr
from ..exceptions import InvalidCredentialsError, UserDoesNotExist
from ..services.auth import AuthManager, JwtManager
from ..settings import Settings
-from . import ApiController, ControllerDoc, EndpointDoc, RESTController, allow_empty_body
+from . import ApiController, ControllerDoc, EndpointDoc, RESTController, \
+ allow_empty_body, set_cookies
+
+# Python 3.8 introduced `samesite` attribute:
+# https://docs.python.org/3/library/http.cookies.html#morsel-objects
+if sys.version_info < (3, 8):
+ http.cookies.Morsel._reserved["samesite"] = "SameSite" # type: ignore # pylint: disable=W0212
logger = logging.getLogger('controllers.auth')
pwd_update_required = user_data.get('pwdUpdateRequired', False)
if user_perms is not None:
+ url_prefix = 'https' if mgr.get_localized_module_option('ssl') else 'http'
+
logger.info('Login successful: %s', username)
mgr.ACCESS_CTRL_DB.reset_attempt(username)
mgr.ACCESS_CTRL_DB.save()
token = JwtManager.gen_token(username)
token = token.decode('utf-8')
- cherrypy.response.headers['Authorization'] = "Bearer: {}".format(token)
+ set_cookies(url_prefix, token)
return {
'token': token,
'username': username,
spec_url = "{}/docs/api.json".format(base)
auth_header = cherrypy.request.headers.get('authorization')
+ auth_cookie = cherrypy.request.cookie['token']
jwt_token = ""
- if auth_header is not None:
+ if auth_cookie is not None:
+ jwt_token = auth_cookie.value
+ elif auth_header is not None:
scheme, params = auth_header.split(' ', 1)
if scheme.lower() == 'bearer':
jwt_token = params
from ..exceptions import UserDoesNotExist
from ..services.auth import JwtManager
from ..tools import prepare_url_prefix
-from . import BaseController, Controller, Endpoint, allow_empty_body
+from . import BaseController, Controller, Endpoint, allow_empty_body, set_cookies
@Controller('/auth/saml2', secure=False)
token = JwtManager.gen_token(username)
JwtManager.set_user(JwtManager.decode_token(token))
token = token.decode('utf-8')
+ set_cookies(url_prefix, token)
raise cherrypy.HTTPRedirect("{}/#/login?access_token={}".format(url_prefix, token))
return {
# pylint: disable=unused-argument
Saml2._check_python_saml()
JwtManager.reset_user()
+ cherrypy.response.cookie['token'] = {'expires': 0, 'max-age': 0}
url_prefix = prepare_url_prefix(mgr.get_module_option('url_prefix', default=''))
raise cherrypy.HTTPRedirect("{}/#/login".format(url_prefix))
before(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
// Need pool for image testing
pools.navigateTo('create');
pools.create(poolName, 8, 'rbd');
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
images.navigateTo();
});
before(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
// Need image for trash testing
images.createImage(imageName, poolName, '1');
images.getFirstTableCell(imageName).should('exist');
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
iscsi.navigateTo();
});
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
mirroring.navigateTo();
});
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
configuration.navigateTo();
});
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
crushmap.navigateTo();
});
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
hosts.navigateTo();
});
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
});
describe('breadcrumb and tab tests', () => {
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
mgrmodules.navigateTo();
});
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
monitors.navigateTo();
});
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
osds.navigateTo();
});
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
filesystems.navigateTo();
});
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
hosts.navigateTo();
});
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
hosts.navigateTo();
});
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
inventory.navigateTo();
});
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
osds.navigateTo();
});
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
pools.navigateTo();
});
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
buckets.navigateTo();
});
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
daemons.navigateTo();
});
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
users.navigateTo();
});
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
dashboard.navigateTo();
});
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
language.navigateTo();
});
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
shared.navigateTo();
});
before(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
pools.navigateTo('create');
pools.create(poolName, 8);
pools.edit_pool_pg(poolName, 4, false);
after(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
pools.navigateTo();
pools.delete(poolName);
});
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
pools.navigateTo();
});
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
roleMgmt.navigateTo();
});
beforeEach(() => {
cy.login();
+ Cypress.Cookies.preserveOnce('token');
userMgmt.navigateTo();
});
const fillAuth = () => {
window.localStorage.setItem('dashboard_username', auth.username);
- window.localStorage.setItem('access_token', auth.token);
window.localStorage.setItem('dashboard_permissions', auth.permissions);
window.localStorage.setItem('user_pwd_expiration_date', auth.pwdExpirationDate);
window.localStorage.setItem('user_pwd_update_required', auth.pwdUpdateRequired);
"tslib": "^2.0.0"
}
},
- "@auth0/angular-jwt": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/@auth0/angular-jwt/-/angular-jwt-5.0.1.tgz",
- "integrity": "sha512-djllMh6rthPscEj5n5T9zF223q8t+sDqnUuAYTJjdKoHvMAzYwwi2yP67HbojqjODG4ZLFAcPtRuzGgp+r7nDQ==",
- "requires": {
- "tslib": "^2.0.0"
- }
- },
"@babel/code-frame": {
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
"@angular/platform-browser": "10.1.5",
"@angular/platform-browser-dynamic": "10.1.5",
"@angular/router": "10.1.5",
- "@auth0/angular-jwt": "5.0.1",
"@circlon/angular-tree-component": "10.0.0",
"@ng-bootstrap/ng-bootstrap": "7.0.0",
"@swimlane/ngx-datatable": "18.0.0",
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
-import { JwtModule } from '@auth0/angular-jwt';
import { ToastrModule } from 'ngx-toastr';
import { AppRoutingModule } from './app-routing.module';
import { JsErrorHandler } from './shared/services/js-error-handler.service';
import { SharedModule } from './shared/shared.module';
-export function jwtTokenGetter() {
- return localStorage.getItem('access_token');
-}
-
@NgModule({
declarations: [AppComponent],
imports: [
AppRoutingModule,
CoreModule,
SharedModule,
- CephModule,
- JwtModule.forRoot({
- config: {
- tokenGetter: jwtTokenGetter
- }
- })
+ CephModule
],
exports: [SharedModule],
providers: [
rbdService = new RbdService(null, null);
notificationService = new NotificationService(null, null, null);
authStorageService = new AuthStorageService();
- authStorageService.set('user', '', { 'rbd-image': ['create', 'read', 'update', 'delete'] });
+ authStorageService.set('user', { 'rbd-image': ['create', 'read', 'update', 'delete'] });
component = new RbdSnapshotListComponent(
authStorageService,
modalService,
} else {
this.authStorageService.set(
login.username,
- token,
login.permissions,
login.sso,
login.pwdExpirationDate
import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
import { Icons } from '~/app/shared/enum/icons.enum';
-import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
import { DocService } from '~/app/shared/services/doc.service';
import { ModalService } from '~/app/shared/services/modal.service';
import { AboutComponent } from '../about/about.component';
modalRef: NgbModalRef;
icons = Icons;
- constructor(
- private modalService: ModalService,
- private authStorageService: AuthStorageService,
- private docService: DocService
- ) {}
+ constructor(private modalService: ModalService, private docService: DocService) {}
ngOnInit() {
this.docService.subscribeOnce('dashboard', (url: string) => {
}
goToApiDocs() {
- const tokenInput = this.docsFormElement.nativeElement.children[0];
- tokenInput.value = this.authStorageService.getToken();
this.docsFormElement.nativeElement.submit();
}
}
it('should login and save the user', fakeAsync(() => {
const fakeCredentials = { username: 'foo', password: 'bar' };
- const fakeResponse = { username: 'foo', token: 'tokenbytes' };
+ const fakeResponse = { username: 'foo' };
service.login(fakeCredentials).subscribe();
const req = httpTesting.expectOne('api/auth');
expect(req.request.method).toBe('POST');
req.flush(fakeResponse);
tick();
expect(localStorage.getItem('dashboard_username')).toBe('foo');
- expect(localStorage.getItem('access_token')).toBe('tokenbytes');
}));
it('should logout and remove the user', () => {
tap((resp: LoginResponse) => {
this.authStorageService.set(
resp.username,
- resp.token,
resp.permissions,
resp.sso,
resp.pwdExpirationDate,
logout(callback: Function = null) {
return this.http.post('api/auth/logout', null).subscribe((resp: any) => {
- this.router.navigate(['/login'], { skipLocationChange: true });
this.authStorageService.remove();
+ this.router.navigate(['/login'], { skipLocationChange: true });
if (callback) {
callback();
}
export class LoginResponse {
username: string;
- token: string;
permissions: object;
pwdExpirationDate: number;
sso: boolean;
});
it('should be SSO', () => {
- service.set(username, '', {}, true);
+ service.set(username, {}, true);
expect(localStorage.getItem('sso')).toBe('true');
expect(service.isSSO()).toBe(true);
});
it('should not be SSO', () => {
- service.set(username, '');
+ service.set(username);
expect(localStorage.getItem('sso')).toBe('false');
expect(service.isSSO()).toBe(false);
});
set(
username: string,
- token: string,
permissions = {},
sso = false,
pwdExpirationDate: number = null,
pwdUpdateRequired: boolean = false
) {
localStorage.setItem('dashboard_username', username);
- localStorage.setItem('access_token', token);
localStorage.setItem('dashboard_permissions', JSON.stringify(new Permissions(permissions)));
localStorage.setItem('user_pwd_expiration_date', String(pwdExpirationDate));
localStorage.setItem('user_pwd_update_required', String(pwdUpdateRequired));
}
remove() {
- localStorage.removeItem('access_token');
localStorage.removeItem('dashboard_username');
localStorage.removeItem('user_pwd_expiration_data');
localStorage.removeItem('user_pwd_update_required');
}
- getToken(): string {
- return localStorage.getItem('access_token');
- }
-
isLoggedIn() {
return localStorage.getItem('dashboard_username') !== null;
}
@classmethod
def get_token_from_header(cls):
- auth_header = cherrypy.request.headers.get('authorization')
- if auth_header is not None:
- scheme, params = auth_header.split(' ', 1)
- if scheme.lower() == 'bearer':
- return params
- return None
+ auth_cookie_name = 'token'
+ try:
+ # use cookie
+ return cherrypy.request.cookie[auth_cookie_name].value
+ except KeyError:
+ try:
+ # fall-back: use Authorization header
+ auth_header = cherrypy.request.headers.get('authorization')
+ if auth_header is not None:
+ scheme, params = auth_header.split(' ', 1)
+ if scheme.lower() == 'bearer':
+ return params
+ except IndexError:
+ return None
@classmethod
def set_user(cls, username):