diff options
author | Lars Wirzenius <liw@liw.fi> | 2018-07-31 15:46:45 +0300 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2018-07-31 15:54:02 +0300 |
commit | 527d2855f37bed4fe8ab82a0d0c340258a19adc7 (patch) | |
tree | e2f87ebabda349f568405c27f26761c1b313be18 | |
parent | 9ead1c5c91e3c75274aa56dca2b17036cdc45573 (diff) | |
download | qvisqve-527d2855f37bed4fe8ab82a0d0c340258a19adc7.tar.gz |
Add: actually check user credentials
-rw-r--r-- | qvisqve/api.py | 7 | ||||
-rw-r--r-- | qvisqve/auth_router.py | 19 | ||||
-rw-r--r-- | yarns/300-end-user-auth.yarn | 4 | ||||
-rw-r--r-- | yarns/lib.py | 13 |
4 files changed, 40 insertions, 3 deletions
diff --git a/qvisqve/api.py b/qvisqve/api.py index 6c3fe34..dfe69d0 100644 --- a/qvisqve/api.py +++ b/qvisqve/api.py @@ -31,7 +31,7 @@ class API: qvisqve.TokenRouter( self._create_token_generator(), self._get_clients()), qvisqve.LoginRouter(), - qvisqve.AuthRouter(self._get_applications()), + qvisqve.AuthRouter(self._get_applications(), self._get_users()), ] routes = [] @@ -65,3 +65,8 @@ class API: rs = self._create_resource_store() am = qvisqve.ApplicationManager(rs) return am + + def _get_users(self): + rs = self._create_resource_store() + um = qvisqve.UserManager(rs) + return um diff --git a/qvisqve/auth_router.py b/qvisqve/auth_router.py index 717e46f..378a995 100644 --- a/qvisqve/auth_router.py +++ b/qvisqve/auth_router.py @@ -17,14 +17,18 @@ import urllib.parse +import bottle + + import qvisqve class AuthRouter(qvisqve.Router): - def __init__(self, apps): + def __init__(self, apps, users): super().__init__() self._apps = apps + self._users = users def get_routes(self): return [ @@ -44,6 +48,12 @@ class AuthRouter(qvisqve.Router): if content_type != 'application/x-www-form-urlencoded': return qvisqve.bad_request_response('Wrong content type') + params = self._get_form_params(body) + username = self._get_param(params, 'username') + password = self._get_param(params, 'password') + if not self._users.is_valid_secret(username, password): + return qvisqve.unauthorized_response('Access denied') + # TODO: # - perform actual auth # - create and store auth code @@ -59,3 +69,10 @@ class AuthRouter(qvisqve.Router): qvisqve.log.log('xxx', msg_text='Returning redirect', url=url) return qvisqve.found_response('Redirect to callback url', url) + + def _get_param(self, params, name): + return params[name][0] + + def _get_form_params(self, body): + body = body.decode('UTF-8') + return urllib.parse.parse_qs(body) diff --git a/yarns/300-end-user-auth.yarn b/yarns/300-end-user-auth.yarn index f2a74f2..46d6236 100644 --- a/yarns/300-end-user-auth.yarn +++ b/yarns/300-end-user-auth.yarn @@ -26,6 +26,10 @@ User goes to the login URL and gets a login page. AND body has an HTML form with field password WHEN browser requests POST /auth, with form values + ... username=tomjon and password=wrong + THEN HTTP status code is 401 Unauthorized + + WHEN browser requests POST /auth, with form values ... username=tomjon and password=hunter2 THEN HTTP status code is 302 Found AND HTTP Location header is https://facade/callback?code=123 diff --git a/yarns/lib.py b/yarns/lib.py index 56707ba..7d83c08 100644 --- a/yarns/lib.py +++ b/yarns/lib.py @@ -181,9 +181,11 @@ def start_qvisqve(): os.mkdir(store) os.mkdir(os.path.join(store, 'client')) os.mkdir(os.path.join(store, 'application')) + os.mkdir(os.path.join(store, 'user')) + + sh = qvisqve_secrets.SecretHasher() if V['client_id'] and V['client_secret']: - sh = qvisqve_secrets.SecretHasher() client = { 'hashed_secret': sh.hash(V['client_secret']), 'allowed_scopes': V['allowed_scopes'], @@ -202,6 +204,15 @@ def start_qvisqve(): with open(filename, 'w') as f: yaml.safe_dump(spec, stream=f) + users = V['users'] + for name in users or []: + filename = os.path.join(store, 'user', name) + spec = { + 'hashed_secret': sh.hash(users[name]), + } + with open(filename, 'w') as f: + yaml.safe_dump(spec, stream=f) + config = { 'gunicorn': 'background', 'gunicorn-log': 'gunicorn.log', |