User permissions added with test.

This commit is contained in:
Nicholas Staples
2016-02-19 16:38:04 +00:00
parent f761afa76e
commit 32e37d89fb
6 changed files with 79 additions and 2 deletions

View File

@@ -169,7 +169,7 @@ def register_errorhandlers(application):
error_code = getattr(error, 'code', 500)
resp = make_response(render_template("error/{0}.html".format(error_code)), error_code)
return useful_headers_after_request(resp)
for errcode in [401, 404, 500]:
for errcode in [401, 404, 403, 500]:
application.errorhandler(errcode)(render_error)

View File

@@ -6,6 +6,8 @@ from app.main.dao import templates_dao
from notifications_python_client.errors import HTTPError
from app import job_api_client
from app.utils import user_has_permissions
@main.route("/services/<service_id>/dashboard")
@login_required

View File

@@ -96,6 +96,7 @@ class User(UserMixin):
self._email_address = fields.get('email_address')
self._mobile_number = fields.get('mobile_number')
self._password_changed_at = fields.get('password_changed_at')
self._permissions = set(fields.get('permissions')) if fields.get('permission') is not None else set()
self._failed_login_count = 0
self._state = fields.get('state')
self.max_failed_login_count = max_failed_login_count
@@ -154,6 +155,25 @@ class User(UserMixin):
def state(self, state):
self._state = state
@property
def permissions(self):
return self._permissions
@permissions.setter
def permissions(self, permissions):
if permissions is None:
permissions = set()
self._permissions = set(permissions)
def add_permissions(self, permissions):
self._permissions.update(permissions)
def remove_permissions(self, permissions):
self._permissions -= permissions
def has_permissions(self, permissions):
return self._permissions > set(permissions)
@property
def failed_login_count(self):
return self._failed_login_count
@@ -172,7 +192,8 @@ class User(UserMixin):
"mobile_number": self.mobile_number,
"password_changed_at": self.password_changed_at,
"state": self.state,
"failed_login_count": self.failed_login_count}
"failed_login_count": self.failed_login_count,
"permissions": [x for x in self._permissions]}
if getattr(self, '_password', None):
dct['password'] = self._password
return dct

View File

@@ -0,0 +1,14 @@
{% extends "withoutnav_template.html" %}
{% block page_title %}Page not found{% endblock %}
{% block maincolumn_content %}
<div class="grid-row">
<div class="column-two-thirds">
<h1 class="heading-large">
403
</h1>
<p>
You do not have permission to view this page.
</p>
</div>
</div>
{% endblock %}

View File

@@ -1,3 +1,7 @@
from functools import wraps
from flask import abort
class BrowsableItem(object):
"""
Maps for the template browse-list.
@@ -68,3 +72,16 @@ def format_phone_number(number):
if len(number) < 9:
raise InvalidPhoneError('Not enough digits')
return '+447{}{}{}'.format(*re.findall('...', number))
def user_has_permissions(*permissions):
def wrap(func):
@wraps(func)
def wrap_func(*args, **kwargs):
# We are making the assumption that the user is logged in.
from flask_login import current_user
if set(permissions) > set(current_user.permissions):
abort(403)
return func(*args, **kwargs)
return wrap_func
return wrap