1 # Copyright (C) 2014 Ipsilon project Contributors, for license see COPYING
3 from ipsilon.login.common import LoginFormBase, LoginManagerBase, \
5 from ipsilon.util.plugin import PluginObject
6 from ipsilon.util.policy import Policy
7 from ipsilon.util import config as pconfig
11 from fedora.client.fasproxy import FasProxyClient
12 from fedora.client import AuthError
16 import openid_cla.cla as cla
19 'cla_click': cla.CLA_URI_FEDORA_CLICK,
20 'cla_dell': cla.CLA_URI_FEDORA_DELL,
21 'cla_done': cla.CLA_URI_FEDORA_DONE,
22 'cla_fedora': cla.CLA_URI_FEDORA_FEDORA,
23 'cla_fpca': cla.CLA_URI_FEDORA_FPCA,
24 'cla_ibm': cla.CLA_URI_FEDORA_IBM,
25 'cla_intel': cla.CLA_URI_FEDORA_INTEL,
26 'cla_redhat': cla.CLA_URI_FEDORA_REDHAT,
32 ['username', 'nickname'],
33 ['telephone', 'phone'],
34 ['country_code', 'country'],
35 ['human_name', 'fullname'],
37 ['timezone', 'timezone'],
41 class FAS(LoginFormBase):
43 def __init__(self, site, mgr, page):
44 super(FAS, self).__init__(site, mgr, page)
45 self.mapper = Policy(fas_mapping)
47 def POST(self, *args, **kwargs):
48 username = kwargs.get("login_name")
49 password = kwargs.get("login_password")
52 if username and password:
55 _, data = self.lm.fpc.login(username, password)
57 cherrypy.log.error("Authentication error [%s]" % str(e),
58 severity=logging.ERROR)
59 except Exception, e: # pylint: disable=broad-except
60 cherrypy.log.error("Unknown Error [%s]" % str(e),
61 severity=logging.ERROR)
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, severity=logging.ERROR)
72 error = "Username or password is missing"
73 cherrypy.log.error("Error: " + error, severity=logging.ERROR)
75 context = self.create_tmpl_context(
78 error_password=not password,
79 error_username=not username
81 self.lm.set_auth_error()
82 return self._template(self.formtemplate, **context)
84 def make_userdata(self, fas_data):
85 userdata, fas_extra = self.mapper.map_attributes(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 group_name = CLA_GROUPS[group['name']]
97 group_name = group['name']
98 userdata['_extras']['cla'].append(group_name)
100 userdata['_groups'].append(group['name'])
105 class LoginManager(LoginManagerBase):
107 def __init__(self, *args, **kwargs):
108 super(LoginManager, self).__init__(*args, **kwargs)
111 self.service_name = 'fas'
114 self.description = """
115 Form based login Manager that uses the Fedora Authentication Server
122 'https://admin.fedoraproject.org/accounts/'),
124 'FAS Proxy client user Agent',
125 'The User Agent presented to the FAS Server.',
129 'If checked skips FAS server cert verification.',
133 'Text used to ask for the username at login time.',
137 'Text used to ask for the password at login time.',
141 'Text used to guide the user at login time.',
142 'Login with your FAS credentials')
147 return self.get_config_value('help text')
150 def username_text(self):
151 return self.get_config_value('username text')
154 def password_text(self):
155 return self.get_config_value('password text')
159 return self.get_config_value('FAS url')
162 def user_agent(self):
163 return self.get_config_value('FAS Proxy client user Agent')
167 return self.get_config_value('FAS Insecure Auth')
169 def get_tree(self, site):
170 self.fpc = FasProxyClient(base_url=self.fas_url,
171 useragent=self.user_agent,
172 insecure=(self.insecure == 'YES'))
173 self.page = FAS(site, self, 'login/fas')
177 class Installer(LoginManagerInstaller):
179 def __init__(self, *pargs):
180 super(Installer, self).__init__()
184 def install_args(self, group):
185 group.add_argument('--fas', choices=['yes', 'no'], default='no',
186 help='Configure FAS authentication')
188 def configure(self, opts):
189 if opts['fas'] != 'yes':
192 # Add configuration data to database
193 po = PluginObject(*self.pargs)
196 po.wipe_config_values()
198 # Update global config to add login plugin
200 po.save_enabled_state()