front/auth: implement privileges + top nav auth
This commit is contained in:
parent
28c90a25f3
commit
d8f11d87e5
5 changed files with 68 additions and 12 deletions
|
@ -2,11 +2,14 @@
|
|||
|
||||
const request = require('superagent');
|
||||
const config = require('./config.js');
|
||||
const EventListener = require('./event_listener.js');
|
||||
|
||||
class Api {
|
||||
constructor() {
|
||||
this.user = null;
|
||||
this.userName = null;
|
||||
this.userPassword = null;
|
||||
this.authenticated = new EventListener();
|
||||
}
|
||||
|
||||
get(url) {
|
||||
|
@ -36,9 +39,25 @@ class Api {
|
|||
});
|
||||
}
|
||||
|
||||
hasPrivilege() {
|
||||
/* TODO: implement */
|
||||
return true;
|
||||
hasPrivilege(lookup) {
|
||||
let minViableRank = null;
|
||||
for (let privilege of Object.keys(config.privileges)) {
|
||||
if (!privilege.startsWith(lookup)) {
|
||||
continue;
|
||||
}
|
||||
const rankName = config.privileges[privilege];
|
||||
const rankIndex = config.service.userRanks.indexOf(rankName);
|
||||
if (minViableRank === null || rankIndex < minViableRank) {
|
||||
minViableRank = rankIndex;
|
||||
}
|
||||
}
|
||||
if (minViableRank === null) {
|
||||
console.error('Bad privilege name: ' + lookup);
|
||||
}
|
||||
let myRank = this.user !== null ?
|
||||
config.service.userRanks.indexOf(this.user.accessRank) :
|
||||
0;
|
||||
return myRank >= minViableRank;
|
||||
}
|
||||
|
||||
login(userName, userPassword) {
|
||||
|
@ -46,10 +65,14 @@ class Api {
|
|||
this.userName = userName;
|
||||
this.userPassword = userPassword;
|
||||
this.get('/user/' + userName)
|
||||
.then(() => { resolve(); })
|
||||
.catch(response => {
|
||||
.then(response => {
|
||||
this.user = response.user;
|
||||
resolve();
|
||||
this.authenticated.fire();
|
||||
}).catch(response => {
|
||||
reject(response.description);
|
||||
this.logout();
|
||||
this.authenticated.fire();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -57,6 +80,7 @@ class Api {
|
|||
logout() {
|
||||
this.userName = null;
|
||||
this.userPassword = null;
|
||||
this.authenticated.fire();
|
||||
}
|
||||
|
||||
isLoggedIn() {
|
||||
|
|
|
@ -36,7 +36,7 @@ class AuthController {
|
|||
options);
|
||||
resolve();
|
||||
page('/');
|
||||
/* TODO: notify top navigation */
|
||||
/* TODO: notify about login */
|
||||
}).catch(errorMessage => { reject(errorMessage); });
|
||||
});
|
||||
}});
|
||||
|
@ -46,7 +46,7 @@ class AuthController {
|
|||
this.api.logout();
|
||||
cookies.remove('auth');
|
||||
page('/');
|
||||
/* TODO: notify top navigation */
|
||||
/* TODO: notify about logout */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ class TopNavigationController {
|
|||
constructor(topNavigationView, api) {
|
||||
this.api = api;
|
||||
this.topNavigationView = topNavigationView;
|
||||
this.activeItem = null;
|
||||
|
||||
this.items = {
|
||||
'home': new NavigationItem('Home', '/'),
|
||||
|
@ -27,9 +28,15 @@ class TopNavigationController {
|
|||
'help': new NavigationItem('Help', '/help'),
|
||||
};
|
||||
|
||||
this.updateVisibility();
|
||||
this.api.authenticated.listen(() => {
|
||||
this.updateVisibility();
|
||||
this.topNavigationView.render(this.items, this.activeItem);
|
||||
this.topNavigationView.activate(this.activeItem);
|
||||
});
|
||||
|
||||
this.topNavigationView.render(this.items);
|
||||
this.updateVisibility();
|
||||
this.topNavigationView.render(this.items, this.activeItem);
|
||||
this.topNavigationView.activate(this.activeItem);
|
||||
}
|
||||
|
||||
updateVisibility() {
|
||||
|
@ -40,7 +47,7 @@ class TopNavigationController {
|
|||
if (!this.api.hasPrivilege('posts:list')) {
|
||||
this.items.posts.available = false;
|
||||
}
|
||||
if (!this.api.hasPrivilege('posts:upload')) {
|
||||
if (!this.api.hasPrivilege('posts:create')) {
|
||||
this.items.upload.available = false;
|
||||
}
|
||||
if (!this.api.hasPrivilege('comments:list')) {
|
||||
|
@ -62,7 +69,8 @@ class TopNavigationController {
|
|||
}
|
||||
|
||||
activate(itemName) {
|
||||
this.topNavigationView.activate(itemName);
|
||||
this.activeItem = itemName;
|
||||
this.topNavigationView.activate(this.activeItem);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
24
static/js/event_listener.js
Normal file
24
static/js/event_listener.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
class EventListener {
|
||||
constructor() {
|
||||
this.listeners = [];
|
||||
}
|
||||
|
||||
listen(callback) {
|
||||
this.listeners.push(callback);
|
||||
}
|
||||
|
||||
unlisten(callback) {
|
||||
const index = this.listeners.indexOf(callback);
|
||||
if (index !== -1) {
|
||||
this.listeners.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
fire(data) {
|
||||
for (let listener of this.listeners) {
|
||||
listener(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = EventListener;
|
|
@ -73,7 +73,7 @@ class UserDetailApi(object):
|
|||
self._auth_service.verify_privilege(request.context.user, 'users:view')
|
||||
session = request.context.session
|
||||
user = self._user_service.get_by_name(session, user_name)
|
||||
request.context.result = _serialize_user(user)
|
||||
request.context.result = {'user': _serialize_user(user)}
|
||||
|
||||
def on_put(self, request, response, user_name):
|
||||
''' Updates an existing user. '''
|
||||
|
|
Loading…
Reference in a new issue