3 # Copyright (C) 2014 Ipsilon contributors, see COPYING file for license
6 from ipsilon.info.common import InfoMapping
7 from ipsilon.login.common import LoginFormBase, LoginManagerBase
8 from ipsilon.login.common import FACILITY
9 from ipsilon.util.plugin import PluginObject
10 from ipsilon.util import config as pconfig
13 from fedora.client.fasproxy import FasProxyClient
14 from fedora.client import AuthError
18 import openid_cla.cla as cla
21 'cla_click': cla.CLA_URI_FEDORA_CLICK,
22 'cla_dell': cla.CLA_URI_FEDORA_DELL,
23 'cla_done': cla.CLA_URI_FEDORA_DONE,
24 'cla_fedora': cla.CLA_URI_FEDORA_FEDORA,
25 'cla_fpca': cla.CLA_URI_FEDORA_FPCA,
26 'cla_ibm': cla.CLA_URI_FEDORA_IBM,
27 'cla_intel': cla.CLA_URI_FEDORA_INTEL,
28 'cla_redhat': cla.CLA_URI_FEDORA_REDHAT,
34 'username': 'nickname',
36 'country_code': 'country',
37 'human_name': 'fullname',
39 'timezone': 'timezone',
43 class FAS(LoginFormBase):
45 def __init__(self, site, mgr, page):
46 super(FAS, self).__init__(site, mgr, page)
47 self.mapper = InfoMapping()
48 self.mapper.set_mapping(fas_mapping)
50 def POST(self, *args, **kwargs):
51 username = kwargs.get("login_name")
52 password = kwargs.get("login_password")
55 if username and password:
58 _, data = self.lm.fpc.login(username, password)
60 cherrypy.log.error("Authentication error [%s]" % str(e))
61 except Exception, e: # pylint: disable=broad-except
62 cherrypy.log.error("Unknown Error [%s]" % str(e))
63 if data and data.user:
64 userdata = self.make_userdata(data.user)
65 return self.lm.auth_successful(self.trans,
66 data.user['username'],
69 error = "Authentication failed"
70 cherrypy.log.error(error)
72 error = "Username or password is missing"
73 cherrypy.log.error("Error: " + error)
75 context = self.create_tmpl_context(
78 error_password=not password,
79 error_username=not username
81 # pylint: disable=star-args
82 return self._template(self.formtemplate, **context)
84 def make_userdata(self, fas_data):
85 userdata, fas_extra = self.mapper.map_attrs(fas_data)
87 # compute and store groups and cla groups
88 userdata['groups'] = []
89 userdata['extras'] = {'fas': fas_extra, 'cla': []}
90 for group in fas_data.get('approved_memberships', {}):
91 if 'name' not in group:
93 if group.get('group_type') == 'cla':
94 if group['name'] in CLA_GROUPS:
95 userdata['extras']['cla'].append(CLA_GROUPS[group['name']])
97 userdata['extras']['cla'].append(group['name'])
99 userdata['groups'].append(group['name'])
104 class LoginManager(LoginManagerBase):
106 def __init__(self, *args, **kwargs):
107 super(LoginManager, self).__init__(*args, **kwargs)
110 self.service_name = 'fas'
113 self.description = """
114 Form based login Manager that uses the Fedora Authentication Server
121 'https://admin.fedoraproject.org/accounts/'),
123 'FAS Proxy client user Agent',
124 'The User Agent presented to the FAS Server.',
128 'If checked skips FAS server cert verification.',
132 'Text used to ask for the username at login time.',
136 'Text used to ask for the password at login time.',
140 'Text used to guide the user at login time.',
141 'Login with your FAS credentials')
146 return self.get_config_value('help text')
149 def username_text(self):
150 return self.get_config_value('username text')
153 def password_text(self):
154 return self.get_config_value('password text')
158 return self.get_config_value('FAS url')
161 def user_agent(self):
162 return self.get_config_value('FAS Proxy client user Agent')
166 return self.get_config_value('FAS Insecure Auth')
168 def get_tree(self, site):
169 self.fpc = FasProxyClient(base_url=self.fas_url,
170 useragent=self.user_agent,
171 insecure=(self.insecure == 'YES'))
172 self.page = FAS(site, self, 'login/fas')
176 class Installer(object):
182 def install_args(self, group):
183 group.add_argument('--fas', choices=['yes', 'no'], default='no',
184 help='Configure FAS authentication')
186 def configure(self, opts):
187 if opts['fas'] != 'yes':
190 # Add configuration data to database
195 po.wipe_config_values(FACILITY)
197 # Update global config to add login plugin
200 globalconf = po.get_plugin_config(FACILITY)
201 if 'order' in globalconf:
202 order = globalconf['order'].split(',')
206 globalconf['order'] = ','.join(order)
207 po.save_plugin_config(FACILITY, globalconf)