fix: fix broken user auth for web API app
This commit is contained in:
parent
b7955a5871
commit
0fb3c0f3d2
|
@ -2,7 +2,7 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
#
|
#
|
||||||
# Rattail -- Retail Software Framework
|
# Rattail -- Retail Software Framework
|
||||||
# Copyright © 2010-2023 Lance Edgar
|
# Copyright © 2010-2024 Lance Edgar
|
||||||
#
|
#
|
||||||
# This file is part of Rattail.
|
# This file is part of Rattail.
|
||||||
#
|
#
|
||||||
|
@ -24,8 +24,6 @@
|
||||||
Tailbone Web API - Auth Views
|
Tailbone Web API - Auth Views
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from rattail.db.auth import set_user_password
|
|
||||||
|
|
||||||
from cornice import Service
|
from cornice import Service
|
||||||
|
|
||||||
from tailbone.api import APIView, api
|
from tailbone.api import APIView, api
|
||||||
|
@ -42,11 +40,10 @@ class AuthenticationView(APIView):
|
||||||
This will establish a server-side web session for the user if none
|
This will establish a server-side web session for the user if none
|
||||||
exists. Note that this also resets the user's session timer.
|
exists. Note that this also resets the user's session timer.
|
||||||
"""
|
"""
|
||||||
data = {'ok': True}
|
data = {'ok': True, 'permissions': []}
|
||||||
if self.request.user:
|
if self.request.user:
|
||||||
data['user'] = self.get_user_info(self.request.user)
|
data['user'] = self.get_user_info(self.request.user)
|
||||||
|
data['permissions'] = list(self.request.user_permissions)
|
||||||
data['permissions'] = list(self.request.tailbone_cached_permissions)
|
|
||||||
|
|
||||||
# background color may be set per-request, by some apps
|
# background color may be set per-request, by some apps
|
||||||
if hasattr(self.request, 'background_color') and self.request.background_color:
|
if hasattr(self.request, 'background_color') and self.request.background_color:
|
||||||
|
@ -176,7 +173,8 @@ class AuthenticationView(APIView):
|
||||||
return {'error': "The current/old password you provided is incorrect"}
|
return {'error': "The current/old password you provided is incorrect"}
|
||||||
|
|
||||||
# okay then, set new password
|
# okay then, set new password
|
||||||
set_user_password(self.request.user, data['new_password'])
|
auth = self.app.get_auth_handler()
|
||||||
|
auth.set_user_password(self.request.user, data['new_password'])
|
||||||
return {
|
return {
|
||||||
'ok': True,
|
'ok': True,
|
||||||
'user': self.get_user_info(self.request.user),
|
'user': self.get_user_info(self.request.user),
|
||||||
|
|
|
@ -25,19 +25,15 @@ Application Entry Point
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import warnings
|
|
||||||
|
|
||||||
import sqlalchemy as sa
|
|
||||||
from sqlalchemy.orm import sessionmaker, scoped_session
|
from sqlalchemy.orm import sessionmaker, scoped_session
|
||||||
|
|
||||||
from wuttjamaican.util import parse_list
|
from wuttjamaican.util import parse_list
|
||||||
|
|
||||||
from rattail.config import make_config
|
from rattail.config import make_config
|
||||||
from rattail.exceptions import ConfigurationError
|
from rattail.exceptions import ConfigurationError
|
||||||
from rattail.db.types import GPCType
|
|
||||||
|
|
||||||
from pyramid.config import Configurator
|
from pyramid.config import Configurator
|
||||||
from pyramid.authentication import SessionAuthenticationPolicy
|
|
||||||
from zope.sqlalchemy import register
|
from zope.sqlalchemy import register
|
||||||
|
|
||||||
import tailbone.db
|
import tailbone.db
|
||||||
|
|
|
@ -27,20 +27,18 @@ Authentication & Authorization
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from rattail.util import NOTSET
|
from wuttjamaican.util import UNSPECIFIED
|
||||||
|
|
||||||
from zope.interface import implementer
|
|
||||||
from pyramid.authentication import SessionAuthenticationHelper
|
|
||||||
from pyramid.request import RequestLocalCache
|
|
||||||
from pyramid.security import remember, forget
|
from pyramid.security import remember, forget
|
||||||
|
|
||||||
|
from wuttaweb.auth import WuttaSecurityPolicy
|
||||||
from tailbone.db import Session
|
from tailbone.db import Session
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def login_user(request, user, timeout=NOTSET):
|
def login_user(request, user, timeout=UNSPECIFIED):
|
||||||
"""
|
"""
|
||||||
Perform the steps necessary to login the given user. Note that this
|
Perform the steps necessary to login the given user. Note that this
|
||||||
returns a ``headers`` dict which you should pass to the redirect.
|
returns a ``headers`` dict which you should pass to the redirect.
|
||||||
|
@ -49,7 +47,7 @@ def login_user(request, user, timeout=NOTSET):
|
||||||
app = config.get_app()
|
app = config.get_app()
|
||||||
user.record_event(app.enum.USER_EVENT_LOGIN)
|
user.record_event(app.enum.USER_EVENT_LOGIN)
|
||||||
headers = remember(request, user.uuid)
|
headers = remember(request, user.uuid)
|
||||||
if timeout is NOTSET:
|
if timeout is UNSPECIFIED:
|
||||||
timeout = session_timeout_for_user(config, user)
|
timeout = session_timeout_for_user(config, user)
|
||||||
log.debug("setting session timeout for '{}' to {}".format(user.username, timeout))
|
log.debug("setting session timeout for '{}' to {}".format(user.username, timeout))
|
||||||
set_session_timeout(request, timeout)
|
set_session_timeout(request, timeout)
|
||||||
|
@ -94,12 +92,12 @@ def set_session_timeout(request, timeout):
|
||||||
request.session['_timeout'] = timeout or None
|
request.session['_timeout'] = timeout or None
|
||||||
|
|
||||||
|
|
||||||
class TailboneSecurityPolicy:
|
class TailboneSecurityPolicy(WuttaSecurityPolicy):
|
||||||
|
|
||||||
def __init__(self, api_mode=False):
|
def __init__(self, db_session=None, api_mode=False, **kwargs):
|
||||||
|
kwargs['db_session'] = db_session or Session()
|
||||||
|
super().__init__(**kwargs)
|
||||||
self.api_mode = api_mode
|
self.api_mode = api_mode
|
||||||
self.session_helper = SessionAuthenticationHelper()
|
|
||||||
self.identity_cache = RequestLocalCache(self.load_identity)
|
|
||||||
|
|
||||||
def load_identity(self, request):
|
def load_identity(self, request):
|
||||||
config = request.registry.settings.get('rattail_config')
|
config = request.registry.settings.get('rattail_config')
|
||||||
|
@ -115,7 +113,7 @@ class TailboneSecurityPolicy:
|
||||||
if match:
|
if match:
|
||||||
token = match.group(1)
|
token = match.group(1)
|
||||||
auth = app.get_auth_handler()
|
auth = app.get_auth_handler()
|
||||||
user = auth.authenticate_user_token(Session(), token)
|
user = auth.authenticate_user_token(self.db_session, token)
|
||||||
|
|
||||||
if not user:
|
if not user:
|
||||||
|
|
||||||
|
@ -126,36 +124,10 @@ class TailboneSecurityPolicy:
|
||||||
|
|
||||||
# fetch user object from db
|
# fetch user object from db
|
||||||
model = app.model
|
model = app.model
|
||||||
user = Session.get(model.User, uuid)
|
user = self.db_session.get(model.User, uuid)
|
||||||
if not user:
|
if not user:
|
||||||
return
|
return
|
||||||
|
|
||||||
# this user is responsible for data changes in current request
|
# this user is responsible for data changes in current request
|
||||||
Session().set_continuum_user(user)
|
self.db_session.set_continuum_user(user)
|
||||||
return user
|
return user
|
||||||
|
|
||||||
def identity(self, request):
|
|
||||||
return self.identity_cache.get_or_create(request)
|
|
||||||
|
|
||||||
def authenticated_userid(self, request):
|
|
||||||
user = self.identity(request)
|
|
||||||
if user is not None:
|
|
||||||
return user.uuid
|
|
||||||
|
|
||||||
def remember(self, request, userid, **kw):
|
|
||||||
return self.session_helper.remember(request, userid, **kw)
|
|
||||||
|
|
||||||
def forget(self, request, **kw):
|
|
||||||
return self.session_helper.forget(request, **kw)
|
|
||||||
|
|
||||||
def permits(self, request, context, permission):
|
|
||||||
# nb. root user can do anything
|
|
||||||
if request.is_root:
|
|
||||||
return True
|
|
||||||
|
|
||||||
config = request.registry.settings.get('rattail_config')
|
|
||||||
app = config.get_app()
|
|
||||||
auth = app.get_auth_handler()
|
|
||||||
|
|
||||||
user = self.identity(request)
|
|
||||||
return auth.has_permission(Session(), user, permission)
|
|
||||||
|
|
Loading…
Reference in a new issue