--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -62,7 +62,9 @@
class AuthController(BaseController):
def __init__(self):
- self.prefs = PreferencesController()
+ self.preferences = PreferencesController()
+ self.user_info = UserInfoController()
+ self.subscriptions = SubscriptionsController()
self.oauth = OAuthController()
@expose('jinja:allura:templates/login.html')
@@ -188,7 +190,7 @@
if c.user:
c.user.claim_openid(oid_obj._id)
flash('Claimed %s' % oid_obj._id)
- redirect('/auth/prefs/')
+ redirect('/auth/preferences/')
@expose()
def logout(self):
@@ -293,268 +295,27 @@
allow_write=has_access(c.app, 'write')(user=user),
allow_create=has_access(c.app, 'create')(user=user))
-class UserSkillsController(BaseController):
-
- def __init__(self, category=None):
- self.category = category
- super(UserSkillsController, self).__init__()
-
- @expose()
- def _lookup(self, catshortname, *remainder):
- cat = M.TroveCategory.query.get(shortname=catshortname)
- return UserSkillsController(category=cat), remainder
-
- @expose('jinja:allura:templates/user_skills.html')
+class PreferencesController(BaseController):
+
+ def _check_security(self):
+ require_authenticated()
+
+ @with_trailing_slash
+ @expose('jinja:allura:templates/user_prefs.html')
def index(self, **kw):
- require_authenticated()
-
- l = []
- parents = []
- if kw.get('selected_category') is not None:
- selected_skill = M.TroveCategory.query.get(trove_cat_id=int(kw.get('selected_category')))
- elif self.category:
- selected_skill = self.category
- else:
- l = M.TroveCategory.query.find(dict(trove_parent_id=0, show_as_skill=True))
- selected_skill = None
- if selected_skill:
- l = [scat for scat in selected_skill.subcategories
- if scat.show_as_skill]
- temp_cat = selected_skill.parent_category
- while temp_cat:
- parents = [temp_cat] + parents
- temp_cat = temp_cat.parent_category
- return dict(
- skills_list = l,
- selected_skill = selected_skill,
- parents = parents,
- add_details_fields=(len(l)==0))
-
- @expose()
- @require_post()
- @validate(F.save_skill_form, error_handler=index)
- def save_skill(self, **kw):
- require_authenticated()
-
- trove_id = int(kw.get('selected_skill'))
- category = M.TroveCategory.query.get(trove_cat_id=trove_id)
-
- new_skill = dict(
- category_id=category._id,
- level=kw.get('level'),
- comment=kw.get('comment'))
-
- s = [skill for skill in c.user.skills
- if str(skill.category_id) != str(new_skill['category_id'])]
- s.append(new_skill)
- c.user.set_pref('skills', s)
- flash('Your skills list was successfully updated!')
- redirect('/auth/prefs/user_skills')
-
- @expose()
- @require_post()
- @validate(F.remove_skill_form, error_handler=index)
- def remove_skill(self, **kw):
- require_authenticated()
-
- trove_id = int(kw.get('categoryid'))
- category = M.TroveCategory.query.get(trove_cat_id=trove_id)
-
- s = [skill for skill in c.user.skills
- if str(skill.category_id) != str(category._id)]
- c.user.set_pref('skills', s)
- flash('Your skills list was successfully updated!')
- redirect('/auth/prefs/user_skills')
-
-class UserContactsController(BaseController):
-
- @expose('jinja:allura:templates/user_contacts.html')
- def index(self, **kw):
- require_authenticated()
- return dict()
-
- @expose()
- @require_post()
- @validate(F.add_socialnetwork_form, error_handler=index)
- def add_social_network(self, **kw):
- require_authenticated()
- c.user.add_socialnetwork(kw['socialnetwork'], kw['accounturl'])
- flash('Your personal contacts were successfully updated!')
- redirect('.')
-
- @expose()
- @require_post()
- @validate(F.remove_socialnetwork_form, error_handler=index)
- def remove_social_network(self, **kw):
- require_authenticated()
- c.user.remove_socialnetwork(kw['socialnetwork'], kw['account'])
- flash('Your personal contacts were successfully updated!')
- redirect('.')
-
- @expose()
- @require_post()
- @validate(F.add_telnumber_form, error_handler=index)
- def add_telnumber(self, **kw):
- require_authenticated()
- c.user.add_telephonenumber(kw['newnumber'])
- flash('Your personal contacts were successfully updated!')
- redirect('.')
-
- @expose()
- @require_post()
- @validate(F.remove_textvalue_form, error_handler=index)
- def remove_telnumber(self, **kw):
- require_authenticated()
- c.user.remove_telephonenumber(kw['oldvalue'])
- flash('Your personal contacts were successfully updated!')
- redirect('.')
-
- @expose()
- @require_post()
- @validate(F.add_website_form, error_handler=index)
- def add_webpage(self, **kw):
- require_authenticated()
- c.user.add_webpage(kw['newwebsite'])
- flash('Your personal contacts were successfully updated!')
- redirect('.')
-
- @expose()
- @require_post()
- @validate(F.remove_textvalue_form, error_handler=index)
- def remove_webpage(self, **kw):
- require_authenticated()
- c.user.remove_webpage(kw['oldvalue'])
- flash('Your personal contacts were successfully updated!')
- redirect('.')
-
- @expose()
- @require_post()
- @validate(F.skype_account_form, error_handler=index)
- def skype_account(self, **kw):
- require_authenticated()
- c.user.set_pref('skypeaccount', kw['skypeaccount'])
- flash('Your personal contacts were successfully updated!')
- redirect('.')
-
-class UserAvailabilityController(BaseController):
-
- @expose('jinja:allura:templates/user_availability.html')
- def index(self, **kw):
- require_authenticated()
- return dict()
-
- @expose()
- @require_post()
- @validate(F.add_timeslot_form, error_handler=index)
- def add_timeslot(self, **kw):
- require_authenticated()
- c.user.add_timeslot(kw['weekday'], kw['starttime'], kw['endtime'])
- flash('Your availability timeslots were successfully updated!')
- redirect('.')
-
- @expose()
- @require_post()
- @validate(F.remove_timeslot_form, error_handler=index)
- def remove_timeslot(self, **kw):
- require_authenticated()
- c.user.remove_timeslot(kw['weekday'], kw['starttime'], kw['endtime'])
- flash('Your availability timeslots were successfully updated!')
- redirect('.')
-
- @expose()
- @require_post()
- @validate(F.add_inactive_period_form, error_handler=index)
- def add_inactive_period(self, **kw):
- require_authenticated()
- c.user.add_inactive_period(kw['startdate'], kw['enddate'])
- flash('Your inactivity periods were successfully updated!')
- redirect('.')
-
- @expose()
- @require_post()
- @validate(F.remove_inactive_period_form, error_handler=index)
- def remove_inactive_period(self, **kw):
- require_authenticated()
- c.user.remove_inactive_period(kw['startdate'], kw['enddate'])
- flash('Your availability timeslots were successfully updated!')
- redirect('.')
-
-class PreferencesController(BaseController):
-
- user_skills = UserSkillsController()
- user_contacts = UserContactsController()
- user_availability = UserAvailabilityController()
-
- @with_trailing_slash
- @expose('jinja:allura:templates/user_preferences.html')
- def index(self, **kw):
- require_authenticated()
- c.form = F.subscription_form
- c.revoke_access = F.oauth_revocation_form
- subscriptions = []
- mailboxes = M.Mailbox.query.find(dict(user_id=c.user._id, is_flash=False))
- mailboxes = list(mailboxes.ming_cursor)
- project_collection = M.Project.query.mapper.collection
- app_collection = M.AppConfig.query.mapper.collection
- projects = dict(
- (p._id, p) for p in project_collection.m.find(dict(
- _id={'$in': [mb.project_id for mb in mailboxes ]})))
- app_index = dict(
- (ac._id, ac) for ac in app_collection.m.find(dict(
- _id={'$in': [mb.app_config_id for mb in mailboxes]})))
-
- for mb in mailboxes:
- project = projects.get(mb.project_id, None)
- app_config = app_index.get(mb.app_config_id, None)
- if project is None:
- mb.m.delete()
- continue
- if app_config is None:
- continue
- subscriptions.append(dict(
- subscription_id=mb._id,
- project_name=project.name,
- mount_point=app_config.options['mount_point'],
- artifact_title=dict(text=mb.artifact_title, href=mb.artifact_url),
- topic=mb.topic,
- type=mb.type,
- frequency=mb.frequency.unit,
- artifact=mb.artifact_index_id,
- subscribed=True))
-
- my_projects = dict((p._id, p) for p in c.user.my_projects())
- my_tools = app_collection.m.find(dict(
- project_id={'$in': my_projects.keys()}))
- for tool in my_tools:
- p_id = tool.project_id
- subscribed = M.Mailbox.subscribed(
- project_id=p_id, app_config_id=tool._id)
- if not subscribed:
- subscriptions.append(dict(
- tool_id=tool._id,
- project_id=p_id,
- project_name=my_projects[p_id].name,
- mount_point=tool.options['mount_point'],
- artifact_title='No subscription',
- topic=None,
- type=None,
- frequency=None,
- artifact=None))
- subscriptions.sort(key=lambda d: (d['project_name'], d['mount_point']))
- api_token = M.ApiToken.query.get(user_id=c.user._id)
provider = plugin.AuthenticationProvider.get(request)
menu = provider.account_navigation()
+ api_token = M.ApiToken.query.get(user_id=c.user._id)
return dict(
- subscriptions=subscriptions,
- api_token=api_token,
- authorized_applications=M.OAuthAccessToken.for_user(c.user),
- menu=menu)
+ menu=menu,
+ api_token=api_token,
+ authorized_applications=M.OAuthAccessToken.for_user(c.user),
+ )
@h.vardec
@expose()
@require_post()
def update(self,
- display_name=None,
addr=None,
new_addr=None,
primary_addr=None,
@@ -562,12 +323,11 @@
new_oid=None,
preferences=None,
**kw):
- require_authenticated()
if config.get('auth.method', 'local') == 'local':
- if display_name is None:
+ if not preferences.get('display_name'):
flash("Display Name cannot be empty.",'error')
redirect('.')
- c.user.set_pref('display_name', display_name)
+ c.user.set_pref('display_name', preferences['display_name'])
for i, (old_a, data) in enumerate(zip(c.user.email_addresses, addr or [])):
obj = c.user.address_object(old_a)
if data.get('delete') or not obj:
@@ -591,6 +351,366 @@
if k == 'results_per_page':
v = int(v)
c.user.set_pref(k, v)
+ redirect('.')
+
+ @expose()
+ @require_post()
+ def gen_api_token(self):
+ tok = M.ApiToken.query.get(user_id=c.user._id)
+ if tok is None:
+ tok = M.ApiToken(user_id=c.user._id)
+ else:
+ tok.secret_key = h.cryptographic_nonce()
+ redirect(request.referer)
+
+ @expose()
+ @require_post()
+ def del_api_token(self):
+ tok = M.ApiToken.query.get(user_id=c.user._id)
+ if tok is None: return
+ tok.delete()
+ redirect(request.referer)
+
+ @expose()
+ @require_post()
+ def revoke_oauth(self, _id=None):
+ tok = M.OAuthAccessToken.query.get(_id=bson.ObjectId(_id))
+ if tok is None:
+ flash('Invalid app ID', 'error')
+ redirect('.')
+ if tok.user_id != c.user._id:
+ flash('Invalid app ID', 'error')
+ redirect('.')
+ tok.delete()
+ flash('Application access revoked')
+ redirect('.')
+
+ @expose()
+ @require_post()
+ @validate(V.NullValidator(), error_handler=index)
+ def change_password(self, **kw):
+ kw = g.theme.password_change_form.to_python(kw, None)
+ ap = plugin.AuthenticationProvider.get(request)
+ try:
+ ap.set_password(c.user, kw['oldpw'], kw['pw'])
+ except wexc.HTTPUnauthorized:
+ flash('Incorrect password', 'error')
+ redirect('.')
+ flash('Password changed')
+ redirect('.')
+
+ @expose()
+ @require_post()
+ def upload_sshkey(self, key=None):
+ ap = plugin.AuthenticationProvider.get(request)
+ try:
+ ap.upload_sshkey(c.user.username, key)
+ except AssertionError, ae:
+ flash('Error uploading key: %s' % ae, 'error')
+ flash('Key uploaded')
+ redirect('.')
+
+class UserInfoController(BaseController):
+
+ def __init__(self, *args, **kwargs):
+ self.skills = UserSkillsController()
+ self.contacts = UserContactsController()
+ self.availability = UserAvailabilityController()
+
+ def _check_security(self):
+ require_authenticated()
+
+ @with_trailing_slash
+ @expose('jinja:allura:templates/user_info.html')
+ def index(self, **kw):
+ provider = plugin.AuthenticationProvider.get(request)
+ menu = provider.account_navigation()
+ return dict(menu=menu)
+
+ @expose()
+ @require_post()
+ @validate(F.change_personal_data_form, error_handler=index)
+ def change_personal_data(self, **kw):
+ require_authenticated()
+ c.user.set_pref('sex', kw['sex'])
+ c.user.set_pref('birthdate', kw.get('birthdate'))
+ localization={'country':kw.get('country'), 'city':kw.get('city')}
+ c.user.set_pref('localization', localization)
+ c.user.set_pref('timezone', kw['timezone'])
+
+ flash('Your personal data was successfully updated!')
+ redirect('.')
+
+class UserSkillsController(BaseController):
+
+ def __init__(self, category=None):
+ self.category = category
+ super(UserSkillsController, self).__init__()
+
+ def _check_security(self):
+ require_authenticated()
+
+ @expose()
+ def _lookup(self, catshortname, *remainder):
+ cat = M.TroveCategory.query.get(shortname=catshortname)
+ return UserSkillsController(category=cat), remainder
+
+ @with_trailing_slash
+ @expose('jinja:allura:templates/user_skills.html')
+ def index(self, **kw):
+ l = []
+ parents = []
+ if kw.get('selected_category') is not None:
+ selected_skill = M.TroveCategory.query.get(trove_cat_id=int(kw.get('selected_category')))
+ elif self.category:
+ selected_skill = self.category
+ else:
+ l = M.TroveCategory.query.find(dict(trove_parent_id=0, show_as_skill=True))
+ selected_skill = None
+ if selected_skill:
+ l = [scat for scat in selected_skill.subcategories
+ if scat.show_as_skill]
+ temp_cat = selected_skill.parent_category
+ while temp_cat:
+ parents = [temp_cat] + parents
+ temp_cat = temp_cat.parent_category
+ provider = plugin.AuthenticationProvider.get(request)
+ menu = provider.account_navigation()
+ return dict(
+ skills_list = l,
+ selected_skill = selected_skill,
+ parents = parents,
+ menu = menu,
+ add_details_fields=(len(l)==0))
+
+ @expose()
+ @require_post()
+ @validate(F.save_skill_form, error_handler=index)
+ def save_skill(self, **kw):
+ trove_id = int(kw.get('selected_skill'))
+ category = M.TroveCategory.query.get(trove_cat_id=trove_id)
+
+ new_skill = dict(
+ category_id=category._id,
+ level=kw.get('level'),
+ comment=kw.get('comment'))
+
+ s = [skill for skill in c.user.skills
+ if str(skill.category_id) != str(new_skill['category_id'])]
+ s.append(new_skill)
+ c.user.set_pref('skills', s)
+ flash('Your skills list was successfully updated!')
+ redirect('..')
+
+ @expose()
+ @require_post()
+ @validate(F.remove_skill_form, error_handler=index)
+ def remove_skill(self, **kw):
+ trove_id = int(kw.get('categoryid'))
+ category = M.TroveCategory.query.get(trove_cat_id=trove_id)
+
+ s = [skill for skill in c.user.skills
+ if str(skill.category_id) != str(category._id)]
+ c.user.set_pref('skills', s)
+ flash('Your skills list was successfully updated!')
+ redirect('..')
+
+class UserContactsController(BaseController):
+
+ def _check_security(self):
+ require_authenticated()
+
+ @with_trailing_slash
+ @expose('jinja:allura:templates/user_contacts.html')
+ def index(self, **kw):
+ provider = plugin.AuthenticationProvider.get(request)
+ menu = provider.account_navigation()
+ return dict(menu=menu)
+
+ @expose()
+ @require_post()
+ @validate(F.add_socialnetwork_form, error_handler=index)
+ def add_social_network(self, **kw):
+ require_authenticated()
+ c.user.add_socialnetwork(kw['socialnetwork'], kw['accounturl'])
+ flash('Your personal contacts were successfully updated!')
+ redirect('.')
+
+ @expose()
+ @require_post()
+ @validate(F.remove_socialnetwork_form, error_handler=index)
+ def remove_social_network(self, **kw):
+ require_authenticated()
+ c.user.remove_socialnetwork(kw['socialnetwork'], kw['account'])
+ flash('Your personal contacts were successfully updated!')
+ redirect('.')
+
+ @expose()
+ @require_post()
+ @validate(F.add_telnumber_form, error_handler=index)
+ def add_telnumber(self, **kw):
+ require_authenticated()
+ c.user.add_telephonenumber(kw['newnumber'])
+ flash('Your personal contacts were successfully updated!')
+ redirect('.')
+
+ @expose()
+ @require_post()
+ @validate(F.remove_textvalue_form, error_handler=index)
+ def remove_telnumber(self, **kw):
+ require_authenticated()
+ c.user.remove_telephonenumber(kw['oldvalue'])
+ flash('Your personal contacts were successfully updated!')
+ redirect('.')
+
+ @expose()
+ @require_post()
+ @validate(F.add_website_form, error_handler=index)
+ def add_webpage(self, **kw):
+ require_authenticated()
+ c.user.add_webpage(kw['newwebsite'])
+ flash('Your personal contacts were successfully updated!')
+ redirect('.')
+
+ @expose()
+ @require_post()
+ @validate(F.remove_textvalue_form, error_handler=index)
+ def remove_webpage(self, **kw):
+ require_authenticated()
+ c.user.remove_webpage(kw['oldvalue'])
+ flash('Your personal contacts were successfully updated!')
+ redirect('.')
+
+ @expose()
+ @require_post()
+ @validate(F.skype_account_form, error_handler=index)
+ def skype_account(self, **kw):
+ require_authenticated()
+ c.user.set_pref('skypeaccount', kw['skypeaccount'])
+ flash('Your personal contacts were successfully updated!')
+ redirect('.')
+
+class UserAvailabilityController(BaseController):
+
+ def _check_security(self):
+ require_authenticated()
+
+ @with_trailing_slash
+ @expose('jinja:allura:templates/user_availability.html')
+ def index(self, **kw):
+ provider = plugin.AuthenticationProvider.get(request)
+ menu = provider.account_navigation()
+ return dict(menu=menu)
+
+ @expose()
+ @require_post()
+ @validate(F.add_timeslot_form, error_handler=index)
+ def add_timeslot(self, **kw):
+ require_authenticated()
+ c.user.add_timeslot(kw['weekday'], kw['starttime'], kw['endtime'])
+ flash('Your availability timeslots were successfully updated!')
+ redirect('.')
+
+ @expose()
+ @require_post()
+ @validate(F.remove_timeslot_form, error_handler=index)
+ def remove_timeslot(self, **kw):
+ require_authenticated()
+ c.user.remove_timeslot(kw['weekday'], kw['starttime'], kw['endtime'])
+ flash('Your availability timeslots were successfully updated!')
+ redirect('.')
+
+ @expose()
+ @require_post()
+ @validate(F.add_inactive_period_form, error_handler=index)
+ def add_inactive_period(self, **kw):
+ require_authenticated()
+ c.user.add_inactive_period(kw['startdate'], kw['enddate'])
+ flash('Your inactivity periods were successfully updated!')
+ redirect('.')
+
+ @expose()
+ @require_post()
+ @validate(F.remove_inactive_period_form, error_handler=index)
+ def remove_inactive_period(self, **kw):
+ require_authenticated()
+ c.user.remove_inactive_period(kw['startdate'], kw['enddate'])
+ flash('Your availability timeslots were successfully updated!')
+ redirect('.')
+
+class SubscriptionsController(BaseController):
+
+ def _check_security(self):
+ require_authenticated()
+
+ @with_trailing_slash
+ @expose('jinja:allura:templates/user_subs.html')
+ def index(self, **kw):
+ c.form = F.subscription_form
+ c.revoke_access = F.oauth_revocation_form
+ subscriptions = []
+ mailboxes = M.Mailbox.query.find(dict(user_id=c.user._id, is_flash=False))
+ mailboxes = list(mailboxes.ming_cursor)
+ project_collection = M.Project.query.mapper.collection
+ app_collection = M.AppConfig.query.mapper.collection
+ projects = dict(
+ (p._id, p) for p in project_collection.m.find(dict(
+ _id={'$in': [mb.project_id for mb in mailboxes ]})))
+ app_index = dict(
+ (ac._id, ac) for ac in app_collection.m.find(dict(
+ _id={'$in': [mb.app_config_id for mb in mailboxes]})))
+
+ for mb in mailboxes:
+ project = projects.get(mb.project_id, None)
+ app_config = app_index.get(mb.app_config_id, None)
+ if project is None:
+ mb.m.delete()
+ continue
+ if app_config is None:
+ continue
+ subscriptions.append(dict(
+ subscription_id=mb._id,
+ project_name=project.name,
+ mount_point=app_config.options['mount_point'],
+ artifact_title=dict(text=mb.artifact_title, href=mb.artifact_url),
+ topic=mb.topic,
+ type=mb.type,
+ frequency=mb.frequency.unit,
+ artifact=mb.artifact_index_id,
+ subscribed=True))
+
+ my_projects = dict((p._id, p) for p in c.user.my_projects())
+ my_tools = app_collection.m.find(dict(
+ project_id={'$in': my_projects.keys()}))
+ for tool in my_tools:
+ p_id = tool.project_id
+ subscribed = M.Mailbox.subscribed(
+ project_id=p_id, app_config_id=tool._id)
+ if not subscribed:
+ subscriptions.append(dict(
+ tool_id=tool._id,
+ project_id=p_id,
+ project_name=my_projects[p_id].name,
+ mount_point=tool.options['mount_point'],
+ artifact_title='No subscription',
+ topic=None,
+ type=None,
+ frequency=None,
+ artifact=None))
+ subscriptions.sort(key=lambda d: (d['project_name'], d['mount_point']))
+ provider = plugin.AuthenticationProvider.get(request)
+ menu = provider.account_navigation()
+ return dict(
+ subscriptions=subscriptions,
+ authorized_applications=M.OAuthAccessToken.for_user(c.user),
+ menu=menu)
+
+ @h.vardec
+ @expose()
+ @require_post()
+ def update(self,
+ preferences=None,
+ **kw):
if 'email_format' in preferences:
c.user.set_pref('email_format', preferences['email_format'])
redirect('.')
@@ -611,77 +731,6 @@
s['subscription_id'].delete()
redirect(request.referer)
- @expose()
- @require_post()
- def gen_api_token(self):
- tok = M.ApiToken.query.get(user_id=c.user._id)
- if tok is None:
- tok = M.ApiToken(user_id=c.user._id)
- else:
- tok.secret_key = h.cryptographic_nonce()
- redirect(request.referer)
-
- @expose()
- @require_post()
- def del_api_token(self):
- tok = M.ApiToken.query.get(user_id=c.user._id)
- if tok is None: return
- tok.delete()
- redirect(request.referer)
-
- @expose()
- @require_post()
- def revoke_oauth(self, _id=None):
- tok = M.OAuthAccessToken.query.get(_id=bson.ObjectId(_id))
- if tok is None:
- flash('Invalid app ID', 'error')
- redirect('.')
- if tok.user_id != c.user._id:
- flash('Invalid app ID', 'error')
- redirect('.')
- tok.delete()
- flash('Application access revoked')
- redirect('.')
-
- @expose()
- @require_post()
- @validate(V.NullValidator(), error_handler=index)
- def change_password(self, **kw):
- kw = g.theme.password_change_form.to_python(kw, None)
- ap = plugin.AuthenticationProvider.get(request)
- try:
- ap.set_password(c.user, kw['oldpw'], kw['pw'])
- except wexc.HTTPUnauthorized:
- flash('Incorrect password', 'error')
- redirect('.')
- flash('Password changed')
- redirect('.')
-
- @expose()
- @require_post()
- @validate(F.change_personal_data_form, error_handler=index)
- def change_personal_data(self, **kw):
- require_authenticated()
- c.user.set_pref('sex', kw['sex'])
- c.user.set_pref('birthdate', kw.get('birthdate'))
- localization={'country':kw.get('country'), 'city':kw.get('city')}
- c.user.set_pref('localization', localization)
- c.user.set_pref('timezone', kw['timezone'])
-
- flash('Your personal data was successfully updated!')
- redirect('.')
-
- @expose()
- @require_post()
- def upload_sshkey(self, key=None):
- ap = plugin.AuthenticationProvider.get(request)
- try:
- ap.upload_sshkey(c.user.username, key)
- except AssertionError, ae:
- flash('Error uploading key: %s' % ae, 'error')
- flash('Key uploaded')
- redirect('.')
-
class OAuthController(BaseController):
@with_trailing_slash