Mercurial > kallithea
view rhodecode/lib/auth_modules/auth_pam.py @ 4116:ffd45b185016 rhodecode-2.2.5-gpl
Imported some of the GPLv3'd changes from RhodeCode v2.2.5.
This imports changes between changesets 21af6c4eab3d and 6177597791c2 in
RhodeCode's original repository, including only changes to Python files and HTML.
RhodeCode clearly licensed its changes to these files under GPLv3
in their /LICENSE file, which states the following:
The Python code and integrated HTML are licensed under the GPLv3 license.
(See:
https://code.rhodecode.com/rhodecode/files/v2.2.5/LICENSE
or
http://web.archive.org/web/20140512193334/https://code.rhodecode.com/rhodecode/files/f3b123159901f15426d18e3dc395e8369f70ebe0/LICENSE
for an online copy of that LICENSE file)
Conservancy reviewed these changes and confirmed that they can be licensed as
a whole to the Kallithea project under GPLv3-only.
While some of the contents committed herein are clearly licensed
GPLv3-or-later, on the whole we must assume the are GPLv3-only, since the
statement above from RhodeCode indicates that they intend GPLv3-only as their
license, per GPLv3ยง14 and other relevant sections of GPLv3.
author | Bradley M. Kuhn <bkuhn@sfconservancy.org> |
---|---|
date | Wed, 02 Jul 2014 19:03:13 -0400 |
parents | |
children | 7e5f8c12a3fc |
line wrap: on
line source
# -*- coding: utf-8 -*- # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # 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 General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. """ rhodecode.lib.auth_pam ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RhodeCode authentication library for PAM :created_on: Created on Apr 09, 2013 :author: Alexey Larikov """ import logging import time import pam import pwd import grp import re import socket import threading from rhodecode.lib import auth_modules from rhodecode.lib.compat import formatted_json, hybrid_property log = logging.getLogger(__name__) # Cache to store PAM authenticated users _auth_cache = dict() _pam_lock = threading.Lock() class RhodeCodeAuthPlugin(auth_modules.RhodeCodeExternalAuthPlugin): # PAM authnetication can be slow. Repository operations involve a lot of # auth calls. Little caching helps speedup push/pull operations significantly AUTH_CACHE_TTL = 4 def __init__(self): global _auth_cache ts = time.time() cleared_cache = dict( [(k, v) for (k, v) in _auth_cache.items() if (v + RhodeCodeAuthPlugin.AUTH_CACHE_TTL > ts)]) _auth_cache = cleared_cache @hybrid_property def name(self): return "pam" def settings(self): settings = [ { "name": "service", "validator": self.validators.UnicodeString(strip=True), "type": "string", "description": "PAM service name to use for authentication", "default": "login", "formname": "PAM service name" }, { "name": "gecos", "validator": self.validators.UnicodeString(strip=True), "type": "string", "description": "Regex for extracting user name/email etc " "from Unix userinfo", "default": "(?P<last_name>.+),\s*(?P<first_name>\w+)", "formname": "Gecos Regex" } ] return settings def use_fake_password(self): return True def auth(self, userobj, username, password, settings, **kwargs): if username not in _auth_cache: # Need lock here, as PAM authentication is not thread safe _pam_lock.acquire() try: auth_result = pam.authenticate(username, password, settings["service"]) # cache result only if we properly authenticated if auth_result: _auth_cache[username] = time.time() finally: _pam_lock.release() if not auth_result: log.error("PAM was unable to authenticate user: %s" % (username,)) return None else: log.debug("Using cached auth for user: %s" % (username,)) # old attrs fetched from RhodeCode database admin = getattr(userobj, 'admin', False) active = getattr(userobj, 'active', True) email = getattr(userobj, 'email', '') or "%s@%s" % (username, socket.gethostname()) firstname = getattr(userobj, 'firstname', '') lastname = getattr(userobj, 'lastname', '') extern_type = getattr(userobj, 'extern_type', '') user_attrs = { 'username': username, 'firstname': firstname, 'lastname': lastname, 'groups': [g.gr_name for g in grp.getgrall() if username in g.gr_mem], 'email': email, 'admin': admin, 'active': active, "active_from_extern": None, 'extern_name': username, 'extern_type': extern_type, } try: user_data = pwd.getpwnam(username) regex = settings["gecos"] match = re.search(regex, user_data.pw_gecos) if match: user_attrs["firstname"] = match.group('first_name') user_attrs["lastname"] = match.group('last_name') except Exception: log.warn("Cannot extract additional info for PAM user") pass log.debug("pamuser: \n%s" % formatted_json(user_attrs)) log.info('user %s authenticated correctly' % user_attrs['username']) return user_attrs