From c576634923e869c4beee7fc99d01c0cead474a95 Mon Sep 17 00:00:00 2001 From: Bartek Fabiszewski Date: Fri, 20 Dec 2019 09:46:35 +0100 Subject: [PATCH] Add auth class --- js/src/auth.js | 94 ++++++++++++++++++++++++++++ js/test/auth.test.js | 142 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 236 insertions(+) create mode 100644 js/src/auth.js create mode 100644 js/test/auth.test.js diff --git a/js/src/auth.js b/js/src/auth.js new file mode 100644 index 0000000..905af34 --- /dev/null +++ b/js/src/auth.js @@ -0,0 +1,94 @@ +/* + * μlogger + * + * Copyright(C) 2019 Bartek Fabiszewski (www.fabiszewski.net) + * + * This is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +import uUser from './user.js'; + +export default class uAuth { + + constructor() { + /** @type {boolean} */ + this._isAdmin = false; + /** @type {boolean} */ + this._isAuthenticated = false; + /** @type {?uUser} */ + this._user = null; + } + + /** + * @param {uUser} user + */ + set user(user) { + if (user) { + this._user = user; + this._isAuthenticated = true; + } else { + this._user = null; + this._isAuthenticated = false; + this._isAdmin = false; + } + } + + /** + * @param {boolean} isAdmin + */ + set isAdmin(isAdmin) { + if (!this._user) { + throw new Error('No authenticated user'); + } + this._isAdmin = isAdmin; + } + + /** + * @return {boolean} + */ + get isAdmin() { + return this._isAdmin; + } + + /** + * @return {boolean} + */ + get isAuthenticated() { + return this._isAuthenticated; + } + + /** + * @return {?uUser} + */ + get user() { + return this._user; + } + + /** + * Load auth state from data object + * @param {Object} data + * @param {boolean} data.isAdmin + * @param {boolean} data.isAuthenticated + * @param {?number} data.userId + * @param {?string} data.userLogin + */ + load(data) { + if (data) { + if (data.isAuthenticated) { + this.user = new uUser(data.userId, data.userLogin); + this.isAdmin = data.isAdmin; + } + } + } +} diff --git a/js/test/auth.test.js b/js/test/auth.test.js new file mode 100644 index 0000000..3fa4969 --- /dev/null +++ b/js/test/auth.test.js @@ -0,0 +1,142 @@ +/* + * μlogger + * + * Copyright(C) 2019 Bartek Fabiszewski (www.fabiszewski.net) + * + * This is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +import uAuth from '../src/auth.js'; +import uUser from '../src/user.js'; + +describe('Auth tests', () => { + + let auth; + let user; + + beforeEach(() => { + auth = new uAuth(); + user = new uUser(1, 'testUser'); + }); + + it('should create instance', () => { + expect(auth.isAdmin).toBe(false); + expect(auth.isAuthenticated).toBe(false); + expect(auth.user).toBe(null); + }); + + it('should set authenticated user', () => { + // when + auth.user = user; + // then + expect(auth.user).toBe(user); + expect(auth.isAuthenticated).toBe(true); + expect(auth.isAdmin).toBe(false); + }); + + it('should unset authenticated user', () => { + // given + auth.user = user; + auth.isAdmin = true; + // when + auth.user = null; + // then + expect(auth.user).toBe(null); + expect(auth.isAuthenticated).toBe(false); + expect(auth.isAdmin).toBe(false); + }); + + it('should set user as admin', () => { + // given + auth.user = user; + // when + auth.isAdmin = true; + // then + expect(auth.user).toBe(user); + expect(auth.isAuthenticated).toBe(true); + expect(auth.isAdmin).toBe(true); + }); + + it('should throw error when setting admin when no user is defined', () => { + // given + auth.user = null; + // when + // then + expect(() => { auth.isAdmin = true; }).toThrowError('No authenticated user'); + expect(auth.user).toBe(null); + expect(auth.isAuthenticated).toBe(false); + expect(auth.isAdmin).toBe(false); + }); + + it('should initialize with loaded data', () => { + // given + auth.user = null; + const data = { + isAdmin: false, + isAuthenticated: true, + userId: 5, + userLogin: 'dataUser' + }; + // when + auth.load(data); + // then + expect(auth.user).toEqual(new uUser(data.userId, data.userLogin)); + expect(auth.isAuthenticated).toBe(true); + expect(auth.isAdmin).toBe(false); + }); + + it('should initialize with loaded data containing admin user', () => { + // given + auth.user = null; + const data = { + isAdmin: true, + isAuthenticated: true, + userId: 5, + userLogin: 'dataUser' + }; + // when + auth.load(data); + // then + expect(auth.user).toEqual(new uUser(data.userId, data.userLogin)); + expect(auth.isAuthenticated).toBe(true); + expect(auth.isAdmin).toBe(true); + }); + + it('should skip loaded data if isAuthenticated is not set', () => { + // given + auth.user = null; + const data = { + userId: 5, + userLogin: 'dataUser' + }; + // when + auth.load(data); + // then + expect(auth.user).toBe(null); + expect(auth.isAuthenticated).toBe(false); + expect(auth.isAdmin).toBe(false); + }); + + it('should skip loading if data is not set', () => { + // given + auth.user = null; + // when + auth.load(null); + // then + expect(auth.user).toBe(null); + expect(auth.isAuthenticated).toBe(false); + expect(auth.isAdmin).toBe(false); + }); + +});