fix: fix broken user auth for web API app

This commit is contained in:
Lance Edgar 2024-08-19 09:23:31 -05:00
parent b7955a5871
commit 0fb3c0f3d2
3 changed files with 16 additions and 50 deletions

View file

@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2023 Lance Edgar
# Copyright © 2010-2024 Lance Edgar
#
# This file is part of Rattail.
#
@ -24,8 +24,6 @@
Tailbone Web API - Auth Views
"""
from rattail.db.auth import set_user_password
from cornice import Service
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
exists. Note that this also resets the user's session timer.
"""
data = {'ok': True}
data = {'ok': True, 'permissions': []}
if self.request.user:
data['user'] = self.get_user_info(self.request.user)
data['permissions'] = list(self.request.tailbone_cached_permissions)
data['permissions'] = list(self.request.user_permissions)
# background color may be set per-request, by some apps
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"}
# 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 {
'ok': True,
'user': self.get_user_info(self.request.user),

View file

@ -25,19 +25,15 @@ Application Entry Point
"""
import os
import warnings
import sqlalchemy as sa
from sqlalchemy.orm import sessionmaker, scoped_session
from wuttjamaican.util import parse_list
from rattail.config import make_config
from rattail.exceptions import ConfigurationError
from rattail.db.types import GPCType
from pyramid.config import Configurator
from pyramid.authentication import SessionAuthenticationPolicy
from zope.sqlalchemy import register
import tailbone.db

View file

@ -27,20 +27,18 @@ Authentication & Authorization
import logging
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 wuttaweb.auth import WuttaSecurityPolicy
from tailbone.db import Session
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
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()
user.record_event(app.enum.USER_EVENT_LOGIN)
headers = remember(request, user.uuid)
if timeout is NOTSET:
if timeout is UNSPECIFIED:
timeout = session_timeout_for_user(config, user)
log.debug("setting session timeout for '{}' to {}".format(user.username, timeout))
set_session_timeout(request, timeout)
@ -94,12 +92,12 @@ def set_session_timeout(request, timeout):
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.session_helper = SessionAuthenticationHelper()
self.identity_cache = RequestLocalCache(self.load_identity)
def load_identity(self, request):
config = request.registry.settings.get('rattail_config')
@ -115,7 +113,7 @@ class TailboneSecurityPolicy:
if match:
token = match.group(1)
auth = app.get_auth_handler()
user = auth.authenticate_user_token(Session(), token)
user = auth.authenticate_user_token(self.db_session, token)
if not user:
@ -126,36 +124,10 @@ class TailboneSecurityPolicy:
# fetch user object from db
model = app.model
user = Session.get(model.User, uuid)
user = self.db_session.get(model.User, uuid)
if not user:
return
# this user is responsible for data changes in current request
Session().set_continuum_user(user)
self.db_session.set_continuum_user(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)