API keys hooked up and working. All tests passing.

This commit is contained in:
Nicholas Staples
2016-02-29 14:57:07 +00:00
parent 96e7239064
commit 48943527ec
11 changed files with 83 additions and 31 deletions

View File

@@ -17,6 +17,7 @@ from app.notify_client.api_key_api_client import ApiKeyApiClient
from app.notify_client.user_api_client import UserApiClient
from app.notify_client.job_api_client import JobApiClient
from app.notify_client.status_api_client import StatusApiClient
from app.notify_client.permission_api_client import PermissionApiClient
from app.its_dangerous_session import ItsdangerousSessionInterface
from app.asset_fingerprinter import AssetFingerprinter
from app.utils import validate_phone_number, InvalidPhoneError
@@ -33,6 +34,7 @@ api_key_api_client = ApiKeyApiClient()
job_api_client = JobApiClient()
status_api_client = StatusApiClient()
asset_fingerprinter = AssetFingerprinter()
permission_api_client = PermissionApiClient()
def create_app(config_name, config_overrides=None):
@@ -49,6 +51,7 @@ def create_app(config_name, config_overrides=None):
api_key_api_client.init_app(application)
job_api_client.init_app(application)
status_api_client.init_app(application)
permission_api_client.init_app(application)
login_manager.init_app(application)
login_manager.login_view = 'main.sign_in'

View File

@@ -3,6 +3,7 @@ from flask_login import login_required
from app.main import main
from app.main.forms import CreateKeyForm
from app import api_key_api_client
from app.utils import user_has_permissions
@main.route("/services/<service_id>/documentation")
@@ -13,6 +14,7 @@ def documentation(service_id):
@main.route("/services/<service_id>/api-keys")
@login_required
@user_has_permissions('manage_api_keys')
def api_keys(service_id):
return render_template(
'views/api-keys.html',
@@ -23,6 +25,7 @@ def api_keys(service_id):
@main.route("/services/<service_id>/api-keys/create", methods=['GET', 'POST'])
@login_required
@user_has_permissions('manage_api_keys')
def create_api_key(service_id):
key_names = [
key['name'] for key in api_key_api_client.get_api_keys(service_id=service_id)['apiKeys']
@@ -41,6 +44,7 @@ def create_api_key(service_id):
@main.route("/services/<service_id>/api-keys/revoke/<int:key_id>", methods=['GET', 'POST'])
@login_required
@user_has_permissions('manage_api_keys')
def revoke_api_key(service_id, key_id):
key_name = api_key_api_client.get_api_keys(service_id=service_id, key_id=key_id)['apiKeys'][0]['name']
if request.method == 'GET':

View File

@@ -23,6 +23,8 @@ def service_dashboard(service_id):
try:
service = get_service_by_id(service_id)
session['service_name'] = service['data']['name']
print(service['data']['id'])
session['service_id'] = service['data']['id']
except HTTPError as e:
if e.status_code == 404:
abort(404)

View File

@@ -44,10 +44,6 @@ def choose_sms_template(service_id):
abort(404)
else:
raise e
print("="*80)
print(jobs)
print(len(jobs))
print(bool(len(jobs)))
return render_template(
'views/choose-sms-template.html',
templates=[

View File

@@ -0,0 +1,25 @@
import uuid
from notifications_python_client.base import BaseAPIClient
class PermissionApiClient(BaseAPIClient):
def __init__(self, base_url=None, client_id=None, secret=None):
super(self.__class__, self).__init__(base_url=base_url or 'base_url',
client_id=client_id or 'client_id',
secret=secret or 'secret')
def init_app(self, app):
self.base_url = app.config['API_HOST_NAME']
self.client_id = app.config['ADMIN_CLIENT_USER_NAME']
self.secret = app.config['ADMIN_CLIENT_SECRET']
def delete_permission(self, permission_id):
return self.delete(url='/permission/{}'.format(permission_id))['data']
def create_permission(self, permission, user_id, service_id):
return self.post(
url='/permission',
data={'permission': permission,
'user': user_id,
'service': service_id})['data']

View File

@@ -89,7 +89,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._permissions = fields.get('permissions')
self._failed_login_count = 0
self._state = fields.get('state')
self.max_failed_login_count = max_failed_login_count
@@ -154,18 +154,12 @@ class User(UserMixin):
@permissions.setter
def permissions(self, permissions):
if permissions is None:
permissions = set()
self._permissions = set(permissions)
raise AttributeError("Read only property")
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)
def has_permissions(self, service_id, permissions):
if service_id in self._permissions:
return set(self._permissions[service_id]) > set(permissions)
return False
@property
def failed_login_count(self):

View File

@@ -2,16 +2,22 @@
<h2 class="navigation-service-name">
<a href="{{ url_for('.service_dashboard', service_id=service_id) }}">{{ session.get('service_name', 'Service') }}</a>
</h2>
{% if current_user.has_permissions(session.get('service_id', ''), ['send_messages']) %}
<ul>
<li><a href="{{ url_for('.choose_sms_template', service_id=service_id) }}">Send text messages</a></li>
<li><a href="{{ url_for('.send_email', service_id=service_id) }}">Send emails</a></li>
</ul>
{% endif %}
{% if current_user.has_permissions(session.get('service_id', ''), ['manage_service']) %}
<ul>
<li><a href="{{ url_for('.manage_users', service_id=service_id) }}">Manage team</a></li>
<li><a href="{{ url_for('.service_settings', service_id=service_id) }}">Manage settings</a></li>
</ul>
{% endif %}
{% if current_user.has_permissions(session.get('service_id', ''), ['manage_api_keys']) %}
<ul>
<li><a href="{{ url_for('.api_keys', service_id=service_id) }}">API keys</a></li>
<li><a href="{{ url_for('.documentation', service_id=service_id) }}">Developer documentation</a></li>
</ul>
{% endif %}
</nav>

View File

@@ -1,5 +1,5 @@
from functools import wraps
from flask import abort
from flask import (abort, session)
class BrowsableItem(object):
@@ -80,8 +80,10 @@ def user_has_permissions(*permissions):
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):
service_id = session.get('service_id', '')
if current_user and current_user.has_permissions(service_id, permissions):
return func(*args, **kwargs)
else:
abort(403)
return func(*args, **kwargs)
return wrap_func
return wrap