1 # Copyright (C) 2014 Ipsilon contributors, see COPYING file for license
4 from ipsilon.login.common import LoginFormBase, LoginManagerBase, \
6 from ipsilon.util.plugin import PluginObject
7 from ipsilon.util.policy import Policy
8 from ipsilon.util import config as pconfig
12 from fedora.client.fasproxy import FasProxyClient
13 from fedora.client import AuthError
17 import openid_cla.cla as cla
20 'cla_click': cla.CLA_URI_FEDORA_CLICK,
21 'cla_dell': cla.CLA_URI_FEDORA_DELL,
22 'cla_done': cla.CLA_URI_FEDORA_DONE,
23 'cla_fedora': cla.CLA_URI_FEDORA_FEDORA,
24 'cla_fpca': cla.CLA_URI_FEDORA_FPCA,
25 'cla_ibm': cla.CLA_URI_FEDORA_IBM,
26 'cla_intel': cla.CLA_URI_FEDORA_INTEL,
27 'cla_redhat': cla.CLA_URI_FEDORA_REDHAT,
33 ['username', 'nickname'],
34 ['telephone', 'phone'],
35 ['country_code', 'country'],
36 ['human_name', 'fullname'],
38 ['timezone', 'timezone'],
42 class FAS(LoginFormBase):
44 def __init__(self, site, mgr, page):
45 super(FAS, self).__init__(site, mgr, page)
46 self.mapper = Policy(fas_mapping)
48 def POST(self, *args, **kwargs):
49 username = kwargs.get("login_name")
50 password = kwargs.get("login_password")
53 if username and password:
56 _, data = self.lm.fpc.login(username, password)
58 cherrypy.log.error("Authentication error [%s]" % str(e),
59 severity=logging.ERROR)
60 except Exception, e: # pylint: disable=broad-except
61 cherrypy.log.error("Unknown Error [%s]" % str(e),
62 severity=logging.ERROR)
64 if data and data.user:
65 userdata = self.make_userdata(data.user)
66 return self.lm.auth_successful(self.trans,
67 data.user['username'],
70 error = "Authentication failed"
71 cherrypy.log.error(error, severity=logging.ERROR)
73 error = "Username or password is missing"
74 cherrypy.log.error("Error: " + error, severity=logging.ERROR)
76 context = self.create_tmpl_context(
79 error_password=not password,
80 error_username=not username
82 self.lm.set_auth_error()
83 return self._template(self.formtemplate, **context)
85 def make_userdata(self, fas_data):
86 userdata, fas_extra = self.mapper.map_attributes(fas_data)
88 # compute and store groups and cla groups
89 userdata['_groups'] = []
90 userdata['_extras'] = {'fas': fas_extra, 'cla': []}
91 for group in fas_data.get('approved_memberships', {}):
92 if 'name' not in group:
94 if group.get('group_type') == 'cla':
95 if group['name'] in CLA_GROUPS:
96 group_name = CLA_GROUPS[group['name']]
98 group_name = group['name']
99 userdata['_extras']['cla'].append(group_name)
101 userdata['_groups'].append(group['name'])
106 class LoginManager(LoginManagerBase):
108 def __init__(self, *args, **kwargs):
109 super(LoginManager, self).__init__(*args, **kwargs)
112 self.service_name = 'fas'
115 self.description = """
116 Form based login Manager that uses the Fedora Authentication Server
123 'https://admin.fedoraproject.org/accounts/'),
125 'FAS Proxy client user Agent',
126 'The User Agent presented to the FAS Server.',
130 'If checked skips FAS server cert verification.',
134 'Text used to ask for the username at login time.',
138 'Text used to ask for the password at login time.',
142 'Text used to guide the user at login time.',
143 'Login with your FAS credentials')
148 return self.get_config_value('help text')
151 def username_text(self):
152 return self.get_config_value('username text')
155 def password_text(self):
156 return self.get_config_value('password text')
160 return self.get_config_value('FAS url')
163 def user_agent(self):
164 return self.get_config_value('FAS Proxy client user Agent')
168 return self.get_config_value('FAS Insecure Auth')
170 def get_tree(self, site):
171 self.fpc = FasProxyClient(base_url=self.fas_url,
172 useragent=self.user_agent,
173 insecure=(self.insecure == 'YES'))
174 self.page = FAS(site, self, 'login/fas')
178 class Installer(LoginManagerInstaller):
180 def __init__(self, *pargs):
181 super(Installer, self).__init__()
185 def install_args(self, group):
186 group.add_argument('--fas', choices=['yes', 'no'], default='no',
187 help='Configure FAS authentication')
189 def configure(self, opts):
190 if opts['fas'] != 'yes':
193 # Add configuration data to database
194 po = PluginObject(*self.pargs)
197 po.wipe_config_values()
199 # Update global config to add login plugin
201 po.save_enabled_state()