From 3cb6f5ca9d1eaee5f6dcacbd5a699f075a7cb1f2 Mon Sep 17 00:00:00 2001 From: Martin Krizek Date: Mon, 28 Nov 2016 12:32:08 +0000 Subject: [PATCH] blockerbugs: remove hotfix, already released --- .../python-fedora-openidbaseclient-hotfix.py | 406 ------------------ roles/blockerbugs/tasks/main.yml | 9 - 2 files changed, 415 deletions(-) delete mode 100644 roles/blockerbugs/files/python-fedora-openidbaseclient-hotfix.py diff --git a/roles/blockerbugs/files/python-fedora-openidbaseclient-hotfix.py b/roles/blockerbugs/files/python-fedora-openidbaseclient-hotfix.py deleted file mode 100644 index 5bc1c8af14..0000000000 --- a/roles/blockerbugs/files/python-fedora-openidbaseclient-hotfix.py +++ /dev/null @@ -1,406 +0,0 @@ -#!/usr/bin/env python2 -tt -# -*- coding: utf-8 -*- -# -# Copyright (C) 2013-2014 Red Hat, Inc. -# This file is part of python-fedora -# -# python-fedora is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# python-fedora 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 -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with python-fedora; if not, see -# - -"""Base client for application relying on OpenID for authentication. - -.. moduleauthor:: Pierre-Yves Chibon -.. moduleauthor:: Toshio Kuratomi - -.. versionadded: 0.3.35 - -""" - -# :F0401: Unable to import : Disabled because these will either import on py3 -# or py2 not both. -# :E0611: No name $X in module: This was renamed in python3 - -import logging -import os -import sqlite3 -from collections import defaultdict -from functools import partial - -# pylint: disable-msg=F0401 -try: - # pylint: disable-msg=E0611 - # Python 3 - from urllib.parse import urljoin -except ImportError: - # Python 2 - from urlparse import urljoin -# pylint: enable-msg=F0401,E0611 - - -import requests -from functools import wraps -from munch import munchify -from kitchen.text.converters import to_bytes - -from fedora import __version__ -from fedora.client import AuthError, LoginRequiredError, ServerError -from fedora.client.openidproxyclient import ( - OpenIdProxyClient, absolute_url, openid_login) - -log = logging.getLogger(__name__) - -b_SESSION_DIR = os.path.join(os.path.expanduser('~'), '.fedora') -b_SESSION_FILE = os.path.join(b_SESSION_DIR, 'baseclient-sessions.sqlite') - - -def requires_login(func): - """ - Decorator function for get or post requests requiring login. - - Decorate a controller method that requires the user to be authenticated. - Example:: - - from fedora.client.openidbaseclient import requires_login - - @requires_login - def rename_user(new_name): - user = new_name - # [...] - """ - def _decorator(request, *args, **kwargs): - """ Run the function and check if it redirected to the openid form. - """ - output = func(request, *args, **kwargs) - if output and \ - 'OpenID transaction in progress' in output.text: - raise LoginRequiredError( - '{0} requires a logged in user'.format(output.url)) - return output - return wraps(func)(_decorator) - - -class OpenIdBaseClient(OpenIdProxyClient): - - """ A client for interacting with web services relying on openid auth. """ - - def __init__(self, base_url, login_url=None, useragent=None, debug=False, - insecure=False, openid_insecure=False, username=None, - session_id=None, session_name='session', - openid_session_id=None, openid_session_name='FAS_OPENID', - cache_session=True, retries=None, timeout=None): - """Client for interacting with web services relying on fas_openid auth. - - :arg base_url: Base of every URL used to contact the server - :kwarg login_url: The url to the login endpoint of the application. - If none are specified, it uses the default `/login`. - :kwarg useragent: Useragent string to use. If not given, default to - "Fedora OpenIdBaseClient/VERSION" - :kwarg debug: If True, log debug information - :kwarg insecure: If True, do not check server certificates against - their CA's. This means that man-in-the-middle attacks are - possible against the `BaseClient`. You might turn this option on - for testing against a local version of a server with a self-signed - certificate but it should be off in production. - :kwarg openid_insecure: If True, do not check the openid server - certificates against their CA's. This means that man-in-the- - middle attacks are possible against the `BaseClient`. You might - turn this option on for testing against a local version of a - server with a self-signed certificate but it should be off in - production. - :kwarg username: Username for establishing authenticated connections - :kwarg session_id: id of the user's session - :kwarg session_name: name of the cookie to use with session handling - :kwarg openid_session_id: id of the user's openid session - :kwarg openid_session_name: name of the cookie to use with openid - session handling - :kwarg cache_session: If set to true, cache the user's session data on - the filesystem between runs - :kwarg retries: if we get an unknown or possibly transient error from - the server, retry this many times. Setting this to a negative - number makes it try forever. Defaults to zero, no retries. - :kwarg timeout: A float describing the timeout of the connection. The - timeout only affects the connection process itself, not the - downloading of the response body. Defaults to 120 seconds. - - """ - - # These are also needed by OpenIdProxyClient - self.useragent = useragent or 'Fedora BaseClient/%(version)s' % { - 'version': __version__} - self.base_url = base_url - self.login_url = login_url or urljoin(self.base_url, '/login') - self.debug = debug - self.insecure = insecure - self.openid_insecure = openid_insecure - self.retries = retries - self.timeout = timeout - self.session_name = session_name - self.openid_session_name = openid_session_name - - # These are specific to OpenIdBaseClient - self.username = username - self.cache_session = cache_session - - # Make sure the database for storing the session cookies exists - if cache_session: - self._db = self._initialize_session_cache() - if not self._db: - self.cache_session = False - - # Session cookie that identifies this user to the application - self._session_id_map = defaultdict(str) - if session_id: - self.session_id = session_id - if openid_session_id: - self.openid_session_id = openid_session_id - - # python-requests session. Holds onto cookies - self._session = requests.session() - - def _initialize_session_cache(self): - # Note -- fallback to returning None on any problems as this isn't - # critical. It just makes it so that we don't have to ask the user - # for their password over and over. - if not os.path.isdir(b_SESSION_DIR): - try: - os.makedirs(b_SESSION_DIR, mode=0o755) - except OSError as err: - log.warning('Unable to create {file}: {error}'.format( - file=b_SESSION_DIR, error=err)) - return None - - if not os.path.exists(b_SESSION_FILE): - dbcon = sqlite3.connect(b_SESSION_FILE) - cursor = dbcon.cursor() - try: - cursor.execute('create table sessions (username text,' - ' base_url text, session_id text,' - ' primary key (username, base_url))') - except sqlite3.DatabaseError as err: - # Probably not a database - log.warning('Unable to initialize {file}: {error}'.format( - file=b_SESSION_FILE, error=err)) - return None - dbcon.commit() - else: - try: - dbcon = sqlite3.connect(b_SESSION_FILE) - except sqlite3.OperationalError as err: - # Likely permission denied - log.warning('Unable to connect to {file}: {error}'.format( - file=b_SESSION_FILE, error=err)) - return None - return dbcon - - def _get_id(self, base_url=None): - # base_url is only sent as a param if we're looking for the openid - # session - base_url = base_url or self.base_url - - username = self.username or '' - - session_id_key = '{}:{}'.format(base_url, username) - if self._session_id_map[session_id_key]: - # Cached in memory - return self._session_id_map[session_id_key] - - if username and self.cache_session: - # Look for a session on disk - cursor = self._db.cursor() - cursor.execute('select * from sessions where' - ' username = ? and base_url = ?', - (username, base_url)) - found_sessions = cursor.fetchall() - if found_sessions: - self._session_id_map[session_id_key] = found_sessions[0] - - if not self._session_id_map[session_id_key]: - log.debug('No session cached for "{username}"'.format( - username=self.username)) - return self._session_id_map[session_id_key] - - def _set_id(self, session_id, base_url=None): - #if not self.username: - # base_url is only sent as a param if we're looking for the openid - # session - base_url = base_url or self.base_url - - username = self.username or '' - - # Cache in memory - session_id_key = '{}:{}'.format(base_url, username) - self._session_id_map[session_id_key] = session_id - - if username and self.cache_session: - # Save to disk as well - cursor = self._db.cursor() - try: - cursor.exectue('insert into sessions' - ' (session_id, username, base_url)' - ' values (?, ?, ?)', - (session_id, username, base_url)) - except sqlite3.IntegrityError: - # Record already exists for that username and url - cursor.execute('update sessions set session_id = ? where' - ' username = ? and base_url = ?', - (session_id, username, base_url)) - cursor.commit() - - def _del_id(self, base_url=None): - # base_url is only sent as a param if we're looking for the openid - # session - base_url = base_url or self.base_url - - username = self.username or '' - - # Remove from the in-memory cache - session_id_key = '{}:{}'.format(base_url, username) - del self._session_id_map[session_id_key] - - if username and self.cache_session: - # Remove from the disk cache as well - cursor = self._db.cursor() - cursor.execute('delete from sessions where' - ' username = ? and base_url = ?', - (username, base_url)) - - session_id = property( - _get_id, - _set_id, - _del_id, - """The session_id. - - The session id is saved in a file in case it is needed in - consecutive runs of BaseClient. - """) - - openid_session_id = property( - partial(_get_id, base_url='FAS_OPENID'), - partial(_set_id, base_url='FAS_OPENID'), - partial(_del_id, base_url='FAS_OPENID'), - """The openid_session_id. - - The openid session id is saved in a file in case it is needed in - consecutive runs of BaseClient. - """) - - @requires_login - def _authed_post(self, url, params=None, data=None, **kwargs): - """ Return the request object of a post query.""" - response = self._session.post(url, params=params, data=data, **kwargs) - return response - - @requires_login - def _authed_get(self, url, params=None, data=None, **kwargs): - """ Return the request object of a get query.""" - response = self._session.get(url, params=params, data=data, **kwargs) - return response - - def send_request(self, method, auth=False, verb='POST', **kwargs): - """Make an HTTP request to a server method. - - The given method is called with any parameters set in req_params. If - auth is True, then the request is made with an authenticated session - cookie. - - :arg method: Method to call on the server. It's a url fragment that - comes after the :attr:`base_url` set in :meth:`__init__`. - :kwarg retries: if we get an unknown or possibly transient error from - the server, retry this many times. Setting this to a negative - number makes it try forever. Default to use the :attr:`retries` - value set on the instance or in :meth:`__init__` (which defaults - to zero, no retries). - :kwarg timeout: A float describing the timeout of the connection. The - timeout only affects the connection process itself, not the - downloading of the response body. Default to use the - :attr:`timeout` value set on the instance or in :meth:`__init__` - (which defaults to 120s). - :kwarg auth: If True perform auth to the server, else do not. - :kwarg req_params: Extra parameters to send to the server. - :kwarg file_params: dict of files where the key is the name of the - file field used in the remote method and the value is the local - path of the file to be uploaded. If you want to pass multiple - files to a single file field, pass the paths as a list of paths. - :kwarg verb: HTTP verb to use. GET and POST are currently supported. - POST is the default. - """ - # Decide on the set of auth cookies to use - - method = absolute_url(self.base_url, method) - - self._authed_verb_dispatcher = {(False, 'POST'): self._session.post, - (False, 'GET'): self._session.get, - (True, 'POST'): self._authed_post, - (True, 'GET'): self._authed_get} - try: - func = self._authed_verb_dispatcher[(auth, verb)] - except KeyError: - raise Exception('Unknown HTTP verb') - - if auth: - auth_params = {'session_id': self.session_id, - 'openid_session_id': self.openid_session_id} - try: - output = func(method, auth_params, **kwargs) - except LoginRequiredError: - raise AuthError() - else: - try: - output = func(method, **kwargs) - except LoginRequiredError: - raise AuthError() - - try: - data = output.json - # Compatibility with newer python-requests - if callable(data): - data = data() - except ValueError as e: - # The response wasn't JSON data - raise ServerError( - method, output.status_code, 'Error returned from' - ' json module while processing %(url)s: %(err)s\n%(output)s' % - { - 'url': to_bytes(method), - 'err': to_bytes(e), - 'output': to_bytes(output.text), - }) - - data = munchify(data) - - return data - - - def login(self, username, password, otp=None): - """ Open a session for the user. - - Log in the user with the specified username and password - against the FAS OpenID server. - - :arg username: the FAS username of the user that wants to log in - :arg password: the FAS password of the user that wants to log in - :kwarg otp: currently unused. Eventually a way to send an otp to the - API that the API can use. - - """ - response = openid_login( - session=self._session, - login_url=self.login_url, - username=username, - password=password, - otp=otp, - openid_insecure=self.openid_insecure) - return response - -__all__ = ('OpenIdBaseClient', 'requires_login') diff --git a/roles/blockerbugs/tasks/main.yml b/roles/blockerbugs/tasks/main.yml index e96c8bdda6..2b4054e592 100644 --- a/roles/blockerbugs/tasks/main.yml +++ b/roles/blockerbugs/tasks/main.yml @@ -52,12 +52,3 @@ tags: - config - blockerbugs - -# hotfix openidbaseclient.py in python-fedora so it doesn't blow up during sync. -# fix is in upstream, waiting for new release: https://github.com/fedora-infra/python-fedora/commit/a5a66e8e744ad1c54788e00d78bd6b66e67fe83b -- name: hotfix python-fedora so it doesn't blow up - when: env == "production" - copy: src=python-fedora-openidbaseclient-hotfix.py dest=/usr/lib/python2.7/site-packages/fedora/client/openidbaseclient.py owner=root group=root mode=0644 - tags: - - blockerbugs - - hotfix