def refresh(self, id): try: context = {'model': model, 'user': c.user, 'session': model.Session} p.toolkit.get_action('harvest_job_create')( context, {'source_id': id, 'run': True} ) h.flash_success( _('Harvest will start shortly. Refresh this page for updates.') ) except p.toolkit.ObjectNotFound: abort(404, _('Harvest source not found')) except p.toolkit.NotAuthorized: abort(401, self.not_auth_message) except HarvestSourceInactiveError: h.flash_error( _( 'Cannot create new harvest jobs on inactive ' 'sources. First, please change the source status ' 'to "active".' ) ) except HarvestJobExists: h.flash_notice( _('A harvest job has already been scheduled for ' 'this source') ) except Exception as e: msg = 'An error occurred: [%s]' % str(e) h.flash_error(msg) h.redirect_to(h.url_for('{0}_admin'.format(DATASET_TYPE_NAME), id=id))
def config(self): items = self._get_config_form_items() data = request.POST if 'save' in data: try: # really? data_dict = logic.clean_dict( dict_fns.unflatten( logic.tuplize_dict( logic.parse_params( request.POST, ignore_keys=CACHE_PARAMETERS)))) del data_dict['save'] data = logic.get_action('config_option_update')( {'user': c.user}, data_dict) except logic.ValidationError, e: errors = e.error_dict error_summary = e.error_summary vars = {'data': data, 'errors': errors, 'error_summary': error_summary, 'form_items': items} return base.render('admin/config.html', extra_vars=vars) h.redirect_to(controller='admin', action='config')
def slo(self): environ = p.toolkit.request.environ # so here I might get either a LogoutResponse or a LogoutRequest client = environ['repoze.who.plugins']['saml2auth'] if 'QUERY_STRING' in environ: saml_resp = p.toolkit.request.GET.get('SAMLResponse', '') saml_req = p.toolkit.request.GET.get('SAMLRequest', '') if saml_req: log.info('SAML REQUEST for logout recieved') get = p.toolkit.request.GET subject_id = environ["repoze.who.identity"]['repoze.who.userid'] headers, success = client.saml_client.do_http_redirect_logout(get, subject_id) h.redirect_to(headers[0][1]) elif saml_resp: ## # fix the cert so that it is on multiple lines ## out = [] ## # if on multiple lines make it a single one ## line = ''.join(saml_resp.split('\n')) ## while len(line) > 64: ## out.append(line[:64]) ## line = line[64:] ## out.append(line) ## saml_resp = '\n'.join(out) ## try: ## res = client.saml_client.logout_request_response( ## saml_resp, ## binding=BINDING_HTTP_REDIRECT ## ) ## except KeyError: ## # return error reply ## pass delete_cookies() h.redirect_to(controller='user', action='logged_out')
def _identify_user_default(self): """ Identifies the user using two methods: a) If they logged into the web interface then repoze.who will set REMOTE_USER. b) For API calls they may set a header with an API key. """ # environ['REMOTE_USER'] is set by repoze.who if it authenticates a # user's cookie. But repoze.who doesn't check the user (still) exists # in our database - we need to do that here. (Another way would be # with an userid_checker, but that would mean another db access. # See: http://docs.repoze.org/who/1.0/narr.html#module-repoze.who\ # .plugins.sql ) c.user = request.environ.get("REMOTE_USER", "") if c.user: c.user = c.user.decode("utf8") c.userobj = model.User.by_name(c.user) if c.userobj is None or not c.userobj.is_active(): # This occurs when a user that was still logged in is deleted, # or when you are logged in, clean db and then restart (or # when you change your username) There is no user object, so # even though repoze thinks you are logged in and your cookie # has ckan_display_name, we need to force user to logout and # login again to get the User object. ev = request.environ if "repoze.who.plugins" in ev: pth = getattr(ev["repoze.who.plugins"]["friendlyform"], "logout_handler_path") h.redirect_to(pth) else: c.userobj = self._get_user_for_apikey() if c.userobj is not None: c.user = c.userobj.name
def delete(self, dataset_id, issue_number): dataset = self._before_dataset(dataset_id) if 'cancel' in request.params: h.redirect_to('issues_show', dataset_id=dataset_id, issue_number=issue_number) if request.method == 'POST': try: toolkit.get_action('issue_delete')( data_dict={'issue_number': issue_number, 'dataset_id': dataset_id} ) except toolkit.NotAuthorized: msg = _('Unauthorized to delete issue {0}'.format( issue_number)) toolkit.abort(401, msg) h.flash_notice( _('Issue {0} has been deleted.'.format(issue_number)) ) h.redirect_to('issues_dataset', dataset_id=dataset_id) else: return render('issues/confirm_delete.html', extra_vars={ 'issue_number': issue_number, 'pkg': dataset, })
def post(self, group_type, is_organization, id=None): set_org(is_organization) context = self._prepare(id) try: _action(u'group_delete')(context, {u'id': id}) if group_type == u'organization': h.flash_notice(_(u'Organization has been deleted.')) elif group_type == u'group': h.flash_notice(_(u'Group has been deleted.')) else: h.flash_notice( _(u'%s has been deleted.') % _(group_type.capitalize())) group_dict = _action(u'group_show')(context, {u'id': id}) except NotAuthorized: base.abort(403, _(u'Unauthorized to delete group %s') % u'') except NotFound: base.abort(404, _(u'Group not found')) except ValidationError as e: h.flash_error(e.error_dict['message']) return h.redirect_to(u'organization.read', id=id) return h.redirect_to(u'{}.read'.format(group_type), id=id) # TODO: Remove g.group_dict = group_dict return h.redirect_to(u'{}.index'.format(group_type))
def abort(self, status_code, detail, headers, comment): # HTTP Status 401 causes a login redirect. We need to prevent this # unless we are actually trying to login. if (status_code == 401 and p.toolkit.request.environ['PATH_INFO'] != '/user/login'): h.redirect_to('saml2_unauthorized') return (status_code, detail, headers, comment)
def login(self): # We can be here either because we are requesting a login (no user) # or we have just been logged in. if not p.toolkit.c.user: # A 401 HTTP Status will cause the login to be triggered return base.abort(401, p.toolkit._('Login required!')) h.redirect_to(controller='user', action='dashboard')
def reset_config(self): '''FIXME: This method is probably not doing what people would expect. It will reset the configuration to values cached when CKAN started. If these were coming from the database during startup, that's the ones that will get applied on reset, not the ones in the ini file. Only after restarting the server and having CKAN reset the values from the ini file (as the db ones are not there anymore) will these be used. ''' if 'cancel' in request.params: h.redirect_to(controller='admin', action='config') if request.method == 'POST': #check against csrf attacks custom_base.csrf_check(self) # remove sys info items for item in self._get_config_form_items(): name = item['name'] model.delete_system_info(name) # reset to values in config app_globals.reset() h.redirect_to(controller='admin', action='config') return base.render('admin/confirm_reset.html')
def form(self): context = {'model': model, 'user': c.user} if not ckan.new_authz.is_authorized('sysadmin', context, {})['success']: base.abort(401, _('Need to be system administrator')) # get one and only one entry from our extlink table entry = model.Session.query(extlinkmodel.ExtLink).first() if not entry: # create the empty entry for the first time entry = extlinkmodel.ExtLink() entry.save() if base.request.method == "POST": data = logic.clean_dict( df.unflatten( logic.tuplize_dict( logic.parse_params(base.request.params) ))) entry.domains = data.get('white-list') entry.message = data.get('message') entry.save() h.flash_success(_('External link changes saved.')) h.redirect_to(controller=self.controller_path, action='form') c.extlinkdata = { 'white-list': entry.domains, 'message': entry.message, 'placeholder': msg_default, } return p.toolkit.render("form.html")
def logged_in(self): # we need to set the language via a redirect lang = session.pop("lang", None) session.save() came_from = request.params.get("came_from", "") # we need to set the language explicitly here or the flash # messages will not be translated. i18n.set_lang(lang) if c.user: context = None data_dict = {"id": c.user} user_dict = get_action("user_show")(context, data_dict) h.flash_success(_("%s is now logged in") % user_dict["display_name"]) if came_from: return h.redirect_to(str(came_from)) return self.me() else: err = _("Login failed. Bad username or password.") if g.openid_enabled: err += _(" (Or if using OpenID, it hasn't been associated " "with a user account.)") if h.asbool(config.get("ckan.legacy_templates", "false")): h.flash_error(err) h.redirect_to(locale=lang, controller="user", action="login", came_from=came_from) else: return self.login(error=err)
def datahub_package_create(context, data_dict): from ckan.logic.auth.create import _check_group_auth if authz.is_sysadmin(context.get('user')): return {'success': True} user = context['user'] if not authz.auth_is_registered_user(): if '/new' in c.environ['PATH_INFO']: h.redirect_to(CREATE_DATASET_HELP_PAGE) else: return {'success': False, 'msg': _('You must login to create a dataset')} check1 = authz.check_config_permission('create_dataset_if_not_in_organization') \ or authz.check_config_permission('create_unowned_dataset') #if not authorized and not a part of any org, redirect to help page on how to join one if not check1 and not authz.has_user_permission_for_some_org(user, 'create_dataset'): if '/new' in c.environ['PATH_INFO']: h.redirect_to(CREATE_DATASET_HELP_PAGE) else: return {'success': False, 'msg': _('User %s not authorized to create packages') % user} check2 = _check_group_auth(context,data_dict) if not check2 and not check1: return {'success': False, 'msg': _('User %s not authorized to edit these groups') % user} # If an organization is given are we able to add a dataset to it? data_dict = data_dict or {} org_id = data_dict.get('organization_id') if org_id and not authz.has_user_permission_for_group_or_org( org_id, user, 'create_dataset'): return {'success': False, 'msg': _('User %s not authorized to add dataset to this organization') % user} return {'success': True}
def datahub_package_create(context, data_dict): from ckan.logic.auth.create import _check_group_auth if new_authz.is_sysadmin(context.get('user')): return {'success': True} user = context['user'] if not new_authz.auth_is_registered_user(): return {'success': False, 'msg': _('You must login to create a dataset')} else: check1 = new_authz.check_config_permission('create_dataset_if_not_in_organization') \ or new_authz.check_config_permission('create_unowned_dataset') if not check1 and not new_authz.has_user_permission_for_some_org(user, 'create_dataset'): h.redirect_to('/pages/requesting-an-organization') if not check1: return {'success': False, 'msg': _('User %s not authorized to create packages') % user} check2 = _check_group_auth(context,data_dict) if not check2: return {'success': False, 'msg': _('User %s not authorized to edit these groups') % user} # If an organization is given are we able to add a dataset to it? data_dict = data_dict or {} org_id = data_dict.get('organization_id') if org_id and not new_authz.has_user_permission_for_group_or_org( org_id, user, 'create_dataset'): return {'success': False, 'msg': _('User %s not authorized to add dataset to this organization') % user} return {'success': True}
def view(self, uuid): """ View object If this is basic HTTP request, this will redirect to the record If the request is for RDF (content negotiation) return the rdf """ if uuid in ABYSSLINE_UUIDS: self.abyssline_object_redirect(uuid) # Is the request for a particular format _format = check_access_header() if _format: return self.rdf(uuid, _format) else: try: # This is a normal HTTP request, so redirect to the object record record, resource = get_record_by_uuid(uuid) except TypeError: pass else: if record: package_id = resource.get_package_id() package = get_action("package_show")(self.context, {"id": package_id}) h.redirect_to( controller="ckanext.nhm.controllers.record:RecordController", action="view", package_name=package["name"], resource_id=resource.id, record_id=record["_id"], ) abort(404, _("Record not found"))
def abyssline_object_redirect(self, uuid): """ Temporary fix to allow abyssline object references to resolve to the temp dataset :param uuid: :return: """ resource_id = config.get("ckanext.nhm.abyssline_resource_id") context = {"model": model, "session": model.Session, "user": c.user or c.author} search_result = get_action("datastore_search")( context, {"resource_id": resource_id, "filters": {"catalogNumber": uuid}} ) try: record = search_result["records"][0] except KeyError: pass else: h.redirect_to( controller="ckanext.nhm.controllers.record:RecordController", action="view", package_name="abyssline", resource_id=resource_id, record_id=record["_id"], ) abort(404, _("Record not found"))
def _save_edit(self, id, context): try: data_dict = logic.clean_dict(unflatten( logic.tuplize_dict(logic.parse_params(request.params)))) context['message'] = data_dict.get('log_message', '') data_dict['id'] = id if data_dict['password1'] and data_dict['password2']: identity = {'login': c.user, 'password': data_dict['old_password']} auth = authenticator.UsernamePasswordAuthenticator() if auth.authenticate(request.environ, identity) != c.user: raise UsernamePasswordError # MOAN: Do I really have to do this here? if 'activity_streams_email_notifications' not in data_dict: data_dict['activity_streams_email_notifications'] = False user = get_action('user_update')(context, data_dict) h.flash_success(_('Profile updated')) h.redirect_to(controller='user', action='read', id=user['name']) except NotAuthorized: abort(401, _('Unauthorized to edit user %s') % id) except NotFound, e: abort(404, _('User not found'))
def request_reset(self): context = {'model': model, 'session': model.Session, 'user': c.user, 'auth_user_obj': c.userobj} try: check_access('request_reset', context) except NotAuthorized: abort(401, _('Unauthorized to request reset password.')) if request.method == 'POST': email = request.params.get('email') users = model.User.by_email(email) if not users: h.flash_error(_('Email not registered: %s') % email) else: try: mailer.send_reset_link(users[0]) h.flash_success(_('Please check your inbox for ' 'a reset code.')) h.redirect_to('/') except mailer.MailerException, e: h.flash_error(_('Could not send reset link: %s') % unicode(e))
def logged_in(self): came_from = request.params.get('came_from', '') if c.user: context = None data_dict = {'id': c.user, 'link_wotkit': True} try: user_dict = get_action('user_show')(context, data_dict) except logic.NotAuthorized as e: return self.login(error=str(e)) h.flash_success(_("%s is now logged in") % user_dict['display_name']) if came_from and "logged_in" not in came_from: """Mark: HACK redirect to ignore the base URL /data. This used to use url_for, but doing so always appends the /data path which we won't want Thus had to change it to redirect_to """ return routes.redirect_to(str(came_from)) return self.me() else: err = _('Login failed. Bad username or password.') if g.openid_enabled: err += _(' (Or if using OpenID, it hasn\'t been associated ' 'with a user account.)') if h.asbool(config.get('ckan.legacy_templates', 'false')): h.flash_error(err) h.redirect_to(locale=lang, controller='user', action='login', came_from=came_from) else: return self.login(error=err)
def logged_in(self): # we need to set the language via a redirect lang = session.pop('lang', None) session.save() came_from = request.params.get('came_from', '') # we need to set the language explicitly here or the flash # messages will not be translated. i18n.set_lang(lang) if c.user: context = None data_dict = {'id': c.user} user_dict = get_action('user_show')(context, data_dict) h.flash_success(_("%s is now logged in") % user_dict['display_name']) if came_from: return h.redirect_to(str(came_from)) return self.me() else: err = _('Login failed. Bad username or password.') if g.openid_enabled: err += _(' (Or if using OpenID, it hasn\'t been associated ' 'with a user account.)') if h.asbool(config.get('ckan.legacy_templates', 'false')): h.flash_error(err) h.redirect_to(locale=lang, controller='user', action='login', came_from=came_from) else: return self.login(error=err)
def report(self, dataset_id, issue_number): dataset = self._before_dataset(dataset_id) if request.method == 'POST': if not c.user: msg = _('You must be logged in to report issues') toolkit.abort(401, msg) try: report_info = toolkit.get_action('issue_report')( data_dict={ 'issue_number': issue_number, 'dataset_id': dataset_id } ) if report_info: # we have this info if it is an admin msgs = [_('Report acknowledged.')] if report_info['abuse_status'] == \ issuemodel.AbuseStatus.abuse.value: msgs.append(_('Marked as abuse/spam.')) msgs.append(_('Issue is visible.') if report_info['visibility'] == 'visible' else _('Issue is invisible to normal users.')) h.flash_success(' '.join(msgs)) else: h.flash_success(_('Issue reported to an administrator')) except toolkit.ValidationError: toolkit.abort(404) except toolkit.ObjectNotFound: toolkit.abort(404) except ReportAlreadyExists, e: h.flash_error(e.message) h.redirect_to('issues_show', dataset_id=dataset_id, issue_number=issue_number)
def _save_new(self, context, group_type=None): try: data_dict = clean_dict(dict_fns.unflatten( tuplize_dict(parse_params(request.params)))) data_dict['type'] = group_type or 'group' context['message'] = data_dict.get('log_message', '') data_dict['users'] = [{'name': c.user, 'capacity': 'admin'}] group = self._action('group_create')(context, data_dict) log.info('::::: Persisting localised metadata locale :::::') lang = get_lang()[0] session = model.Session try: session.add_all([ GroupMultilang(group_id=group.get('id'), name=group.get('name'), field='title', lang=lang, text=group.get('title')), GroupMultilang(group_id=group.get('id'), name=group.get('name'), field='description', lang=lang, text=group.get('description')), ]) session.commit() except Exception, e: # on rollback, the same closure of state # as that of commit proceeds. session.rollback() log.error('Exception occurred while persisting DB objects: %s', e) raise # Redirect to the appropriate _read route for the type of group h.redirect_to(group['type'] + '_read', id=group['name'])
def request_reset(self): context = {'model': model, 'session': model.Session, 'user': c.user, 'auth_user_obj': c.userobj} data_dict = {'id': request.params.get('user')} try: check_access('request_reset', context) except NotAuthorized: abort(401, _('Unauthorized to request reset password.')) if request.method == 'POST': id = request.params.get('user') context = {'model': model, 'user': c.user} data_dict = {'id': id} user_obj = None try: user_dict = get_action('user_show')(context, data_dict) user_obj = context['user_obj'] except NotFound: # Show success regardless of outcome to prevent scanning h.flash_success(_('Please check your inbox for ' 'a reset code.')) if user_obj: try: mailer.send_reset_link(user_obj) h.flash_success(_('Please check your inbox for ' 'a reset code.')) h.redirect_to('/') except mailer.MailerException, e: h.flash_error(_('Could not send reset link: %s') % unicode(e))
def member_delete(self, id): group_type = self._ensure_controller_matches_group_type(id) if 'cancel' in request.params: h.redirect_to(group_type + '_members', id=id) context = {'model': model, 'session': model.Session, 'user': c.user} try: self._check_access('group_member_delete', context, {'id': id}) except NotAuthorized: abort(403, _('Unauthorized to delete group %s members') % '') try: user_id = request.params.get('user') if request.method == 'POST': self._action('group_member_delete')( context, {'id': id, 'user_id': user_id}) h.flash_notice(_('Group member has been deleted.')) h.redirect_to(group_type + '_members', id=id) c.user_dict = self._action('user_show')(context, {'id': user_id}) c.user_id = user_id c.group_id = id except NotAuthorized: abort(403, _('Unauthorized to delete group %s members') % '') except NotFound: abort(404, _('Group not found')) return self._render_template('group/confirm_delete_member.html', group_type)
def me(self, locale=None): if not c.user: h.redirect_to( locale=locale, controller='user', action='login', id=None) user_ref = c.userobj.get_reference_preferred_for_uri() h.redirect_to( locale=locale, controller='user', action='dashboard', id=user_ref)
def me(self, locale=None): if not c.user: h.redirect_to(locale=locale, controller="user", action="login", id=None) user_ref = c.userobj.get_reference_preferred_for_uri() # HO Change - direct users to the search rather than the dashboard # h.redirect_to(locale=locale, controller='user', action='dashboard') h.redirect_to(controller="package", action="search")
def read(self, id, limit=20): group_type = self._ensure_controller_matches_group_type( id.split('@')[0]) context = {'model': model, 'session': model.Session, 'user': c.user, 'schema': self._db_to_form_schema(group_type=group_type), 'for_view': True} data_dict = {'id': id, 'type': group_type} # unicode format (decoded from utf8) c.q = request.params.get('q', '') try: # Do not query for the group datasets when dictizing, as they will # be ignored and get requested on the controller anyway data_dict['include_datasets'] = False c.group_dict = self._action('group_show')(context, data_dict) c.group = context['group'] except (NotFound, NotAuthorized): abort(404, _('Group not found')) # if the user specified a group id, redirect to the group name if data_dict['id'] == c.group_dict['id'] and \ data_dict['id'] != c.group_dict['name']: h.redirect_to(controller=group_type, action='read', id=c.group_dict['name']) self._read(id, limit, group_type) return render(self._read_template(c.group_dict['type']), extra_vars={'group_type': group_type})
def logged_in(self): # redirect if needed came_from = request.params.get('came_from', '') if self._sane_came_from(came_from): return h.redirect_to(str(came_from)) if c.user: context = None data_dict = {'id': c.user} user_dict = get_action('user_show')(context, data_dict) h.flash_success( _("%s is now logged in") % user_dict['display_name']) return self.me() else: err = _('Login failed. Bad username or password.') if g.openid_enabled: err += _(' (Or if using OpenID, it hasn\'t been associated ' 'with a user account.)') if h.asbool(config.get('ckan.legacy_templates', 'false')): h.flash_error(err) h.redirect_to( controller='user', action='login', came_from=came_from) else: return self.login(error=err)
def abyssline_object_redirect(self, uuid, version=None): """ Temporary fix to allow abyssline object references to resolve to the temp dataset. :param uuid: the uuid of the object :param version: the version to get """ resource_id = config.get("ckanext.nhm.abyssline_resource_id") # figure out the rounded version data_dict = { u'resource_id': resource_id, u'version': version, } version = get_action(u'datastore_get_rounded_version')(self.context, data_dict) # search for the record search_data_dict = { 'resource_id': resource_id, 'filters': { 'catalogNumber': uuid } } search_result = get_action('datastore_search')(self.context, search_data_dict) try: record = search_result['records'][0] except KeyError: pass else: h.redirect_to(controller='ckanext.nhm.controllers.record:RecordController', action='view', package_name='abyssline', resource_id=resource_id, record_id=record['_id'], version=version) abort(404, _('Record not found'))
def logout(self): # Do any plugin logout stuff for item in p.PluginImplementations(p.IAuthenticator): item.logout() url = h.url_for(controller='user', action='logged_out_page') h.redirect_to(self._get_repoze_handler('logout_handler_path') + '?came_from=' + url, parse_url=True)
def logged_in(self): # redirect if needed came_from = request.params.get('came_from', '') if c.user: context = None data_dict = {'id': c.user} user_dict = get_action('user_show')(context, data_dict) user_ref = c.userobj.get_reference_preferred_for_uri() if h.url_is_local(came_from) and came_from != '/': return h.redirect_to(str(came_from)) h.redirect_to(locale=None, controller='user', action='dashboard_datasets', id=user_ref) else: err = _('Login failed. Wrong email or password.') if h.asbool(config.get('ckan.legacy_templates', 'false')): h.flash_error(err) h.redirect_to(controller='user', action='login', came_from=came_from) else: return self.login(error=err)
def read(id): context = { u'model': model, u'session': model.Session, u'user': g.user, u'auth_user_obj': g.userobj, u'for_view': True } data_dict = { u'id': id, u'user_obj': g.userobj, u'include_datasets': True, u'include_num_followers': True } # FIXME: line 331 in multilingual plugins expects facets to be defined. # any ideas? g.fields = [] extra_vars = _extra_template_variables(context, data_dict) if extra_vars is None: return h.redirect_to(u'user.login') return base.render(u'user/read.html', extra_vars)
def unfollow(id): u'''Stop following this user.''' context = { u'model': model, u'session': model.Session, u'user': g.user, u'auth_user_obj': g.userobj } data_dict = {u'id': id, u'include_num_followers': True} try: logic.get_action(u'unfollow_user')(context, data_dict) user_dict = logic.get_action(u'user_show')(context, data_dict) h.flash_success( _(u'You are no longer following {0}').format( user_dict[u'display_name'])) except (logic.NotFound, logic.NotAuthorized) as e: error_message = e.message h.flash_error(error_message) except logic.ValidationError as e: error_message = (e.error_summary or e.message or e.error_dict) h.flash_error(error_message) return h.redirect_to(u'user.read', id=id)
def post(self, group_type: str, is_organization: bool, id: Optional[str] = None) -> Response: set_org(is_organization) context = self._prepare(id) try: _action(u'group_delete')(context, {u'id': id}) group_label = h.humanize_entity_type( u'group', group_type, u'has been deleted') or _(u'Group') h.flash_notice( _(u'%s has been deleted.') % _(group_label)) except NotAuthorized: base.abort(403, _(u'Unauthorized to delete group %s') % u'') except NotFound: base.abort(404, _(u'Group not found')) except ValidationError as e: base.abort(403, _(e.error_dict['message'])) return h.redirect_to(u'{}.index'.format(group_type))
def post(self, id): context = {u'model': model} data_dict = logic.clean_dict( dictization_functions.unflatten( logic.tuplize_dict(logic.parse_params(request.form)))) data_dict[u'user'] = id try: token = logic.get_action(u'api_token_create')( context, data_dict )[u'token'] except logic.NotAuthorized: base.abort(403, _(u'Unauthorized to create API tokens.')) except logic.ValidationError as e: errors = e.error_dict error_summary = e.error_summary return self.get(id, data_dict, errors, error_summary) copy_btn = dom_tags.button(dom_tags.i(u'', { u'class': u'fa fa-copy' }), { u'type': u'button', u'class': u'btn btn-default btn-xs', u'data-module': u'copy-into-buffer', u'data-module-copy-value': ensure_str(token) }) h.flash_success( _( u"API Token created: <code style=\"word-break:break-all;\">" u"{token}</code> {copy}<br>" u"Make sure to copy it now, " u"you won't be able to see it again!" ).format(token=ensure_str(token), copy=copy_btn), True ) return h.redirect_to(u'user.api_tokens', id=id)
def read(id: str) -> Union[Response, str]: context = cast( Context, { u'model': model, u'session': model.Session, u'user': current_user.name, u'auth_user_obj': current_user, u'for_view': True }) data_dict: dict[str, Any] = { u'id': id, u'user_obj': current_user, u'include_datasets': True, u'include_num_followers': True } # FIXME: line 331 in multilingual plugins expects facets to be defined. # any ideas? g.fields = [] extra_vars = _extra_template_variables(context, data_dict) if extra_vars is None: return h.redirect_to(u'user.login') return base.render(u'user/read.html', extra_vars)
def delete(id: str) -> Union[Response, Any]: u'''Delete user with id passed as parameter''' context = cast( Context, { u'model': model, u'session': model.Session, u'user': current_user.name, u'auth_user_obj': current_user }) data_dict = {u'id': id} try: logic.get_action(u'user_delete')(context, data_dict) except logic.NotAuthorized: msg = _(u'Unauthorized to delete user with id "{user_id}".') base.abort(403, msg.format(user_id=id)) if current_user.is_authenticated: if current_user.id == id: # type: ignore return logout() else: user_index = h.url_for(u'user.index') return h.redirect_to(user_index)
def get(self, data=None, errors=None, error_summary=None): context = self._prepare() themes = logic.get_action(u'theme_list')(context, {}) if not themes.get(u'data', []): h.flash_notice(_(u'Create a theme first then sub-theme')) return h.redirect_to(u'theme.index') theme_options = [] for theme in themes.get(u'data', []): opt = {u'text': theme[u'title'], u'value': theme[u'id']} theme_options.append(opt) form_vars = { u'data': data or {}, u'theme_options': theme_options, u'errors': errors or {}, u'error_summary': error_summary or {} } extra_vars = {u'form': base.render(new_sub_theme_form, form_vars)} return base.render(u'sub_theme/new.html', extra_vars)
def delete_view(id): try: context = {'model': model, 'user': tk.c.user} context['clear_source'] = tk.request.params.get('clear', '').lower() in ( u'true', u'1', ) tk.get_action('harvest_source_delete')(context, {'id': id}) if context['clear_source']: h.flash_success(_('Harvesting source successfully cleared')) else: h.flash_success(_('Harvesting source successfully inactivated')) return h.redirect_to( h.url_for('{0}_admin'.format(DATASET_TYPE_NAME), id=id)) except tk.ObjectNotFound: return tk.abort(404, _('Harvest source not found')) except tk.NotAuthorized: return tk.abort(401, _not_auth_message())
def follow(package_type, id): """Start following this dataset. """ context = { u'model': model, u'session': model.Session, u'user': g.user, u'auth_user_obj': g.userobj } data_dict = {u'id': id} try: get_action(u'follow_dataset')(context, data_dict) package_dict = get_action(u'package_show')(context, data_dict) except ValidationError as e: error_message = (e.message or e.error_summary or e.error_dict) h.flash_error(error_message) except NotAuthorized as e: h.flash_error(e.message) else: h.flash_success( _(u"You are now following {0}").format(package_dict[u'title'])) return h.redirect_to(u'dataset.read', id=id)
def post(self, group_type, is_organization, id=None): set_org(is_organization) context = self._prepare(id, is_organization) try: data_dict = clean_dict( dict_fns.unflatten(tuplize_dict(parse_params(request.form)))) context['message'] = data_dict.get(u'log_message', u'') data_dict['id'] = context['id'] context['allow_partial_update'] = True group = _action(u'group_update')(context, data_dict) if id != group['name']: _force_reindex(group) except (NotFound, NotAuthorized) as e: base.abort(404, _(u'Group not found')) except dict_fns.DataError: base.abort(400, _(u'Integrity Error')) except ValidationError as e: errors = e.error_dict error_summary = e.error_summary return self.get(id, group_type, is_organization, data_dict, errors, error_summary) return h.redirect_to(group[u'type'] + u'.read', id=group[u'name'])
def download(package_type: str, id: str, resource_id: str, filename: Optional[str] = None ) -> Union[Response, WerkzeugResponse]: """ Provides a direct download by either redirecting the user to the url stored or downloading an uploaded file directly. """ context = cast(Context, { u'model': model, u'session': model.Session, u'user': current_user.name, u'auth_user_obj': current_user }) try: rsc = get_action(u'resource_show')(context, {u'id': resource_id}) get_action(u'package_show')(context, {u'id': id}) except NotFound: return base.abort(404, _(u'Resource not found')) except NotAuthorized: return base.abort(403, _(u'Not authorized to download resource')) if rsc.get(u'url_type') == u'upload': upload = uploader.get_resource_uploader(rsc) filepath = upload.get_path(rsc[u'id']) resp = flask.send_file(filepath, download_name=filename) if rsc.get('mimetype'): resp.headers['Content-Type'] = rsc['mimetype'] signals.resource_download.send(resource_id) return resp elif u'url' not in rsc: return base.abort(404, _(u'No download is available')) return h.redirect_to(rsc[u'url'])
def map_location(self, id, resource_id): context = None resource = toolkit.get_action('resource_show')(context, {'id': resource_id}) # Validate the resource before pushing the job log_writer = LocationMapperLogWriter(resource['id']) column_name = resource.get('location_column', None) or ast.literal_eval(resource.get('_extras', '{}')).get('location_column', None) column_type = resource.get('location_type', None) or ast.literal_eval(resource.get('_extras', '{}')).get('location_type', None) is_name = column_type is not None and column_type.endswith('_name') if column_name and column_type: # Enqueue the location_mapping task job = ckan.plugins.toolkit.enqueue_job(location_mapper_job, [], {u'resource_id': resource['id'], u'column_name': column_name, u'column_type': column_type, u'is_name': is_name, u'username': ckan.common.c.userobj.name}, title='map_location_async') log_writer.info("Queued location mapping (Job ID:" + job.id + ")") else: if column_name is None: log_writer.error("Location column not specified for resource", state="Something went wrong") if column_type is None: log_writer.error("Location type not specified for resource", state="Something went wrong") return helpers.redirect_to(controller='ckanext.string_to_location.controller:LocationMapperController', action='resource_location_mapping_status', id=id, resource_id=resource_id)
def delete(id): '''Delete the post with the given ID. ''' context = _get_context() try: check_access('post_delete', context, {'id': id}) except logic.NotAuthorized: base.abort( 403, _('You do not have sufficient privileges ' 'to delete this post.')) return try: get_action('post_delete')(context, { 'id': id, }) except logic.NotFound: base.abort(404, _('That post does not exist.')) return except logic.NotAuthorized: base.abort( 403, _('You do not have sufficient privileges ' 'to delete this post.')) return except Exception as e: log.error('Failed to delete post %s. Error: %s', id, str(e)) log.exception(e) base.abort( 500, _('Unexpected error has occured while trying ' 'to delete this post.')) return return h.redirect_to(u'news.index')
def edit_datastore_commands(self): if 'datapusher' in config.get('ckan.plugins', ''): plugin_command = '--plugin=ckan datapusher submit_all' elif 'xloader' in config.get('ckan.plugins', ''): plugin_command = '--plugin=ckanext-xloader xloader submit all' else: return h.redirect_to('home') self._authorize() if request.method == 'POST': from ckanext.gobar_theme.helpers.cron import create_or_update_cron_job params = parse_params(request.POST) config_dict = self._read_config() schedule_hour = params.get('schedule-hour').strip() schedule_minute = params.get('schedule-minute').strip() config_dict['datastore'] = { 'schedule-hour': schedule_hour, 'schedule-minute': schedule_minute } self._set_config(config_dict) # Creamos el cron job, reemplazando el anterior si ya existía command = self._generate_datastore_command(plugin_command) comment = 'datastore - submit_all' create_or_update_cron_job(command, hour=schedule_hour, minute=schedule_minute, comment=comment) return base.render('config/config_18_datastore_commands.html')
def follow(id: str, group_type: str, is_organization: bool) -> Response: u'''Start following this group.''' set_org(is_organization) context = cast( Context, { u'model': model, u'session': model.Session, u'user': current_user.name } ) data_dict = {u'id': id} try: get_action(u'follow_group')(context, data_dict) group_dict = get_action(u'group_show')(context, data_dict) h.flash_success( _(u"You are now following {0}").format(group_dict['title'])) id = group_dict['name'] except ValidationError as e: error_message = (e.message or e.error_summary or e.error_dict) h.flash_error(error_message) except NotAuthorized as e: h.flash_error(e.message) return h.redirect_to(u'group.read', id=id)
def generate_apikey(id=None): u'''Cycle the API key of a user''' context = { u'model': model, u'session': model.Session, u'user': g.user, u'auth_user_obj': g.userobj, } if id is None: if g.userobj: id = g.userobj.id else: base.abort(400, _(u'No user specified')) data_dict = {u'id': id} try: result = logic.get_action(u'user_generate_apikey')(context, data_dict) except logic.NotAuthorized: base.abort(403, _(u'Unauthorized to edit user %s') % u'') except logic.NotFound: base.abort(404, _(u'User not found')) h.flash_success(_(u'Profile updated')) return h.redirect_to(u'user.read', id=result[u'name'])
def RateDataset(self): context = { 'model': model, 'session': model.Session, 'user': c.user or c.author, 'auth_user_obj': c.userobj, 'for_view': True } rating = logic.clean_dict( df.unflatten( logic.tuplize_dict(logic.parse_params(base.request.params)))) logging.warning(rating) dataset_id = rating['dataset_id'] rating = rating['value'] data_dict = { 'rating': rating, 'dataset_id': dataset_id, 'user_id': c.userobj.id } new_rating(context, data_dict) return h.redirect_to(controller='package', action='read', id=dataset_id)
def logged_out(): # redirect if needed came_from = request.params.get(u'came_from', u'') if h.url_is_local(came_from): return h.redirect_to(str(came_from)) return h.redirect_to(u'user.logged_out_page')
def post(self, id, group_type, is_organization, data=None): set_org(is_organization) context = self._prepare(group_type) data_dict = {u'id': id, u'type': group_type} try: check_access(u'bulk_update_public', context, {u'org_id': id}) # Do not query for the group datasets when dictizing, as they will # be ignored and get requested on the controller anyway data_dict['include_datasets'] = False group_dict = _action(u'group_show')(context, data_dict) group = context['group'] except NotFound: base.abort(404, _(u'Group not found')) except NotAuthorized: base.abort(403, _(u'User %r not authorized to edit %s') % (g.user, id)) if not group_dict['is_organization']: # FIXME: better error raise Exception(u'Must be an organization') # TODO: Remove # ckan 2.9: Adding variables that were removed from c object for # compatibility with templates in existing extensions g.group_dict = group_dict g.group = group # use different form names so that ie7 can be detected form_names = set([ u"bulk_action.public", u"bulk_action.delete", u"bulk_action.private" ]) actions_in_form = set(request.form.keys()) actions = form_names.intersection(actions_in_form) # ie7 puts all buttons in form params but puts submitted one twice for key, value in request.form.to_dict().iteritems(): if value in [u'private', u'public']: action = key.split(u'.')[-1] break else: # normal good browser form submission action = actions.pop().split(u'.')[-1] # process the action first find the datasets to perform the action on. # they are prefixed by dataset_ in the form data datasets = [] for param in request.form: if param.startswith(u'dataset_'): datasets.append(param[8:]) action_functions = { u'private': u'bulk_update_private', u'public': u'bulk_update_public', u'delete': u'bulk_update_delete', } data_dict = {u'datasets': datasets, u'org_id': group_dict['id']} try: get_action(action_functions[action])(context, data_dict) except NotAuthorized: base.abort(403, _(u'Not authorized to perform bulk update')) return h.redirect_to(u'{}.bulk_process'.format(group_type), id=id)
def history(id, group_type, is_organization): return h.redirect_to(u'group.activity', id=id)
def post(self, package_type): # The staged add dataset used the new functionality when the dataset is # partially created so we need to know if we actually are updating or # this is a real new. context = self._prepare() is_an_update = False ckan_phase = request.form.get(u'_ckan_phase') try: data_dict = clean_dict( dict_fns.unflatten(tuplize_dict(parse_params(request.form))) ) except dict_fns.DataError: return base.abort(400, _(u'Integrity Error')) try: if ckan_phase: # prevent clearing of groups etc context[u'allow_partial_update'] = True # sort the tags if u'tag_string' in data_dict: data_dict[u'tags'] = _tag_string_to_list( data_dict[u'tag_string'] ) if data_dict.get(u'pkg_name'): is_an_update = True # This is actually an update not a save data_dict[u'id'] = data_dict[u'pkg_name'] del data_dict[u'pkg_name'] # don't change the dataset state data_dict[u'state'] = u'draft' # this is actually an edit not a save pkg_dict = get_action(u'package_update')( context, data_dict ) # redirect to add dataset resources url = h.url_for( u'{}_resource.new'.format(package_type), id=pkg_dict[u'name'] ) return h.redirect_to(url) # Make sure we don't index this dataset if request.form[u'save'] not in [ u'go-resource', u'go-metadata' ]: data_dict[u'state'] = u'draft' # allow the state to be changed context[u'allow_state_change'] = True data_dict[u'type'] = package_type context[u'message'] = data_dict.get(u'log_message', u'') pkg_dict = get_action(u'package_create')(context, data_dict) if ckan_phase: # redirect to add dataset resources url = h.url_for( u'{}_resource.new'.format(package_type), id=pkg_dict[u'name'] ) return h.redirect_to(url) return _form_save_redirect( pkg_dict[u'name'], u'new', package_type=package_type ) except NotAuthorized: return base.abort(403, _(u'Unauthorized to read package')) except NotFound as e: return base.abort(404, _(u'Dataset not found')) except SearchIndexError as e: try: exc_str = text_type(repr(e.args)) except Exception: # We don't like bare excepts exc_str = text_type(str(e)) return base.abort( 500, _(u'Unable to add package to search index.') + exc_str ) except ValidationError as e: errors = e.error_dict error_summary = e.error_summary if is_an_update: # we need to get the state of the dataset to show the stage we # are on. pkg_dict = get_action(u'package_show')(context, data_dict) data_dict[u'state'] = pkg_dict[u'state'] return EditView().get( package_type, data_dict[u'id'], data_dict, errors, error_summary ) data_dict[u'state'] = u'none' return self.get(package_type, data_dict, errors, error_summary)
def read(package_type, id): context = { u'model': model, u'session': model.Session, u'user': g.user, u'for_view': True, u'auth_user_obj': g.userobj } data_dict = {u'id': id, u'include_tracking': True} activity_id = request.params.get(u'activity_id') # check if package exists try: pkg_dict = get_action(u'package_show')(context, data_dict) pkg = context[u'package'] except (NotFound, NotAuthorized): return base.abort(404, _(u'Dataset not found')) g.pkg_dict = pkg_dict g.pkg = pkg # NB templates should not use g.pkg, because it takes no account of # activity_id if activity_id: # view an 'old' version of the package, as recorded in the # activity stream try: activity = get_action(u'activity_show')( context, {u'id': activity_id, u'include_data': True}) except NotFound: base.abort(404, _(u'Activity not found')) except NotAuthorized: base.abort(403, _(u'Unauthorized to view activity data')) current_pkg = pkg_dict try: pkg_dict = activity[u'data'][u'package'] except KeyError: base.abort(404, _(u'Dataset not found')) if u'id' not in pkg_dict or u'resources' not in pkg_dict: log.info(u'Attempt to view unmigrated or badly migrated dataset ' '{} {}'.format(id, activity_id)) base.abort(404, _(u'The detail of this dataset activity is not ' 'available')) if pkg_dict[u'id'] != current_pkg[u'id']: log.info(u'Mismatch between pkg id in activity and URL {} {}' .format(pkg_dict[u'id'], current_pkg[u'id'])) # the activity is not for the package in the URL - don't allow # misleading URLs as could be malicious base.abort(404, _(u'Activity not found')) # The name is used lots in the template for links, so fix it to be # the current one. It's not displayed to the user anyway. pkg_dict[u'name'] = current_pkg[u'name'] # Earlier versions of CKAN only stored the package table in the # activity, so add a placeholder for resources, or the template # will crash. pkg_dict.setdefault(u'resources', []) # if the user specified a package id, redirect to the package name if data_dict['id'] == pkg_dict['id'] and \ data_dict['id'] != pkg_dict['name']: return h.redirect_to(u'{}.read'.format(package_type), id=pkg_dict['name'], activity_id=activity_id) # can the resources be previewed? for resource in pkg_dict[u'resources']: resource_views = get_action(u'resource_view_list')( context, { u'id': resource[u'id'] } ) resource[u'has_views'] = len(resource_views) > 0 package_type = pkg_dict[u'type'] or package_type _setup_template_variables(context, {u'id': id}, package_type=package_type) template = _get_pkg_template(u'read_template', package_type) try: return base.render( template, { u'dataset_type': package_type, u'pkg_dict': pkg_dict, u'pkg': pkg, # NB deprecated - it is the current version of # the dataset, so ignores activity_id u'is_activity_archive': bool(activity_id), } ) except TemplateNotFound as e: msg = _( u"Viewing datasets of type \"{package_type}\" is " u"not supported ({file_!r}).".format( package_type=package_type, file_=e.message ) ) return base.abort(404, msg) assert False, u"We should never get here"
def history(package_type, id): return h.redirect_to(u'{}.activity'.format(package_type), id=id)
def _redirect_to(self, *args, **kw): ''' wrapper to ensue the correct controller is used ''' if self.group_type == 'organization' and 'controller' in kw: kw['controller'] = 'organization' return h.redirect_to(*args, **kw)
def abort(self, status_code, detail, headers, comment): log.info('abort') if (status_code == 401 and (toolkit.request.environ['PATH_INFO'] != '/user/login' or toolkit.request.environ['PATH_INFO'] != '/user/_logout')): h.redirect_to('cas_unauthorized', message = detail) return (status_code, detail, headers, comment)
def identify(self): log.info('identify') #set language as default to be able to translate flash messages lang = request.environ.get('CKAN_LANG') if lang and lang=='sk': i18n.set_lang('sk') c = toolkit.c environ = toolkit.request.environ user = environ.get('REMOTE_USER', '') log.info('environ user %s', user) if user: identity = environ.get("repoze.who.identity", {}) user_data = identity.get("attributes", {}) ticket = identity.get("ticket", '') user_id = identity.get("repoze.who.userid") if not (user_data or user_id): log.info("redirect to logged_out") delete_cookies() return h.redirect_to(controller='user', action='logged_out') if not user_data: user_ticket = pylons.session.get('ckanext-cas-ticket', '') if user_ticket: if is_ticket_valid(user_ticket): c.userobj = model.User.get(user_id) else: log.info("redirect to logged_out") environ['REMOTE_USER'] = None environ['repoze.who.identity'] = None delete_cookies() h.flash_notice(toolkit._('You were logged out in another app')) return #h.redirect_to(controller='home', action='index') else: c.userobj = model.User.get(user_id) else: subject_id = user_data['Subject.UPVSIdentityID'][0] actor_id = user_data['Actor.UPVSIdentityID'][0] success = insert_entry(ticket, subject_id, actor_id) if not success: log.info("same ticket in DB - consistency error") pylons.session['ckanext-cas-ticket'] = ticket pylons.session.save() self._create_user(user_data, 'Actor') if actor_id!=subject_id: self._create_user(user_data, 'Subject') log.debug('jedna sa o zastupovanie subjectu %s actorom %s', subject_id, actor_id) spr_roles = user_data.get('SPR.Roles','') if self._subject_is_org(subject_id) and not 'MOD-R-PO' in spr_roles: identity["repoze.who.userid"] = actor_id pylons.session['ckanext-cas-actorid'] = subject_id pylons.session.save() c.userobj = model.User.get(actor_id) h.flash_notice(toolkit._('You are not allowed to act as {0} in data.gov.sk').format(user_data['Subject.FormattedName'][0])) else: identity["repoze.who.userid"] = subject_id pylons.session['ckanext-cas-actorid'] = actor_id pylons.session.save() c.userobj = model.User.get(subject_id) else: c.userobj = model.User.get(subject_id) #set c.user -> CKAN logic log.debug('c.userobj: %s',c.userobj) c.user = c.userobj.name if user_data: spr_roles = user_data.get('SPR.Roles','') subject_id = user_data['Subject.UPVSIdentityID'][0] actor_id = user_data['Actor.UPVSIdentityID'][0] log.debug("SPR roles: %s", spr_roles) pylons.session['ckanext-cas-roles'] = spr_roles pylons.session.save() if 'MOD-R-PO' in spr_roles: org_id = user_data['Subject.UPVSIdentityID'][0] org_name = user_data.get('Subject.Username',user_data['Subject.UPVSIdentityID'])[0] org_title = user_data['Subject.FormattedName'][0] self.create_organization(org_id, org_name, org_title) if c.user: toolkit.get_action('auditlog_send')(data_dict={'event_name' : 'user_login', 'subject' : user_data['Subject.UPVSIdentityID'][0], 'authorized_user' : user_data['Actor.UPVSIdentityID'][0], 'description' : 'User login to CKAN from IP {0}'.format(environ.get('REMOTE_ADDR', '')), 'object_reference' : 'UserID://' + user_data['Subject.UPVSIdentityID'][0], 'debug_level' : 2, 'error_code' : 0}) else: toolkit.get_action('auditlog_send')(data_dict={'event_name' : 'user_login', 'subject' : user_data['Subject.UPVSIdentityID'][0], 'authorized_user' : user_data['Actor.UPVSIdentityID'][0], 'description' : 'User login to CKAN from IP {0}'.format(environ.get('REMOTE_ADDR', '')), 'object_reference' : 'UserID://' + user_data['Subject.UPVSIdentityID'][0], 'debug_level' : 1, 'error_code' : 1}) else: delete_session_items()
def history(self, id): group_type = self._ensure_controller_matches_group_type(id) if 'diff' in request.params or 'selected1' in request.params: try: params = { 'id': request.params.getone('group_name'), 'diff': request.params.getone('selected1'), 'oldid': request.params.getone('selected2'), } except KeyError: if 'group_name' in dict(request.params): id = request.params.getone('group_name') c.error = \ _('Select two revisions before doing the comparison.') else: params['diff_entity'] = 'group' h.redirect_to(controller='revision', action='diff', **params) context = { 'model': model, 'session': model.Session, 'user': c.user, 'schema': self._db_to_form_schema() } data_dict = {'id': id} try: c.group_dict = self._action('group_show')(context, data_dict) c.group_revisions = self._action('group_revision_list')(context, data_dict) #TODO: remove # Still necessary for the authz check in group/layout.html c.group = context['group'] except (NotFound, NotAuthorized): abort(404, _('Group not found')) format = request.params.get('format', '') if format == 'atom': # Generate and return Atom 1.0 document. from webhelpers.feedgenerator import Atom1Feed feed = Atom1Feed( title=_(u'CKAN Group Revision History'), link=self._url_for_this_controller(action='read', id=c.group_dict['name']), description=_(u'Recent changes to CKAN Group: ') + c.group_dict['display_name'], language=unicode(get_lang()), ) for revision_dict in c.group_revisions: revision_date = h.date_str_to_datetime( revision_dict['timestamp']) try: dayHorizon = int(request.params.get('days')) except: dayHorizon = 30 dayAge = (datetime.datetime.now() - revision_date).days if dayAge >= dayHorizon: break if revision_dict['message']: item_title = u'%s' % revision_dict['message'].\ split('\n')[0] else: item_title = u'%s' % revision_dict['id'] item_link = h.url_for(controller='revision', action='read', id=revision_dict['id']) item_description = _('Log message: ') item_description += '%s' % (revision_dict['message'] or '') item_author_name = revision_dict['author'] item_pubdate = revision_date feed.add_item( title=item_title, link=item_link, description=item_description, author_name=item_author_name, pubdate=item_pubdate, ) feed.content_type = 'application/atom+xml' return feed.writeString('utf-8') return render(self._history_template(group_type), extra_vars={'group_type': group_type})
def _redirect_to_this_controller(self, *args, **kw): ''' wrapper around redirect_to but it adds in this request's controller (so that it works for Organization or other derived controllers)''' kw['controller'] = request.environ['pylons.routes_dict']['controller'] return h.redirect_to(*args, **kw)
def post(self): self._prepare() id = request.form.get(u'user') if id in (None, u''): h.flash_error(_(u'Email is required')) return h.redirect_to(u'/user/reset') log.info(u'Password reset requested for user "{}"'.format(id)) context = {u'model': model, u'user': g.user, u'ignore_auth': True} user_objs = [] # Usernames cannot contain '@' symbols if u'@' in id: # Search by email address # (You can forget a user id, but you don't tend to forget your # email) user_list = logic.get_action(u'user_list')(context, {u'email': id}) if user_list: # send reset emails for *all* user accounts with this email # (otherwise we'd have to silently fail - we can't tell the # user, as that would reveal the existence of accounts with # this email address) for user_dict in user_list: # This is ugly, but we need the user object for the mailer, # and user_list does not return them logic.get_action(u'user_show')(context, { u'id': user_dict[u'id'] }) user_objs.append(context[u'user_obj']) else: # Search by user name # (this is helpful as an option for a user who has multiple # accounts with the same email address and they want to be # specific) try: logic.get_action(u'user_show')(context, {u'id': id}) user_objs.append(context[u'user_obj']) except logic.NotFound: pass if not user_objs: log.info( u'User requested reset link for unknown user: {}'.format(id)) for user_obj in user_objs: log.info(u'Emailing reset link to user: {}'.format(user_obj.name)) try: # FIXME: How about passing user.id instead? Mailer already # uses model and it allow to simplify code above mailer.send_reset_link(user_obj) except mailer.MailerException as e: # SMTP is not configured correctly or the server is # temporarily unavailable h.flash_error( _(u'Error sending the email. Try again later ' 'or contact an administrator for help')) log.exception(e) return h.redirect_to(u'home.index') # always tell the user it succeeded, because otherwise we reveal # which accounts exist or not h.flash_success( _(u'A reset link has been emailed to you ' '(unless the account specified does not exist)')) return h.redirect_to(u'home.index')
def me(): route = u'dashboard.index' if g.user else u'user.login' return h.redirect_to(route)