summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2018-07-31 15:46:45 +0300
committerLars Wirzenius <liw@liw.fi>2018-07-31 15:54:02 +0300
commit527d2855f37bed4fe8ab82a0d0c340258a19adc7 (patch)
treee2f87ebabda349f568405c27f26761c1b313be18
parent9ead1c5c91e3c75274aa56dca2b17036cdc45573 (diff)
downloadqvisqve-527d2855f37bed4fe8ab82a0d0c340258a19adc7.tar.gz
Add: actually check user credentials
-rw-r--r--qvisqve/api.py7
-rw-r--r--qvisqve/auth_router.py19
-rw-r--r--yarns/300-end-user-auth.yarn4
-rw-r--r--yarns/lib.py13
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',