3 # Copyright (C) 2014 Ipsilon contributors, see COPYING file for license
6 from ipsilon.login.common import LoginFormBase, LoginManagerBase
7 from ipsilon.login.common import FACILITY
8 from ipsilon.util.plugin import PluginObject
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 class FAS(LoginFormBase):
34 def POST(self, *args, **kwargs):
35 username = kwargs.get("login_name")
36 password = kwargs.get("login_password")
39 if username and password:
42 _, data = self.lm.fpc.login(username, password)
44 cherrypy.log.error("Authentication error [%s]" % str(e))
45 except Exception, e: # pylint: disable=broad-except
46 cherrypy.log.error("Unknown Error [%s]" % str(e))
47 if data and data.user:
48 userdata = self.make_userdata(data.user)
49 return self.lm.auth_successful(self.trans,
50 data.user['username'],
53 error = "Authentication failed"
54 cherrypy.log.error(error)
56 error = "Username or password is missing"
57 cherrypy.log.error("Error: " + error)
59 context = self.create_tmpl_context(
62 error_password=not password,
63 error_username=not username
65 # pylint: disable=star-args
66 return self._template(self.formtemplate, **context)
68 def make_userdata(self, fas_data):
70 userdata['fas'] = fas_data
72 # compute and store groups and cla groups
73 userdata['groups'] = []
74 userdata['extras'] = {'cla': []}
75 for group in fas_data.get('approved_memberships', {}):
76 if 'name' not in group:
78 if group.get('group_type') == 'cla':
79 if group['name'] in CLA_GROUPS:
80 userdata['extras']['cla'].append(CLA_GROUPS[group['name']])
82 userdata['extras']['cla'].append(group['name'])
84 userdata['groups'].append(group['name'])
89 class LoginManager(LoginManagerBase):
91 def __init__(self, *args, **kwargs):
92 super(LoginManager, self).__init__(*args, **kwargs)
95 self.service_name = 'fas'
98 self.description = """
99 Form based login Manager that uses the Fedora Authentication Server
103 """ The text shown to guide the user at login time. """,
105 'Login wth your FAS credentials'
108 """ The text shown to ask for the username in the form. """,
113 """ The text shown to ask for the password in the form. """,
118 """ The FAS Url. """,
120 'https://admin.fedoraproject.org/accounts/'
122 'FAS Proxy client user Agent': [
123 """ The User Agent presented to the FAS Server. """,
127 'FAS Insecure Auth': [
128 """ If 'YES' skips FAS server cert verification. """,
133 self.conf_opt_order = ['FAS url', 'FAS Proxy client user Agent',
134 'FAS Insecure Auth', 'username text',
135 'password text', 'help text']
139 return self.get_config_value('help text')
142 def username_text(self):
143 return self.get_config_value('username text')
146 def password_text(self):
147 return self.get_config_value('password text')
151 return self.get_config_value('FAS url')
154 def user_agent(self):
155 return self.get_config_value('FAS Proxy client user Agent')
159 return self.get_config_value('FAS Insecure Auth')
161 def get_tree(self, site):
162 self.fpc = FasProxyClient(base_url=self.fas_url,
163 useragent=self.user_agent,
164 insecure=(self.insecure == 'YES'))
165 self.page = FAS(site, self, 'login/fas', 'login/fas.html')
169 class Installer(object):
175 def install_args(self, group):
176 group.add_argument('--fas', choices=['yes', 'no'], default='no',
177 help='Configure FAS authentication')
179 def configure(self, opts):
180 if opts['fas'] != 'yes':
183 # Add configuration data to database
188 po.wipe_config_values(FACILITY)
190 # Update global config to add login plugin
193 globalconf = po.get_plugin_config(FACILITY)
194 if 'order' in globalconf:
195 order = globalconf['order'].split(',')
199 globalconf['order'] = ','.join(order)
200 po.set_config(globalconf)
201 po.save_plugin_config(FACILITY)