1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
|
# -*- coding: utf-8 -*-
#
# Copyright (C) 2008-2009 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 <http://www.gnu.org/licenses/>
#
'''Implement a class that sets up threadsafe communication with the Fedora
Account System
.. moduleauthor:: Ricky Zhou <ricky@fedoraproject.org>
.. moduleauthor:: Toshio Kuratomi <tkuratom@redhat.com>
.. versionadded:: 0.3.17
'''
from fedora.client import AuthError, AppError
from fedora.client.proxyclient import ProxyClient
from fedora import __version__
import logging
log = logging.getLogger(__name__)
class FasProxyClient(ProxyClient):
'''A threadsafe client to the Fedora Account System.'''
def __init__(self, base_url='https://admin.fedoraproject.org/accounts/',
*args, **kwargs):
'''A threadsafe client to the Fedora Account System.
This class is optimized to proxy multiple users to the account system.
ProxyClient is designed to be threadsafe so that code can instantiate
one instance of the class and use it for multiple requests for
different users from different threads.
If you want something that can manage a single user's connection to
the Account System then use fedora.client.AccountSystem instead.
:kwargs base_url: Base of every URL used to contact the server.
Defaults to the Fedora Project FAS instance.
:kwargs useragent: useragent string to use. If not given, default to
"FAS Proxy Client/VERSION"
:kwarg session_name: name of the cookie to use with session handling
: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.
'''
if 'useragent' not in kwargs:
kwargs['useragent'] = 'FAS Proxy Client/%s' % __version__
if 'session_as_cookie' in kwargs and kwargs['session_as_cookie']:
# No need to allow this in FasProxyClient as it's deprecated in
# ProxyClient
raise TypeError('FasProxyClient() got an unexpected keyword'
' argument \'session_as_cookie\'')
kwargs['session_as_cookie'] = False
super(FasProxyClient, self).__init__(base_url, *args, **kwargs)
def login(self, username, password):
'''Login to the Account System
:arg username: username to send to FAS
:arg password: Password to verify the username with
:returns: a tuple of the session id FAS has associated with the user
and the user's account information. This is similar to what is
returned by
:meth:`fedora.client.proxyclient.ProxyClient.get_user_info`
:raises AuthError: if the username and password do not work
'''
return self.send_request(
'/login',
auth_params={'username': username, 'password': password}
)
def logout(self, session_id):
'''Logout of the Account System
:arg session_id: a FAS session_id to remove from FAS
'''
self.send_request('/logout', auth_params={'session_id': session_id})
def refresh_session(self, session_id):
'''Try to refresh a session_id to prevent it from timing out
:arg session_id: FAS session_id to refresh
:returns: session_id that FAS has set now
'''
return self.send_request('', auth_params={'session_id': session_id})
def verify_session(self, session_id):
'''Verify that a session is active.
:arg session_id: session_id to verify is currently associated with a
logged in user
:returns: True if the session_id is valid. False otherwise.
'''
try:
self.send_request('/home', auth_params={'session_id': session_id})
except AuthError:
return False
except:
raise
return True
def verify_password(self, username, password):
'''Return whether the username and password pair are valid.
:arg username: username to try authenticating
:arg password: password for the user
:returns: True if the username/password are valid. False otherwise.
'''
try:
self.send_request('/home',
auth_params={'username': username,
'password': password})
except AuthError:
return False
except:
raise
return True
def get_user_info(self, auth_params):
'''Retrieve information about a logged in user.
:arg auth_params: Auth information for a particular user. For
instance, this can be a username/password pair or a session_id.
Refer to
:meth:`fedora.client.proxyclient.ProxyClient.send_request` for all
the legal values for this.
:returns: a tuple of session_id and information about the user.
:raises AuthError: if the auth_params do not give access
'''
request = self.send_request('/user/view', auth_params=auth_params)
return (request[0], request[1]['person'])
def person_by_id(self, person_id, auth_params):
'''Retrieve information about a particular person
:arg auth_params: Auth information for a particular user. For
instance, this can be a username/password pair or a session_id.
Refer to
:meth:`fedora.client.proxyclient.ProxyClient.send_request` for all
the legal values for this.
:returns: a tuple of session_id and information about the user.
:raises AppError: if the server returns an exception
:raises AuthError: if the auth_params do not give access
'''
request = self.send_request('/json/person_by_id',
req_params={'person_id': person_id},
auth_params=auth_params)
if request[1]['success']:
# In a devel version of FAS, membership info was returned
# separately
# This has been corrected in a later version
# Can remove this code at some point
if 'approved' in request[1]:
request[1]['person']['approved_memberships'] = \
request[1]['approved']
if 'unapproved' in request[1]:
request[1]['person']['unapproved_memberships'] = \
request[1]['unapproved']
return (request[0], request[1]['person'])
else:
raise AppError(name='Generic AppError',
message=request[1]['tg_flash'])
def group_list(self, auth_params):
'''Retrieve a list of groups
:arg auth_params: Auth information for a particular user. For
instance, this can be a username/password pair or a session_id.
Refer to
:meth:`fedora.client.proxyclient.ProxyClient.send_request` for all
the legal values for this.
:returns: a tuple of session_id and information about groups. The
groups information is in two fields:
:groups: contains information about each group
:memberships: contains information about which users are members
of which groups
:raises AuthError: if the auth_params do not give access
'''
request = self.send_request('/group/list', auth_params=auth_params)
return request
|