##// END OF EJS Templates
fix(caching): fixed problems with Cache query for users....
fix(caching): fixed problems with Cache query for users. The old way of querying caused the user get query to be always cached, and returning old results even in 2fa forms. The new limited query doesn't cache the user object resolving issues

File last commit:

r5360:4cbf1ad2 default
r5365:ae8a165b default
Show More
auth_rhodecode.py
228 lines | 8.9 KiB | text/x-python | PythonLexer
copyrights: updated for 2023
r5088 # Copyright (C) 2012-2023 RhodeCode GmbH
project: added all source files and assets
r1 #
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License, version 3
# (only), as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# This program is dual-licensed. If you wish to learn more about the
# RhodeCode Enterprise Edition, including its added features, Support services,
# and proprietary license terms, please see https://rhodecode.com/licenses/
"""
RhodeCode authentication plugin for built in internal auth
"""
import logging
auth: login/registration changes for upcomming new rules for login using external identities....
r3386 import colander
auth: remove usage of pylons translator
r2098 from rhodecode.translation import _
authentication: fixed for python3 migrations
r5057 from rhodecode.lib.utils2 import safe_bytes
project: added all source files and assets
r1 from rhodecode.model.db import User
auth: add scope and login restrictions to rhodecode plugin, and scope restriction to token plugin....
r3392 from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase
from rhodecode.authentication.base import (
RhodeCodeAuthPluginBase, hybrid_property, HTTP_TYPE, VCS_TYPE)
from rhodecode.authentication.routes import AuthnPluginResourceBase
project: added all source files and assets
r1
log = logging.getLogger(__name__)
auth-plugins: some code cleanup + added docs for main plugin.
r3253 def plugin_factory(plugin_id, *args, **kwargs):
project: added all source files and assets
r1 plugin = RhodeCodeAuthPlugin(plugin_id)
return plugin
class RhodecodeAuthnResource(AuthnPluginResourceBase):
pass
class RhodeCodeAuthPlugin(RhodeCodeAuthPluginBase):
authentication: use registerd UID for plugin definition for more consistent loading of auth plugins.
r3246 uid = 'rhodecode'
auth: add scope and login restrictions to rhodecode plugin, and scope restriction to token plugin....
r3392 AUTH_RESTRICTION_NONE = 'user_all'
AUTH_RESTRICTION_SUPER_ADMIN = 'user_super_admin'
AUTH_RESTRICTION_SCOPE_ALL = 'scope_all'
AUTH_RESTRICTION_SCOPE_HTTP = 'scope_http'
AUTH_RESTRICTION_SCOPE_VCS = 'scope_vcs'
project: added all source files and assets
r1
def includeme(self, config):
config.add_authn_plugin(self)
config.add_authn_resource(self.get_id(), RhodecodeAuthnResource(self))
config.add_view(
'rhodecode.authentication.views.AuthnPluginViewBase',
attr='settings_get',
templating: use .mako as extensions for template files.
r1282 renderer='rhodecode:templates/admin/auth/plugin_settings.mako',
project: added all source files and assets
r1 request_method='GET',
route_name='auth_home',
context=RhodecodeAuthnResource)
config.add_view(
'rhodecode.authentication.views.AuthnPluginViewBase',
attr='settings_post',
templating: use .mako as extensions for template files.
r1282 renderer='rhodecode:templates/admin/auth/plugin_settings.mako',
project: added all source files and assets
r1 request_method='POST',
route_name='auth_home',
context=RhodecodeAuthnResource)
auth: login/registration changes for upcomming new rules for login using external identities....
r3386 def get_settings_schema(self):
return RhodeCodeSettingsSchema()
auth: allow custom name for plugins if defined in the settings.
r4545 def get_display_name(self, load_from_settings=False):
auth-plugins: updated display names of plugins, and root resource.
r3234 return _('RhodeCode Internal')
project: added all source files and assets
r1
auth-plugins: some code cleanup + added docs for main plugin.
r3253 @classmethod
def docs(cls):
return "https://docs.rhodecode.com/RhodeCode-Enterprise/auth/auth.html"
project: added all source files and assets
r1 @hybrid_property
def name(self):
authentication: run modernize for python3
r5094 return "rhodecode"
project: added all source files and assets
r1
def user_activation_state(self):
users: make AuthUser propert a method, and allow override of params.
r1997 def_user_perms = User.get_default_user().AuthUser().permissions['global']
project: added all source files and assets
r1 return 'hg.register.auto_activate' in def_user_perms
def allows_authentication_from(
self, user, allows_non_existing_user=True,
allowed_auth_plugins=None, allowed_auth_sources=None):
"""
Custom method for this auth that doesn't accept non existing users.
We know that user exists in our database.
"""
allows_non_existing_user = False
authentication: run modernize for python3
r5094 return super().allows_authentication_from(
project: added all source files and assets
r1 user, allows_non_existing_user=allows_non_existing_user)
def auth(self, userobj, username, password, settings, **kwargs):
if not userobj:
logging: use lazy parameter evaluation in log calls.
r3061 log.debug('userobj was:%s skipping', userobj)
project: added all source files and assets
r1 return None
authentication: introduce login restriction option for builtin rhodecode plugin.
r3387
project: added all source files and assets
r1 if userobj.extern_type != self.name:
auth: add scope and login restrictions to rhodecode plugin, and scope restriction to token plugin....
r3392 log.warning("userobj:%s extern_type mismatch got:`%s` expected:`%s`",
userobj, userobj.extern_type, self.name)
return None
# check scope of auth
scope_restriction = settings.get('scope_restriction', '')
if scope_restriction == self.AUTH_RESTRICTION_SCOPE_HTTP \
and self.auth_type != HTTP_TYPE:
log.warning("userobj:%s tried scope type %s and scope restriction is set to %s",
userobj, self.auth_type, scope_restriction)
project: added all source files and assets
r1 return None
auth: add scope and login restrictions to rhodecode plugin, and scope restriction to token plugin....
r3392 if scope_restriction == self.AUTH_RESTRICTION_SCOPE_VCS \
and self.auth_type != VCS_TYPE:
log.warning("userobj:%s tried scope type %s and scope restriction is set to %s",
userobj, self.auth_type, scope_restriction)
return None
# check super-admin restriction
auth_restriction = settings.get('auth_restriction', '')
if auth_restriction == self.AUTH_RESTRICTION_SUPER_ADMIN \
and userobj.admin is False:
log.warning("userobj:%s is not super-admin and auth restriction is set to %s",
userobj, auth_restriction)
authentication: introduce login restriction option for builtin rhodecode plugin.
r3387 return None
project: added all source files and assets
r1 user_attrs = {
"username": userobj.username,
"firstname": userobj.firstname,
"lastname": userobj.lastname,
"groups": [],
authentication: introduce a group sync flag for plugins....
r2495 'user_group_sync': False,
project: added all source files and assets
r1 "email": userobj.email,
"admin": userobj.admin,
"active": userobj.active,
"active_from_extern": userobj.active,
"extern_name": userobj.user_id,
"extern_type": userobj.extern_type,
}
logging: use lazy parameter evaluation in log calls.
r3061 log.debug("User attributes:%s", user_attrs)
project: added all source files and assets
r1 if userobj.active:
from rhodecode.lib import auth
crypto_backend = auth.crypto_backend()
authentication: fixed for python3 migrations
r5057 password_encoded = safe_bytes(password)
project: added all source files and assets
r1 password_match, new_hash = crypto_backend.hash_check_with_upgrade(
auth-rhodecode: don't fail on bcrypt if user password is set to None....
r2153 password_encoded, userobj.password or '')
project: added all source files and assets
r1
if password_match and new_hash:
log.debug('user %s properly authenticated, but '
'requires hash change to bcrypt', userobj)
# if password match, and we use OLD deprecated hash,
# we should migrate this user hash password to the new hash
# we store the new returned by hash_check_with_upgrade function
user_attrs['_hash_migrate'] = new_hash
if userobj.username == User.DEFAULT_USER and userobj.active:
authentication: introduce login restriction option for builtin rhodecode plugin.
r3387 log.info('user `%s` authenticated correctly as anonymous user',
logging: expose extra metadata to various important logs for loki
r4816 userobj.username,
logging: changed module in logs extra as it is a reserved keyword
r4818 extra={"action": "user_auth_ok", "auth_module": "auth_rhodecode_anon", "username": userobj.username})
project: added all source files and assets
r1 return user_attrs
feat(login by email option): added ability to log in with user primary email. Fixes: RCCE-63
r5358 elif (userobj.username == username or userobj.email == username) and password_match:
logging: expose extra metadata to various important logs for loki
r4816 log.info('user `%s` authenticated correctly', userobj.username,
logging: changed module in logs extra as it is a reserved keyword
r4818 extra={"action": "user_auth_ok", "auth_module": "auth_rhodecode", "username": userobj.username})
project: added all source files and assets
r1 return user_attrs
auth: add scope and login restrictions to rhodecode plugin, and scope restriction to token plugin....
r3392 log.warning("user `%s` used a wrong password when "
"authenticating on this plugin", userobj.username)
project: added all source files and assets
r1 return None
else:
auth: add scope and login restrictions to rhodecode plugin, and scope restriction to token plugin....
r3392 log.warning('user `%s` failed to authenticate via %s, reason: account not '
'active.', username, self.name)
project: added all source files and assets
r1 return None
core: change from homebrew plugin system into pyramid machinery....
r3240
authentication: introduce login restriction option for builtin rhodecode plugin.
r3387 class RhodeCodeSettingsSchema(AuthnPluginSettingsSchemaBase):
feat(2fa): Added 2fa option. Fixes: RCCE-65
r5360 global_2fa = colander.SchemaNode(
colander.Bool(),
default=False,
description=_('Force all users to use two factor authentication by enabling this.'),
missing=False,
title=_('Global 2FA'),
widget='bool',
)
auth: add scope and login restrictions to rhodecode plugin, and scope restriction to token plugin....
r3392
auth_restriction_choices = [
(RhodeCodeAuthPlugin.AUTH_RESTRICTION_NONE, 'All users'),
(RhodeCodeAuthPlugin.AUTH_RESTRICTION_SUPER_ADMIN, 'Super admins only'),
]
auth_scope_choices = [
(RhodeCodeAuthPlugin.AUTH_RESTRICTION_SCOPE_ALL, 'HTTP and VCS'),
(RhodeCodeAuthPlugin.AUTH_RESTRICTION_SCOPE_HTTP, 'HTTP only'),
authentication: introduce login restriction option for builtin rhodecode plugin.
r3387 ]
auth: add scope and login restrictions to rhodecode plugin, and scope restriction to token plugin....
r3392 auth_restriction = colander.SchemaNode(
authentication: introduce login restriction option for builtin rhodecode plugin.
r3387 colander.String(),
auth: add scope and login restrictions to rhodecode plugin, and scope restriction to token plugin....
r3392 default=auth_restriction_choices[0],
description=_('Allowed user types for authentication using this plugin.'),
title=_('User restriction'),
validator=colander.OneOf([x[0] for x in auth_restriction_choices]),
authentication: introduce login restriction option for builtin rhodecode plugin.
r3387 widget='select_with_labels',
auth: add scope and login restrictions to rhodecode plugin, and scope restriction to token plugin....
r3392 choices=auth_restriction_choices
)
scope_restriction = colander.SchemaNode(
colander.String(),
default=auth_scope_choices[0],
description=_('Allowed protocols for authentication using this plugin. '
'VCS means GIT/HG/SVN. HTTP is web based login.'),
title=_('Scope restriction'),
validator=colander.OneOf([x[0] for x in auth_scope_choices]),
widget='select_with_labels',
choices=auth_scope_choices
authentication: introduce login restriction option for builtin rhodecode plugin.
r3387 )
core: change from homebrew plugin system into pyramid machinery....
r3240 def includeme(config):
authentication: run modernize for python3
r5094 plugin_id = f'egg:rhodecode-enterprise-ce#{RhodeCodeAuthPlugin.uid}'
core: change from homebrew plugin system into pyramid machinery....
r3240 plugin_factory(plugin_id).includeme(config)