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 # pylint: disable=star-args
84 return self._template(self.formtemplate, **context)
86 def make_userdata(self, fas_data):
87 userdata, fas_extra = self.mapper.map_attributes(fas_data)
89 # compute and store groups and cla groups
90 userdata['_groups'] = []
91 userdata['_extras'] = {'fas': fas_extra, 'cla': []}
92 for group in fas_data.get('approved_memberships', {}):
93 if 'name' not in group:
95 if group.get('group_type') == 'cla':
96 if group['name'] in CLA_GROUPS:
97 group_name = CLA_GROUPS[group['name']]
99 group_name = group['name']
100 userdata['_extras']['cla'].append(group_name)
102 userdata['_groups'].append(group['name'])
107 class LoginManager(LoginManagerBase):
109 def __init__(self, *args, **kwargs):
110 super(LoginManager, self).__init__(*args, **kwargs)
113 self.service_name = 'fas'
116 self.description = """
117 Form based login Manager that uses the Fedora Authentication Server
124 'https://admin.fedoraproject.org/accounts/'),
126 'FAS Proxy client user Agent',
127 'The User Agent presented to the FAS Server.',
131 'If checked skips FAS server cert verification.',
135 'Text used to ask for the username at login time.',
139 'Text used to ask for the password at login time.',
143 'Text used to guide the user at login time.',
144 'Login with your FAS credentials')
149 return self.get_config_value('help text')
152 def username_text(self):
153 return self.get_config_value('username text')
156 def password_text(self):
157 return self.get_config_value('password text')
161 return self.get_config_value('FAS url')
164 def user_agent(self):
165 return self.get_config_value('FAS Proxy client user Agent')
169 return self.get_config_value('FAS Insecure Auth')
171 def get_tree(self, site):
172 self.fpc = FasProxyClient(base_url=self.fas_url,
173 useragent=self.user_agent,
174 insecure=(self.insecure == 'YES'))
175 self.page = FAS(site, self, 'login/fas')
179 class Installer(LoginManagerInstaller):
181 def __init__(self, *pargs):
182 super(Installer, self).__init__()
186 def install_args(self, group):
187 group.add_argument('--fas', choices=['yes', 'no'], default='no',
188 help='Configure FAS authentication')
190 def configure(self, opts):
191 if opts['fas'] != 'yes':
194 # Add configuration data to database
195 po = PluginObject(*self.pargs)
198 po.wipe_config_values()
200 # Update global config to add login plugin
202 po.save_enabled_state()