def logged_in(self):
        # we need to set the language via a redirect
        lang = session.pop('lang', None)
        session.save()

        # we need to set the language explicitly here or the flash
        # messages will not be translated.
        i18n.set_lang(lang)

        if c.user:
            is_new = False
            is_sysadmin = new_authz.is_sysadmin(c.user)

            # Retrieve information about the current user
            context = {'model': model, 'session': model.Session,
                   'user': c.user or c.author,
                   'schema': schema.user_new_form_schema()}
            data_dict = {'id': c.user}

            user_dict = get_action('user_show')(context, data_dict)

            # This check is not needed (or correct) for sys admins
            if not is_sysadmin:

                # Get all organizations and all groups the user belongs to
                orgs_q = model.Session.query(model.Group) \
                    .filter(model.Group.is_organization == True) \
                    .filter(model.Group.state == 'active')
                q = model.Session.query(model.Member) \
                    .filter(model.Member.table_name == 'user') \
                    .filter(model.Member.table_id == user_dict['id'])

                group_ids = []
                for row in q.all():
                    group_ids.append(row.group_id)

                if not group_ids:
                    is_new = True
                else:
                    orgs_q = orgs_q.filter(model.Group.id.in_(group_ids))

                    orgs_list = model_dictize.group_list_dictize(orgs_q.all(), context)

                    if len(orgs_list) == 0:
                        is_new = True

            h.flash_success(_("<p><strong>Note</strong></p>"
                "<p>%s is now logged in</p>") %
                user_dict['display_name'], allow_html=True)

            if is_new:
                return h.redirect_to(controller='ckanext.canada.controller:CanadaController',
                                         action='view_new_user', locale=lang)
            else:
                return h.redirect_to(controller='package',
                    action='search', locale=lang)
        else:
            h.flash_error(_('Login failed. Bad username or password.'))
            return h.redirect_to(controller='user',
                action='login', locale=lang)
    def upload(self, id):
        package_type = self._get_package_type(id)
        geno = get_geno(package_type)
        lc = ckanapi.LocalCKAN(username=c.user)
        dataset = lc.action.package_show(id=id)
        try:
            if request.POST['xls_update'] == '':
                raise BadExcelData('You must provide a valid file')

            _process_upload_file(
                lc,
                dataset,
                request.POST['xls_update'].file,
                geno)

            h.flash_success(_(
                "Your file was successfully uploaded into the central system."
                ))

            redirect(h.url_for(controller='package', action='read', id=id))
        except BadExcelData, e:
            org = lc.action.organization_show(id=dataset['owner_org'])
            return self.preview_table(
                resource_name=dataset['resources'][0]['name'],
                owner_org=org['name'],
                errors=[e.message])
Example #3
0
        def action_add_form(users_or_authz_groups):
            # The user is attempting to set new roles for a named user
            new_user = request.params.get('new_user_name')
            # this is the list of roles whose boxes were ticked
            checked_roles = [ a for (a,b) in request.params.items() if (b == u'on')]
            # this is the list of all the roles that were in the submitted form
            submitted_roles = [ a for (a,b) in request.params.items() if (b == u'submitted')]

            # from this we can make a dictionary of the desired states
            # i.e. true for the ticked boxes, false for the unticked
            desired_roles = {}
            for r in submitted_roles:
                desired_roles[r]=False
            for r in checked_roles:
                desired_roles[r]=True

            # again, in order to avoid either creating a role twice or deleting one which is
            # non-existent, we need to get the users' current roles (if any)
  
            current_uors = get_userobjectroles()

            if users_or_authz_groups=='users':
                current_roles = [uor.role for uor in current_uors if ( uor.user and uor.user.name == new_user )]
                user_object = model.User.by_name(new_user)
                if user_object==None:
                    # The submitted user does not exist. Bail with flash message
                    h.flash_error('unknown user:'******'authz_groups':
                current_roles = [uor.role for uor in current_uors if ( uor.authorized_group and uor.authorized_group.name == new_user )]
                user_object = model.AuthorizationGroup.by_name(new_user)
                if user_object==None:
                    # The submitted user does not exist. Bail with flash message
                    h.flash_error('unknown authorization group:' + str (new_user))
                else:
                    # Whenever our desired state is different from our current state, change it.
                    for (r,val) in desired_roles.items():
                        if val:
                            if (r not in current_roles):
                                model.add_authorization_group_to_role(user_object, r, group)
                        else:
                            if (r in current_roles):
                                model.remove_authorization_group_from_role(user_object, r, group)
                    h.flash_success("Authorization Group Added")

            else:
                assert False, "shouldn't be here"

            # and finally commit all these changes to the database
            model.repo.commit_and_remove()
Example #4
0
        def action_add_form(users_or_authz_groups):
            # The user is attempting to set new roles for a named user
            new_user = request.params.get('new_user_name')
            # this is the list of roles whose boxes were ticked
            checked_roles = [ a for (a,b) in request.params.items() if (b == u'on')]
            # this is the list of all the roles that were in the submitted form
            submitted_roles = [ a for (a,b) in request.params.items() if (b == u'submitted')]

            # from this we can make a dictionary of the desired states
            # i.e. true for the ticked boxes, false for the unticked
            desired_roles = {}
            for r in submitted_roles:
                desired_roles[r]=False
            for r in checked_roles:
                desired_roles[r]=True

            # again, in order to avoid either creating a role twice or deleting one which is
            # non-existent, we need to get the users' current roles (if any)
  
            current_uors = get_userobjectroles()

            if users_or_authz_groups=='users':
                current_roles = [uor.role for uor in current_uors if ( uor.user and uor.user.name == new_user )]
                user_object = model.User.by_name(new_user)
                if user_object==None:
                    # The submitted user does not exist. Bail with flash message
                    h.flash_error('unknown user:'******'authz_groups':
                current_roles = [uor.role for uor in current_uors if ( uor.authorized_group and uor.authorized_group.name == new_user )]
                user_object = model.AuthorizationGroup.by_name(new_user)
                if user_object==None:
                    # The submitted user does not exist. Bail with flash message
                    h.flash_error('unknown authorization group:' + str (new_user))
                else:
                    # Whenever our desired state is different from our current state, change it.
                    for (r,val) in desired_roles.items():
                        if val:
                            if (r not in current_roles):
                                model.add_authorization_group_to_role(user_object, r, pkg)
                        else:
                            if (r in current_roles):
                                model.remove_authorization_group_from_role(user_object, r, pkg)
                    h.flash_success("Authorization Group Added")

            else:
                assert False, "shouldn't be here"

            # and finally commit all these changes to the database
            model.repo.commit_and_remove()
    def delete_record(self, id):
        lc = ckanapi.LocalCKAN(username=c.user)
        filters = {}
        package_type = self._get_package_type(id)
        for f in primary_key_fields(package_type):
           filters[f['datastore_id']] = request.POST.get(f['datastore_id'], '')

        package = lc.action.package_show(id=id)
        result = lc.action.datastore_search(
            resource_id=package['resources'][0]['id'],
            filters=filters,
            rows=2)  # only need two to know if there are multiple matches
        records = result['records']

        x_vars = {'filters': filters, 'action': 'edit'}
        if not records:
            x_vars['delete_errors'] = [_('No matching records found')]
        elif len(records) > 1:
            x_vars['delete_errors'] = [_('Multiple matching records found')]

        if 'delete_errors' in x_vars:
            c.pkg_dict = package
            return render(self._edit_template(package_type), extra_vars=x_vars)

        # XXX: can't avoid the race here with the existing datastore API.
        # datastore_delete doesn't support _id filters
        lc.action.datastore_delete(
            resource_id=package['resources'][0]['id'],
            filters=filters,
            )
        h.flash_success(_(
            "Record deleted."
            ))

        redirect(h.url_for(controller='package', action='read', id=id))
Example #6
0
    def delete(self, id):
        """Provide a delete action, but only for UKLP datasets"""
        from ckan.lib.search import SearchIndexError
        context = {
            'model': model,
            'session': model.Session,
            'user': c.user,
        }

        pkg_dict = get_action('package_show')(context, {'id':id}) # has side-effect of populating context.get('package')

        if request.params: # POST
            if 'cancel' in request.params:
                h.redirect_to(controller='package', action='read', id=id)
            elif 'delete' in request.params:
                try:
                    package_name = pkg_dict['name']
                    get_action('package_delete')(context, {'id':id})
                    h.flash_success(_('Successfully deleted package.'))
                    self._form_save_redirect(package_name, 'edit')
                except NotAuthorized:
                    abort(401, _('Unauthorized to delete package %s') % id)
                except ObjectNotFound, e:
                    abort(404, _('Package not found'))
                except DataError:
                    abort(400, _(u'Integrity Error'))
                except SearchIndexError, e:
                    abort(500, _(u'Unable to update search index.') + repr(e.args))
Example #7
0
    def delete(self, id):
        """Provide a delete action, but only for UKLP datasets"""
        from ckan.lib.search import SearchIndexError
        context = {
            'model': model,
            'session': model.Session,
            'user': c.user,
        }

        pkg_dict = get_action('package_show')(context, {
            'id': id
        })  # has side-effect of populating context.get('package')

        if request.params:  # POST
            if 'cancel' in request.params:
                h.redirect_to(controller='package', action='read', id=id)
            elif 'delete' in request.params:
                try:
                    package_name = pkg_dict['name']
                    get_action('package_delete')(context, {'id': id})
                    h.flash_success(_('Successfully deleted package.'))
                    self._form_save_redirect(package_name, 'edit')
                except NotAuthorized:
                    abort(401, _('Unauthorized to delete package %s') % id)
                except ObjectNotFound, e:
                    abort(404, _('Package not found'))
                except DataError:
                    abort(400, _(u'Integrity Error'))
                except SearchIndexError, e:
                    abort(500,
                          _(u'Unable to update search index.') + repr(e.args))
Example #8
0
def validate_resource_edit(self,
                           id,
                           resource_id,
                           data=None,
                           errors=None,
                           error_summary=None):
    '''
    Intercept save_edit
    Replace author, maintainer, maintainer_email
    '''
    if 'validation_schema' in request.POST and 'format' in request.POST:
        resource_format = request.POST.getone('format')
        validation_schema = request.POST.getone('validation_schema')
        if resource_format == 'CSV' and validation_schema and validation_schema != '':
            schema_url = plugin.generate_download_url(id, validation_schema)
            data_url = plugin.generate_download_url(id, resource_id)
            validation_url = "http://goodtables.okfnlabs.org/api/run?format=csv&schema={0}&data={1}&row_limit=100000&report_limit=1000&report_type=grouped".format(
                schema_url, data_url)
            req = requests.get(validation_url, verify=False)
            if req.status_code == requests.codes.ok:
                response_text = json.loads(req.text)
                if response_text['success']:
                    h.flash_success(
                        "CSV was validated successfully against the selected schema"
                    )
                else:
                    h.flash_error(
                        "CSV was NOT validated against the selected schema")

    return RESOURCE_EDIT(self, id, resource_id, data, errors, error_summary)
Example #9
0
 def success(self, label=None):
     label = request.params.get('label', label)
     h.flash_success('Upload successful')
     c.file_url = h.url_for('storage_file',
                            label=label,
                            qualified=True)
     c.upload_url = h.url_for('storage_upload')
     return render('storage/success.html')
 def resource_edit(self, id, resource_id, data=None, errors=None,
                   error_summary=None):
     try:
         return super(CanadaDatasetController, self).resource_edit(
             id, resource_id, data, errors, error_summary)
     except HTTPFound:
         h.flash_success(_(u'Resource updated.'))
         # resource read page is unfinished, return to dataset page
         h.redirect_to(controller='package', action='read', id=id)
 def abort_harvest_job(self, harvest_job_id):
     try:
         toolkit.get_action('harvest_job_abort')(None, {
             "id": harvest_job_id
         })
         h.flash_success(_('Harvest job ID %s - aborted' % harvest_job_id))
     except Exception, e:
         h.flash_error(
             _('ERROR aborting harvest job ID %s' % harvest_job_id))
Example #12
0
 def success(self, label=None):
     label=request.params.get('label', label)
     h.flash_success('Upload successful')
     c.file_url = h.url_for('storage_file',
             label=label,
             qualified=True
             )
     c.upload_url = h.url_for('storage_upload')
     return render('storage/success.html')
Example #13
0
 def create_request(self, pkg_id):
     pkg = Package.get(pkg_id)
     user = c.userobj if c.userobj else None
     if user:
         req = KataAccessRequest(user.id, pkg.id)
         req.save()
         url = h.url_for(controller='package', action='read', id=pkg_id)
         h.flash_success(_("You now requested editor rights to package %s" % pkg.name))
         redirect(url)
     else:
         url = h.url_for(controller='package', action='read', id=pkg_id)
         h.flash_error(_("Please log in!"))
         redirect(url)
Example #14
0
 def unlock_access(self, id):
     q = model.Session.query(KataAccessRequest)
     q = q.filter_by(id=id)
     req = q.first()
     if req:
         user = User.get(req.user_id)
         pkg = Package.get(req.pkg_id)
         add_user_to_role(user, 'editor', pkg)
         url = h.url_for(controller='package', action='read', id=req.pkg_id)
         h.flash_success(_("%s now has editor rights to package %s" % (user.name, pkg.name)))
         req.delete()
         meta.Session.commit()
         redirect(url)
     else:
         h.flash_error(_("No such request found!"))
         redirect('/')
Example #15
0
 def follow(self, id):
     '''Start following this group.'''
     context = {'model': model,
                'session': model.Session,
                'user': c.user or c.author}
     data_dict = {'id': id}
     try:
         get_action('follow_group')(context, data_dict)
         h.flash_success(_("You are now following {0}").format(id))
     except ValidationError as e:
         error_message = (e.extra_msg or e.message or e.error_summary
                 or e.error_dict)
         h.flash_error(error_message)
     except NotAuthorized as e:
         h.flash_error(e.extra_msg)
     h.redirect_to(controller='group', action='read', id=id)
    def package_delete(self, pkg_id):
        h.flash_success(_(
            '<strong>Note</strong><br> The dataset has been removed from'
            ' the Open Government Portal. <br/> The record may re-appear'
            ' if it is re-harvested or updated. Please ensure that the'
            ' record is deleted and purged from the source catalogue in'
            ' order to prevent it from reappearing.'
            ),
            allow_html=True
        )
        lc = LocalCKAN(username=c.user)
        lc.action.package_delete(id=pkg_id)

        return h.redirect_to(
            controller='package',
            action='search'
        )
    def package_undelete(self, pkg_id):
        h.flash_success(_(
            '<strong>Note</strong><br> The record has been restored.'),
            allow_html=True
        )

        lc = LocalCKAN(username=c.user)
        lc.action.package_patch(
            id=pkg_id,
            state='active'
        )

        return h.redirect_to(
            controller='package',
            action='read',
            id=pkg_id
        )
    def delete(self, id):
        """Provide a delete ('withdraw') action, but only for UKLP datasets"""
        from ckan.lib.search import SearchIndexError
        context = {
            'model': model,
            'session': model.Session,
            'user': c.user,
        }

        try:
            pkg_dict = get_action('package_show')(context, {
                'id': id
            })  # has side-effect of populating context.get('package')
        except NotAuthorized:
            abort(401, 'Not authorized to delete package')
        except ObjectNotFound:
            abort(404, 'Dataset not found')

        if request.params:  # POST
            if 'cancel' in request.params:
                h.redirect_to(controller='package', action='read', id=id)
            elif 'delete' in request.params:
                try:
                    package_name = pkg_dict['name']
                    get_action('package_delete')(context, {'id': id})
                    is_uklp = get_from_flat_dict(pkg_dict['extras'],
                                                 'UKLP') == 'True'
                    if is_uklp:
                        action = 'withdrawn'
                        resource_type = get_from_flat_dict(
                            pkg_dict['extras'], 'resource-type') + ' record'
                    else:
                        action = 'deleted'
                        resource_type = 'dataset'
                    h.flash_success('Successfully %s %s.' \
                                    % (action, resource_type))
                    self._form_save_redirect(package_name, 'edit')
                except NotAuthorized:
                    abort(401, _('Unauthorized to delete package %s') % id)
                except ObjectNotFound, e:
                    abort(404, _('Package not found'))
                except DataError:
                    abort(400, _(u'Integrity Error'))
                except SearchIndexError, e:
                    abort(500,
                          _(u'Unable to update search index.') + repr(e.args))
Example #19
0
    def _send_application(self, group, reason):
        from genshi.template.text import NewTextTemplate

        if not reason:
            h.flash_error(
                _("There was a problem with your submission, \
                             please correct it and try again"))
            errors = {"reason": ["No reason was supplied"]}
            return self.apply(group.id,
                              errors=errors,
                              error_summary=action.error_summary(errors))

        admins = group.members_of_type(model.User, 'admin').all()
        recipients = [(u.fullname,u.email) for u in admins] if admins else \
                     [(config.get('ckan.admin.name', "CKAN Administrator"),
                       config.get('ckan.admin.email', None), )]

        if not recipients:
            h.flash_error(
                _("There is a problem with the system configuration"))
            errors = {"reason": ["No group administrator exists"]}
            return self.apply(group.id,
                              data=data,
                              errors=errors,
                              error_summary=action.error_summary(errors))

        extra_vars = {'group': group, 'requester': c.userobj, 'reason': reason}
        email_msg = render("organizations/email/join_publisher_request.txt",
                           extra_vars=extra_vars,
                           loader_class=NewTextTemplate)

        try:
            for (name, recipient) in recipients:
                mailer.mail_recipient(name, recipient, "Publisher request",
                                      email_msg)
        except:
            h.flash_error(
                _("There is a problem with the system configuration"))
            errors = {"reason": ["No mail server was found"]}
            return self.apply(group.id,
                              errors=errors,
                              error_summary=action.error_summary(errors))

        h.flash_success(_("Your application has been submitted"))
        h.redirect_to('publisher_read', id=group.name)
 def _form_save_redirect(self, pkgname, action):
     '''This redirects the user to the CKAN package/read page,
     unless there is request parameter giving an alternate location,
     perhaps an external website.
     @param pkgname - Name of the package just edited
     @param action - What the action of the edit was
     '''
     assert action in ('new', 'edit')
     if action == 'new':
         msg = _('<span class="new-dataset">Your catalog has been created.</span>')
         h.flash_success(msg, allow_html=True)
     url = request.params.get('return_to') or \
           config.get('package_%s_return_url' % action)
     if url:
         url = url.replace('<NAME>', pkgname)
     else:
         url = h.url_for(controller='package', action='read', id=pkgname)
     redirect(url)        
Example #21
0
    def _send_application( self, group, reason  ):
        from genshi.template.text import NewTextTemplate

        if not reason:
            h.flash_error(_("There was a problem with your submission, \
                             please correct it and try again"))
            errors = {"reason": ["No reason was supplied"]}
            return self.apply(group.id, errors=errors,
                              error_summary=action.error_summary(errors))

        admins = group.members_of_type( model.User, 'admin' ).all()
        recipients = [(u.fullname,u.email) for u in admins] if admins else \
                     [(config.get('ckan.admin.name', "CKAN Administrator"),
                       config.get('ckan.admin.email', None), )]

        if not recipients:
            h.flash_error(_("There is a problem with the system configuration"))
            errors = {"reason": ["No group administrator exists"]}
            return self.apply(group.id, data=data, errors=errors,
                              error_summary=action.error_summary(errors))

        extra_vars = {
            'group'    : group,
            'requester': c.userobj,
            'reason'   : reason
        }
        email_msg = render("organizations/email/join_publisher_request.txt",
                           extra_vars=extra_vars,
                           loader_class=NewTextTemplate)

        try:
            for (name,recipient) in recipients:
                mailer.mail_recipient(name,
                               recipient,
                               "Publisher request",
                               email_msg)
        except:
            h.flash_error(_("There is a problem with the system configuration"))
            errors = {"reason": ["No mail server was found"]}
            return self.apply(group.id, errors=errors,
                              error_summary=action.error_summary(errors))

        h.flash_success(_("Your application has been submitted"))
        h.redirect_to( 'publisher_read', id=group.name)
    def logged_in(self):
        # we need to set the language via a redirect

        # Lang is not being retrieved properly by the Babel i18n lib in
        # this redirect, so using this clunky workaround for now.
        lang = session.pop('lang', None)
        if lang is None:
            came_from = request.params.get('came_from', '')
            if came_from.startswith('/fr'):
                lang = 'fr'
            else:
                lang = 'en'

        session.save()

        # 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(
                _('<strong>Note</strong><br>{0} is now logged in').format(
                    user_dict['display_name']
                ),
                allow_html=True
            )

            notice_no_access()

            return h.redirect_to(
                controller='ckanext.canada.controller:CanadaController',
                action='home',
                locale=lang)
        else:
            h.flash_error(_('Login failed. Bad username or password.'))
            return h.redirect_to(
                controller='user',
                action='login', locale=lang
            )
Example #23
0
 def unfollow(self, id):
     '''Stop following this group.'''
     context = {'model': model,
                'session': model.Session,
                'user': c.user or c.author}
     data_dict = {'id': id}
     try:
         get_action('unfollow_group')(context, data_dict)
         group_dict = get_action('group_show')(context, data_dict)
         h.flash_success(_("You are no longer following {0}").format(
             group_dict['title']))
     except ValidationError as e:
         error_message = (e.extra_msg or e.message or e.error_summary
                 or e.error_dict)
         h.flash_error(error_message)
     except (NotFound, NotAuthorized) as e:
         error_message = e.extra_msg or e.message
         h.flash_error(error_message)
     h.redirect_to(controller='group', action='read', id=id)
    def contact(self, name=None):
        """
        This action allows users to create an issue by filling in a contact
        form.
        """
        import ckan.model as model
        from ckanext.redmine.client import RedmineClient

        print name
        extra_vars = {"data": {}, "errors": {}}

        client = RedmineClient(name)
        c.categories = client.load_categories()
        c.name = name

        if request.method == 'POST':
            data = clean_dict(
                unflatten(tuplize_dict(parse_params(request.POST))))
            context = {
                'model': model,
                'session': model.Session,
                'user': c.user
            }

            # Create the issue with the data we were passed.
            try:
                newid = get_action('issue_create')(context, data)
                if newid is None:
                    self._save_on_fail(data)
                    h.flash_success(
                        _('Thank you for contacting us'.format(newid)))
                else:
                    h.flash_success(
                        _('Thank you for contacting us, please quote #{0} in future correspondence'
                          .format(newid)))

                h.redirect_to(str(data.get('referer', '/')))
            except ValidationError, e:
                extra_vars["errors"] = e.error_dict
                extra_vars["error_summary"] = e.error_summary
                extra_vars["data"] = data
                c.category_id = data.get('category', '')
Example #25
0
    def delete(self, id):
        """Provide a delete ('withdraw') action, but only for UKLP datasets"""
        from ckan.lib.search import SearchIndexError
        context = {
            'model': model,
            'session': model.Session,
            'user': c.user,
        }

        try:
            pkg_dict = get_action('package_show')(context, {'id':id}) # has side-effect of populating context.get('package')
        except NotAuthorized:
            abort(401, 'Not authorized to delete package')
        except ObjectNotFound:
            abort(404, 'Dataset not found')

        if request.params: # POST
            if 'cancel' in request.params:
                h.redirect_to(controller='package', action='read', id=id)
            elif 'delete' in request.params:
                try:
                    package_name = pkg_dict['name']
                    get_action('package_delete')(context, {'id':id})
                    is_uklp = get_from_flat_dict(pkg_dict['extras'], 'UKLP') == 'True'
                    if is_uklp:
                        action = 'withdrawn'
                        resource_type = get_from_flat_dict(pkg_dict['extras'], 'resource-type') + ' record'
                    else:
                        action = 'deleted'
                        resource_type = 'dataset'
                    h.flash_success('Successfully %s %s.' \
                                    % (action, resource_type))
                    self._form_save_redirect(package_name, 'edit')
                except NotAuthorized:
                    abort(401, _('Unauthorized to delete package %s') % id)
                except ObjectNotFound, e:
                    abort(404, _('Package not found'))
                except DataError:
                    abort(400, _(u'Integrity Error'))
                except SearchIndexError, e:
                    abort(500, _(u'Unable to update search index.') + repr(e.args))
Example #26
0
 def _form_save_redirect(self, pkgname, action):
     '''This redirects the user to the CKAN package/read page,
     unless there is request parameter giving an alternate location,
     perhaps an external website.
     @param pkgname - Name of the package just edited
     @param action - What the action of the edit was
     '''
     assert action in ('new', 'edit')
     if action == 'new':
         msg = _('<span class="new-dataset">Congratulations, your dataset has been created. ' \
                 '<a href="%s">Upload or link ' \
                 'some data now &raquo;</a></span>')
         msg = msg % h.url_for(controller='package', action='edit',
                 id=pkgname, anchor='section-resources')
         h.flash_success(msg,allow_html=True)
     url = request.params.get('return_to') or \
           config.get('package_%s_return_url' % action)
     if url:
         url = url.replace('<NAME>', pkgname)
     else:
         url = h.url_for(controller='package', action='read', id=pkgname)
     redirect(url)        
Example #27
0
 def unfollow(self, id):
     '''Stop following this group.'''
     context = {
         'model': model,
         'session': model.Session,
         'user': c.user or c.author
     }
     data_dict = {'id': id}
     try:
         get_action('unfollow_group')(context, data_dict)
         group_dict = get_action('group_show')(context, data_dict)
         h.flash_success(
             _("You are no longer following {0}").format(
                 group_dict['title']))
     except ValidationError as e:
         error_message = (e.extra_msg or e.message or e.error_summary
                          or e.error_dict)
         h.flash_error(error_message)
     except (NotFound, NotAuthorized) as e:
         error_message = e.extra_msg or e.message
         h.flash_error(error_message)
     h.redirect_to(controller='group', action='read', id=id)
Example #28
0
 def _form_save_redirect(self, pkgname, action):
     '''This redirects the user to the CKAN package/read page,
     unless there is request parameter giving an alternate location,
     perhaps an external website.
     @param pkgname - Name of the package just edited
     @param action - What the action of the edit was
     '''
     assert action in ('new', 'edit')
     if action == 'new':
         msg = _('<span class="new-dataset">Congratulations, your dataset has been created. ' \
                 '<a href="%s">Upload or link ' \
                 'some data now &raquo;</a></span>')
         msg = msg % h.url_for(controller='package', action='edit',
                 id=pkgname, anchor='section-resources')
         h.flash_success(msg,allow_html=True)
     url = request.params.get('return_to') or \
           config.get('package_%s_return_url' % action)
     if url:
         url = url.replace('<NAME>', pkgname)
     else:
         url = h.url_for(controller='package', action='read', id=pkgname)
     redirect(url)        
Example #29
0
    def contact(self, name=None):
        """
        This action allows users to create an issue by filling in a contact
        form.
        """
        import ckan.model as model
        from ckanext.redmine.client import RedmineClient

        print name
        extra_vars = {
            "data": {},
            "errors": {}
        }

        client = RedmineClient(name)
        c.categories = client.load_categories()
        c.name = name

        if request.method == 'POST':
            data = clean_dict(unflatten(tuplize_dict(parse_params(request.POST))))
            context = {'model': model, 'session': model.Session,
                       'user': c.user}

            # Create the issue with the data we were passed.
            try:
                newid = get_action('issue_create')(context, data)
                if newid is None:
                    self._save_on_fail(data)
                    h.flash_success(_('Thank you for contacting us'.format(newid)))
                else:
                    h.flash_success(_('Thank you for contacting us, please quote #{0} in future correspondence'.format(newid)))

                h.redirect_to(str(data.get('referer', '/')))
            except ValidationError, e:
                extra_vars["errors"] = e.error_dict
                extra_vars["error_summary"] = e.error_summary
                extra_vars["data"] = data
                c.category_id = data.get('category','')
Example #30
0
    def logged_in(self):
        # we need to set the language via a redirect
        lang = session.pop("lang", None)
        session.save()

        # 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(
                _("<p><strong>Note</strong></p>" "<p>%s is now logged in</p>") % user_dict["display_name"],
                allow_html=True,
            )
            return h.redirect_to(controller="package", action="search", locale=lang)
        else:
            h.flash_error(_("Login failed. Bad username or password."))
            return h.redirect_to(controller="user", action="login", locale=lang)
Example #31
0
    def upload(self, id):
        package_type = self._get_package_type(id)
        geno = get_geno(package_type)
        lc = ckanapi.LocalCKAN(username=c.user)
        dataset = lc.action.package_show(id=id)
        try:
            if request.POST['xls_update'] == '':
                raise BadExcelData('You must provide a valid file')

            _process_upload_file(lc, dataset, request.POST['xls_update'].file,
                                 geno)

            h.flash_success(
                _("Your file was successfully uploaded into the central system."
                  ))

            redirect(h.url_for(controller='package', action='read', id=id))
        except BadExcelData, e:
            org = lc.action.organization_show(id=dataset['owner_org'])
            return self.preview_table(
                resource_name=dataset['resources'][0]['name'],
                owner_org=org['name'],
                errors=[e.message])
Example #32
0
    def delete_record(self, id, resource_id):
        lc = ckanapi.LocalCKAN(username=c.user)
        filters = {}
        res = lc.action.resource_show(id=resource_id)
        for f in recombinant_primary_key_fields(res['name']):
           filters[f['datastore_id']] = request.POST.get(f['datastore_id'], '')

        result = lc.action.datastore_search(
            resource_id=resource_id,
            filters=filters,
            rows=2)  # only need two to know if there are multiple matches
        records = result['records']

        x_vars = {'filters': filters, 'action': 'edit'}
        if not records:
            x_vars['delete_errors'] = [_('No matching records found')]
        elif len(records) > 1:
            x_vars['delete_errors'] = [_('Multiple matching records found')]

        if 'delete_errors' in x_vars:
            c.pkg_dict = dataset = lc.action.package_show(id=id)
            return render('recombinant/resource_edit.html',
                extra_vars=dict(x_vars, dataset=dataset, resource=res))

        # XXX: can't avoid the race here with the existing datastore API.
        # datastore_delete doesn't support _id filters
        lc.action.datastore_delete(
            resource_id=resource_id,
            filters=filters,
            )
        h.flash_success(_(
            "Record deleted."
            ))

        redirect(h.url_for(
            controller='ckanext.recombinant.controller:PreviewController',
            action='preview_table', id=id, resource_id=resource_id))
Example #33
0
    def delete(self, id):
        """Provide a delete ('withdraw') action, but only for UKLP datasets"""
        from ckan.lib.search import SearchIndexError

        context = {"model": model, "session": model.Session, "user": c.user}

        try:
            pkg_dict = get_action("package_show")(
                context, {"id": id}
            )  # has side-effect of populating context.get('package')
        except NotAuthorized:
            abort(401, "Not authorized to delete package")

        if request.params:  # POST
            if "cancel" in request.params:
                h.redirect_to(controller="package", action="read", id=id)
            elif "delete" in request.params:
                try:
                    package_name = pkg_dict["name"]
                    get_action("package_delete")(context, {"id": id})
                    is_uklp = get_from_flat_dict(pkg_dict["extras"], "UKLP") == "True"
                    if is_uklp:
                        action = "withdrawn"
                        resource_type = get_from_flat_dict(pkg_dict["extras"], "resource-type") + " record"
                    else:
                        action = "deleted"
                        resource_type = "dataset"
                    h.flash_success("Successfully %s %s." % (action, resource_type))
                    self._form_save_redirect(package_name, "edit")
                except NotAuthorized:
                    abort(401, _("Unauthorized to delete package %s") % id)
                except ObjectNotFound, e:
                    abort(404, _("Package not found"))
                except DataError:
                    abort(400, _(u"Integrity Error"))
                except SearchIndexError, e:
                    abort(500, _(u"Unable to update search index.") + repr(e.args))
    def logged_in(self):
        # we need to set the language via a redirect
        lang = session.pop('lang', None)
        session.save()

        # 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(_("<p><strong>Note</strong></p>"
                "<p>%s is now logged in</p>") %
                user_dict['display_name'], allow_html=True)
            return h.redirect_to(controller='package',
                action='search', locale=lang)
        else:
            h.flash_error(_('Login failed. Bad username or password.'))
            return h.redirect_to(controller='user',
                action='login', locale=lang)
Example #35
0
    def upload(self, id):
        package_type = self._get_package_type(id)
        geno = get_geno(package_type)
        lc = ckanapi.LocalCKAN(username=c.user)
        dataset = lc.action.package_show(id=id)
        try:
            if request.POST['xls_update'] == '':
                raise BadExcelData('You must provide a valid file')

            _process_upload_file(
                lc,
                dataset,
                request.POST['xls_update'].file,
                geno)

            h.flash_success(_(
                "Your file was successfully uploaded into the central system."
                ))

            redirect(h.url_for(controller='package', action='read', id=id))
        except BadExcelData, e:
            x_vars = {'errors': [e.message], 'action': 'edit'}
            c.pkg_dict = dataset
            return render(self._edit_template(package_type), extra_vars=x_vars)
Example #36
0
    def delete_records(self, id, resource_id):
        lc = ckanapi.LocalCKAN(username=c.user)
        filters = {}

        x_vars = {'filters': filters, 'action': 'edit'}
        pkg = lc.action.package_show(id=id)
        res = lc.action.resource_show(id=resource_id)
        org = lc.action.organization_show(id=pkg['owner_org'])

        dataset = lc.action.recombinant_show(
            dataset_type=pkg['type'], owner_org=org['name'])

        def delete_error(err):
            return render('recombinant/resource_edit.html',
                extra_vars={
                    'delete_errors':[err],
                    'dataset':dataset,
                    'resource':res,
                    'organization':org,
                    'filters':filters,
                    'action':'edit'})

        form_text = request.POST.get('bulk-delete', '')
        if not form_text:
            return delete_error(_('Required field'))

        pk_fields = recombinant_primary_key_fields(res['name'])

        ok_records = []
        ok_filters = []
        records = iter(form_text.split('\n'))
        for r in records:
            r = r.rstrip('\r')
            def record_fail(err):
                # move bad record to the top of the pile
                filters['bulk-delete'] = '\n'.join(
                    [r] + list(records) + ok_records)
                return delete_error(err)

            split_on = '\t' if '\t' in r else ','
            fields = [f for f in r.split(split_on)]
            if len(fields) != len(pk_fields):
                return record_fail(_('Wrong number of fields, expected {num}')
                    .format(num=len(pk_fields)))

            filters.clear()
            for f, pkf in zip(fields, pk_fields):
                filters[pkf['datastore_id']] = f
            try:
                result = lc.action.datastore_search(
                    resource_id=resource_id,
                    filters=filters,
                    limit=2)
            except ValidationError:
                return record_fail(_('Invalid fields'))
            found = result['records']
            if not found:
                return record_fail(_('No matching records found "%s"') %
                    u'", "'.join(fields))
            if len(found) > 1:
                return record_fail(_('Multiple matching records found'))

            if r not in ok_records:
                ok_records.append(r)
                ok_filters.append(dict(filters))

        if 'cancel' in request.POST:
            return render('recombinant/resource_edit.html',
                extra_vars={
                    'delete_errors':[],
                    'dataset':dataset,
                    'resource':res,
                    'organization':org,
                    'filters':{'bulk-delete':u'\n'.join(ok_records)},
                    'action':'edit'})
        if not 'confirm' in request.POST:
            return render('recombinant/confirm_delete.html',
                extra_vars={
                    'dataset':dataset,
                    'resource':res,
                    'num': len(ok_records),
                    'bulk_delete': u'\n'.join(ok_records
                        # extra blank is needed to prevent field
                        # from being completely empty
                        + ([''] if '' in ok_records else [])) })

        for f in ok_filters:
            lc.action.datastore_delete(
                resource_id=resource_id,
                filters=f,
                )

        h.flash_success(_("{num} deleted.").format(num=len(ok_filters)))

        redirect(h.url_for(
            controller='ckanext.recombinant.controller:UploadController',
            action='preview_table',
            resource_name=res['name'],
            owner_org=org['name'],
            ))
class OrganisationController(OrganizationController):

    ## end hooks
    def index(self):

        context = {
            'model': model,
            'session': model.Session,
            'user': c.user or c.author
        }
        data_dict = {'all_fields': True}

        try:
            check_access('site_read', context)
        except NotAuthorized:
            abort(401, _('Not authorized to see this page'))

        # This used to be just used by the hierarchy but now is not, but it is
        # now used for search autocomplete and count.
        # c.all_groups = model.Session.query(model.Group).\
        #                filter(model.Group.type == 'organization').\
        #                filter(model.Group.state == 'active').\
        #                order_by('title')
        # c.page = AlphaPage(
        #     controller_name="ckanext.dgu_orgs.controllers.organisation:OrganisationController",
        #     collection=c.all_groups,
        #     page=request.params.get('page', 'A'),
        #     alpha_attribute='title',
        #     other_text=_('Other'),
        # )

        return render('organisation/index.html')

    def _send_application(self, group, reason):
        from ckan.logic.action import error_summary
        from ckan.lib.mailer import mail_recipient
        from genshi.template.text import NewTextTemplate
        from pylons import config

        if not reason:
            h.flash_error(
                _("There was a problem with your submission, \
                             please correct it and try again"))
            errors = {"reason": ["No reason was supplied"]}
            return self.apply(group.id,
                              errors=errors,
                              error_summary=error_summary(errors))

        recipients, recipient_organisation = find_group_admins(group)

        if not recipients:
            if not config.get('dgu.admin.email'):
                log.error(
                    'User "%s" prevented from applying for organisation access for "%s" '
                    'because: dgu.admin.email is not setup in CKAN config.',
                    c.user, group.name)
                h.flash_error(
                    _("There is a problem with the system configuration"))
                errors = {"reason": ["data.gov.uk error"]}
                return self.apply(group.id,
                                  errors=errors,
                                  error_summary=error_summary(errors))
            recipients = [(config.get('dgu.admin.name',
                                      "DGU Admin"), config['dgu.admin.email'])]
            recipient_organisation = 'data.gov.uk admin team'

        url = urljoin(
            g.site_url,
            h.url_for(
                controller=
                'ckanext.dgu_orgs.controllers.organisation:OrganisationController',
                action='users',
                id=group.name))

        log.debug(
            'User "%s" requested organisation access for "%s" which was sent to admin %s (%r) with reason: %r',
            c.user, group.name, recipient_organisation, recipients, reason)
        extra_vars = {
            'group': group,
            'requester': c.userobj,
            'reason': reason,
            'accept_url': url
        }
        email_msg = render("email/join_publisher_request.txt",
                           extra_vars=extra_vars,
                           loader_class=NewTextTemplate)

        try:
            for (name, recipient) in recipients:
                mail_recipient(
                    name,
                    recipient,
                    subject=
                    'DGUKOrganisationRequest: Please add me as a data.gov.uk organisation',
                    body=email_msg)
        except Exception, e:
            h.flash_error(
                'There is a problem with the system configuration. Please instead <a href="http://data.gov.uk/contact">contact the data.gov.uk team</a>',
                allow_html=True)
            errors = {"reason": ["data.gov.uk error"]}
            log.error(
                'User "%s" prevented from applying for organisation access for "%s" because of mail configuration error: %s',
                c.user, group.name, e)
            return self.apply(group.id,
                              errors=errors,
                              error_summary=error_summary(errors))

        h.flash_success(
            'Your application has been submitted to administrator for: %s. If you do not hear back in a couple of days then <a href="http://data.gov.uk/contact">contact the data.gov.uk team</a>'
            % recipient_organisation,
            allow_html=True)
        h.redirect_to('organisation_read', id=group.name)
Example #38
0
            data_dict['url'] = '/dataset/%s' % c.pkg.name
            success = False
            try:
                res = get_action('comment_create')(context, data_dict)
                #res = {'id': dataset_id }

                success = True
            except ValidationError, ve:
                log.debug(ve)
            except Exception, e:
                log.debug(e)
                abort(403)

            if success:
                h.flash_success('<strong>' + _('Muy Bien') + '!</strong> ' + _(
                    u'Su comentario ha sido puesto en cola para su revisión por los administradores del sitio y se publicará después de su aprobación.'
                ),
                                allow_html=True)
                h.redirect_to(
                    str('/dataset/%s#comment_%s' % (c.pkg.name, res['id'])))

        return render("package/read.html")

    def delete(self, dataset_id, comment_id):

        context = {'model': model, 'user': c.user}

        # Verifica que el usuario autenticado pueda ver el paquete
        # Se comenta para evitar que solo usuarios conectados puedan realizar comentarios
        data_dict = {'id': dataset_id}
        check_access('package_show', context, data_dict)
Example #39
0
            check_access('manage_users', context, data_dict)
        except NotAuthorized, error:
            abort(401, error.__str__())

        group = model.Group.get(helpers.get_default_group())

        data_dict['id'] = group.id

        role = data_dict['role']

        if role == 'default':
            get_action('group_member_delete')(context, data_dict)
            h.flash_notice(_('User rights are removed.'), allow_html=True)
        else:
            get_action('group_member_create')(context, data_dict)
            h.flash_success(_('User Role is Updated Successfully.'), allow_html=True)

        url = h.url_for(controller='ckanext.ngds.ngdsui.controllers.user:UserController', action='manage_users')
        redirect(url)


    def member_list(self, group_name):
        """
        Accepts a group name, which is configured in the site configuration file and returns users that are associated with the group.
        """

        group = model.Group.get(group_name)

        q = model.Session.query(model.Member). \
            filter(model.Member.group_id == group.id). \
            filter(model.Member.state == "active"). \
Example #40
0
        def action_save_form(users_or_authz_groups):
            # The permissions grid has been saved
            # which is a grid of checkboxes named user$role
            rpi = request.params.items()

            # The grid passes us a list of the users/roles that were displayed
            submitted = [ a for (a,b) in rpi if (b == u'submitted')]
            # and also those which were checked
            checked = [ a for (a,b) in rpi if (b == u'on')]

            # from which we can deduce true/false for each user/role combination
            # that was displayed in the form
            table_dict={}
            for a in submitted:
                table_dict[a]=False
            for a in checked:
                table_dict[a]=True

            # now we'll split up the user$role strings to make a dictionary from 
            # (user,role) to True/False, which tells us what we need to do.
            new_user_role_dict={}
            for (ur,val) in table_dict.items():
                u,r = ur.split('$')
                new_user_role_dict[(u,r)] = val
               
            # we get the current user/role assignments 
            # and make a dictionary of them
            current_uors = get_userobjectroles()

            if users_or_authz_groups=='users':
                current_users_roles = [( uor.user.name, uor.role) for uor in current_uors if uor.user]
            elif users_or_authz_groups=='authz_groups':
                current_users_roles = [( uor.authorized_group.name, uor.role) for uor in current_uors if uor.authorized_group]        
            else:
                assert False, "shouldn't be here"

            current_user_role_dict={}
            for (u,r) in current_users_roles:
                current_user_role_dict[(u,r)]=True

            # and now we can loop through our dictionary of desired states
            # checking whether a change needs to be made, and if so making it

            # Here we check whether someone is already assigned a role, in order
            # to avoid assigning it twice, or attempting to delete it when it
            # doesn't exist. Otherwise problems can occur.
            if users_or_authz_groups=='users':
                for ((u,r), val) in new_user_role_dict.items():
                    if val:
                        if not ((u,r) in current_user_role_dict):
                            model.add_user_to_role(model.User.by_name(u),r,pkg)
                    else:
                        if ((u,r) in current_user_role_dict):
                            model.remove_user_from_role(model.User.by_name(u),r,pkg)
            elif users_or_authz_groups=='authz_groups':
                for ((u,r), val) in new_user_role_dict.items():
                    if val:
                        if not ((u,r) in current_user_role_dict):
                            model.add_authorization_group_to_role(model.AuthorizationGroup.by_name(u),r,pkg)
                    else:
                        if ((u,r) in current_user_role_dict):
                            model.remove_authorization_group_from_role(model.AuthorizationGroup.by_name(u),r,pkg)
            else:
                assert False, "shouldn't be here"


            # finally commit the change to the database
            model.repo.commit_and_remove()
            h.flash_success("Changes Saved")
    def upload(self, id):
        package_type = self._get_package_type(id)
        t = get_table(package_type)
        expected_sheet_name = t['xls_sheet_name']

        try:
            lc = ckanapi.LocalCKAN(username=c.user)
            package = lc.action.package_show(id=id)
            owner_org = package['organization']['name']

            if request.POST['xls_update'] == u'':
                msg = _('You must provide a valid file')
                raise ValidationError({'xls_update': [msg]})

            upload_data = read_xls(request.POST['xls_update'].file)
            sheet_name, org_name = None, None
            try:
                sheet_name, org_name = next(upload_data)
            except:
                # XXX bare except because this can fail in all sorts of ways
                if asbool(config.get('debug', False)):
                    # on debug we want the real error
                    raise
                raise ValidationError({'xls_update':
                    [_("The server encountered a problem processing the file "
                    "uploaded. Please try copying your data into the latest "
                    "version of the template and uploading again. If this "
                    "problem continues, send your Excel file to "
                    "[email protected] so we may investigate.")]})

            if expected_sheet_name != sheet_name:
                raise ValidationError({'xls_update':
                    [_('Invalid file for this data type. ' +
                    'Sheet must be labeled "{0}", ' +
                    'but you supplied a sheet labeled "{1}"').format(
                        expected_sheet_name, sheet_name)]})

            # is this the right sheet for this organization?
            if org_name != owner_org:
                msg = _(
                    'Invalid sheet for this organization. ' +
                    'Sheet must be labeled for {0}, ' +
                    'but you supplied a sheet for {1}').format(
                        owner_org, org_name)
                raise ValidationError({'xls_update': [msg]})

            resource_id = package['resources'][0]['id']

            records = get_records(upload_data, t['fields'])

            method = 'upsert' if t.get('datastore_primary_key') else 'insert'
            try:
                lc.action.datastore_upsert(
                    method=method,
                    resource_id=resource_id,
                    records=records)
            except NotAuthorized, na:
                msg = _(
                    'You do not have permission to upload to {0}').format(
                        owner_org)
                raise ValidationError({'xls_update': [msg]})

            h.flash_success(_(
                "Your file was successfully uploaded into the central system."
                ))

            redirect(h.url_for(controller='package', action='read', id=id))
Example #42
0
        def action_save_form(users_or_authz_groups):
            # The permissions grid has been saved
            # which is a grid of checkboxes named user$role
            rpi = request.params.items()

            # The grid passes us a list of the users/roles that were displayed
            submitted = [ a for (a,b) in rpi if (b == u'submitted')]
            # and also those which were checked
            checked = [ a for (a,b) in rpi if (b == u'on')]

            # from which we can deduce true/false for each user/role combination
            # that was displayed in the form
            table_dict={}
            for a in submitted:
                table_dict[a]=False
            for a in checked:
                table_dict[a]=True

            # now we'll split up the user$role strings to make a dictionary from 
            # (user,role) to True/False, which tells us what we need to do.
            new_user_role_dict={}
            for (ur,val) in table_dict.items():
                u,r = ur.split('$')
                new_user_role_dict[(u,r)] = val
               
            # we get the current user/role assignments 
            # and make a dictionary of them
            current_uors = get_userobjectroles()

            if users_or_authz_groups=='users':
                current_users_roles = [( uor.user.name, uor.role) for uor in current_uors if uor.user]
            elif users_or_authz_groups=='authz_groups':
                current_users_roles = [( uor.authorized_group.name, uor.role) for uor in current_uors if uor.authorized_group]        
            else:
                assert False, "shouldn't be here"

            current_user_role_dict={}
            for (u,r) in current_users_roles:
                current_user_role_dict[(u,r)]=True

            # and now we can loop through our dictionary of desired states
            # checking whether a change needs to be made, and if so making it

            # Here we check whether someone is already assigned a role, in order
            # to avoid assigning it twice, or attempting to delete it when it
            # doesn't exist. Otherwise problems can occur.
            if users_or_authz_groups=='users':
                for ((u,r), val) in new_user_role_dict.items():
                    if val:
                        if not ((u,r) in current_user_role_dict):
                            model.add_user_to_role(model.User.by_name(u),r,group)
                    else:
                        if ((u,r) in current_user_role_dict):
                            model.remove_user_from_role(model.User.by_name(u),r,group)
            elif users_or_authz_groups=='authz_groups':
                for ((u,r), val) in new_user_role_dict.items():
                    if val:
                        if not ((u,r) in current_user_role_dict):
                            model.add_authorization_group_to_role(model.AuthorizationGroup.by_name(u),r,group)
                    else:
                        if ((u,r) in current_user_role_dict):
                            model.remove_authorization_group_from_role(model.AuthorizationGroup.by_name(u),r,group)
            else:
                assert False, "shouldn't be here"


            # finally commit the change to the database
            model.repo.commit_and_remove()
            h.flash_success("Changes Saved")
Example #43
0
    def _prepare_and_send(self, pkg_id, recipient_id, subject, prefix_template, suffix):
        """
        Sends a message by email from the logged in user to the appropriate
        contact address of the given dataset.

        The prefix template should have formatting placeholders for the following arguments:
        {sender_name}, {sender_email}, {package_title}, {data_pid}

        :param pkg_id: package id
        :type pkg_id: string
        :param recipient_id: id of the recipient, as returned by utils.get_package_contacts
        :type recipient_id: string
        :param subject: the subject of the message
        :type subject: string
        :param prefix_template: the template for the prefix to be automatically included before the user message
        :type prefix_template: unicode
        :param suffix: an additional note to be automatically included after the user message
        :type suffix: unicode
        """

        url = h.url_for(controller='package', action='read', id=pkg_id)

        if asbool(config.get('kata.contact_captcha')):
            try:
                captcha.check_recaptcha(request)
            except captcha.CaptchaError:
                h.flash_error(_(u'Bad Captcha. Please try again.'))
                redirect(url)

        if not request.params.get('accept_logging'):
            h.flash_error(_(u"Message not sent as logging wasn't permitted"))
            return redirect(url)

        if asbool(config.get('kata.disable_contact')):
            h.flash_error(_(u"Sending contact emails is prohibited for now. Please try again later or contact customer "
u"service."))
            return redirect(url)

        package = Package.get(pkg_id)
        package_title = package.title if package.title else package.name

        sender_addr = request.params.get('from_address')
        sender_name = request.params.get('from_name')
        recipient = self._get_contact_email(pkg_id, recipient_id)

        if not recipient:
            abort(404, _('Recipient not found'))

        user_msg = request.params.get('msg', '')

        ct = int(time.time())
        try:
            check = self.crypto.decrypt(base64.b64decode(request.params.get('check_this_out')))
            check = re.sub(' ', '', check)
        except TypeError:
            h.flash_error(_(u"Message not sent. Couldn't confirm human interaction (spam bot control)"))
            return redirect(url)

        hp = request.params.get('hp')

        if hp or not check or (ct - int(check) < 20) or (ct - int(check) > 1200):
            h.flash_error(_(u"Message not sent. Couldn't confirm human interaction (spam bot control)"))
            return redirect(url)

        if sender_addr and sender_name and \
                isinstance(sender_name, basestring) and len(sender_name) >= 3:
            if user_msg:
                prefix = prefix_template.format(
                    sender_name=sender_name,
                    sender_email=sender_addr,
                    package_title=package_title,
                    data_pid=utils.get_primary_data_pid_from_package(package)
                )

                log.info(u"Message {m} sent from {a} ({b}) to {r} about {c}, IP: {d}"
                         .format(m=user_msg, a=sender_name, b=sender_addr, r=recipient, c=pkg_id,
                                 d=request.environ.get('REMOTE_ADDR', 'No remote address')))

                full_msg = u"{a}{b}{c}".format(a=prefix, b=user_msg, c=suffix)
                self._send_message(subject, full_msg, recipient.get('email'), recipient.get('name'))
                h.flash_success(_(u"Message sent"))
            else:
                h.flash_error(_(u"No message"))
        else:
            h.flash_error(_(u"Message not sent. Please, provide reply address and name. Name must contain \
at least three letters."))

        return redirect(url)
Example #44
0
    def delete_records(self, id, resource_id):
        lc = ckanapi.LocalCKAN(username=c.user)
        filters = {}

        x_vars = {'filters': filters, 'action': 'edit'}
        pkg = lc.action.package_show(id=id)
        res = lc.action.resource_show(id=resource_id)
        org = lc.action.organization_show(id=pkg['owner_org'])

        dataset = lc.action.recombinant_show(dataset_type=pkg['type'],
                                             owner_org=org['name'])

        def delete_error(err):
            return render('recombinant/resource_edit.html',
                          extra_vars={
                              'delete_errors': [err],
                              'dataset': dataset,
                              'resource': res,
                              'organization': org,
                              'filters': filters,
                              'action': 'edit'
                          })

        form_text = request.POST.get('bulk-delete', '')
        if not form_text:
            return delete_error(_('Required field'))

        pk_fields = recombinant_primary_key_fields(res['name'])

        ok_records = []
        ok_filters = []
        records = iter(form_text.split('\n'))
        for r in records:
            r = r.rstrip('\r')

            def record_fail(err):
                # move bad record to the top of the pile
                filters['bulk-delete'] = '\n'.join([r] + list(records) +
                                                   ok_records)
                return delete_error(err)

            split_on = '\t' if '\t' in r else ','
            fields = [f for f in r.split(split_on)]
            if len(fields) != len(pk_fields):
                return record_fail(
                    _('Wrong number of fields, expected {num}').format(
                        num=len(pk_fields)))

            filters.clear()
            for f, pkf in zip(fields, pk_fields):
                filters[pkf['datastore_id']] = f
            try:
                result = lc.action.datastore_search(resource_id=resource_id,
                                                    filters=filters,
                                                    limit=2)
            except ValidationError:
                return record_fail(_('Invalid fields'))
            found = result['records']
            if not found:
                return record_fail(
                    _('No matching records found "%s"') % u'", "'.join(fields))
            if len(found) > 1:
                return record_fail(_('Multiple matching records found'))

            if r not in ok_records:
                ok_records.append(r)
                ok_filters.append(dict(filters))

        if 'cancel' in request.POST:
            return render('recombinant/resource_edit.html',
                          extra_vars={
                              'delete_errors': [],
                              'dataset': dataset,
                              'resource': res,
                              'organization': org,
                              'filters': {
                                  'bulk-delete': u'\n'.join(ok_records)
                              },
                              'action': 'edit'
                          })
        if not 'confirm' in request.POST:
            return render(
                'recombinant/confirm_delete.html',
                extra_vars={
                    'dataset':
                    dataset,
                    'resource':
                    res,
                    'num':
                    len(ok_records),
                    'bulk_delete':
                    u'\n'.join(
                        ok_records
                        # extra blank is needed to prevent field
                        # from being completely empty
                        + ([''] if '' in ok_records else []))
                })

        for f in ok_filters:
            lc.action.datastore_delete(
                resource_id=resource_id,
                filters=f,
            )

        h.flash_success(_("{num} deleted.").format(num=len(ok_filters)))

        redirect(
            h.url_for(
                controller='ckanext.recombinant.controller:UploadController',
                action='preview_table',
                resource_name=res['name'],
                owner_org=org['name'],
            ))
Example #45
0
class PublisherController(GroupController):

    ## end hooks
    def index(self):

        context = {'model': model, 'session': model.Session,
                   'user': c.user or c.author}
        data_dict = {'all_fields': True}

        try:
            check_access('site_read', context)
        except NotAuthorized:
            abort(401, _('Not authorized to see this page'))

        # TODO: Fix this up, we only really need to do this when we are
        # showing the hierarchy (and then we should load on demand really).
        c.all_groups = model.Session.query(model.Group).\
                       filter(model.Group.type == 'publisher').\
                       filter(model.Group.state == 'active').\
                       order_by('title')
        c.page = AlphaPage(
            controller_name="ckanext.dgu.controllers.publisher:PublisherController",
            collection=c.all_groups,
            page=request.params.get('page', 'A'),
            alpha_attribute='title',
            other_text=_('Other'),
        )

        return render('publisher/index.html')



    def _send_application( self, group, reason  ):
        from ckan.logic.action import error_summary
        from ckan.lib.mailer import mail_recipient
        from genshi.template.text import NewTextTemplate
        from pylons import config

        if not reason:
            h.flash_error(_("There was a problem with your submission, \
                             please correct it and try again"))
            errors = {"reason": ["No reason was supplied"]}
            return self.apply(group.id, errors=errors,
                              error_summary=error_summary(errors))

        # look for publisher admins up the tree
        recipients = []
        recipient_publisher = None
        for publisher in go_up_tree(group):
            admins = publisher.members_of_type(model.User, 'admin').all()
            if admins:
                recipients = [(u.fullname,u.email) for u in admins]
                recipient_publisher = publisher.title
                break
        if not recipients:
            if not config.get('dgu.admin.email'):
                log.error('User "%s" prevented from applying for publisher access for "%s" '
                          'because: dgu.admin.email is not setup in CKAN config.',
                          c.user, group.name)
                h.flash_error(_("There is a problem with the system configuration"))
                errors = {"reason": ["%s does not have an administrator user to contact" % group.name]}
                return self.apply(group.id, data=data, errors=errors,
                                  error_summary=error_summary(errors))                
            recipients = [(config.get('dgu.admin.name', "DGU Admin"),
                           config['dgu.admin.email'])]
            recipient_publisher = 'data.gov.uk admin'

            
        log.debug('User "%s" requested publisher access for "%s" which was sent to admin %s (%r) with reason: %r',
                  c.user, group.name, recipient_publisher, recipients, reason)
        extra_vars = {
            'group'    : group,
            'requester': c.userobj,
            'reason'   : reason
        }
        email_msg = render("email/join_publisher_request.txt", extra_vars=extra_vars,
                           loader_class=NewTextTemplate)

        try:
            for (name,recipient) in recipients:
                mail_recipient(name,
                               recipient,
                               "Publisher request",
                               email_msg)
        except Exception, e:
            h.flash_error(_("There is a problem with the system configuration"))
            errors = {"reason": ["No mail server was found"]}
            log.error('User "%s" prevented from applying for publisher access for "%s" because of mail configuration error: %s',
                      c.user, group.name, e)
            return self.apply(group.id, errors=errors,
                              error_summary=error_summary(errors))

        h.flash_success("Your application has been submitted to administrator for: %s" % recipient_publisher)
        h.redirect_to( 'publisher_read', id=group.name)
                # they have already been added?
            else:
                c.req.decision = True
                c.req.date_of_decision = datetime.datetime.utcnow()
                if not c.in_group:
                    model.repo.new_revision()
                    member = model.Member(group=c.req_group,
                                          table_id=c.req_user.id,
                                          table_name='user',
                                          capacity='editor')
                    model.Session.add(member)
                msg = '<strong>%s</strong> was added to the organisation <strong>%s</strong>' % (
                    c.req_user.fullname, c.req_group.title)
            model.Session.commit()

            h.flash_success(msg, allow_html=True)
            h.redirect_to('organisation_request', token=token)
        else:
            return render('data/organisation_request.html')

    def organisation_requests(self):
        if not dgu_helpers.is_sysadmin():
            abort(401, 'User must be a sysadmin to view this page.')

        from ckan import model
        from ckanext.dgu_orgs.model.organisation_request import OrganisationRequest

        organisation_requests = []
        for req in model.Session.query(OrganisationRequest).order_by(
                OrganisationRequest.date_of_request.desc()).all():
            item = {}
Example #47
0
    def _prepare_and_send(self, pkg_id, recipient_id, subject, prefix_template, suffix):
        """
        Sends a message by email from the logged in user to the appropriate
        contact address of the given dataset.

        The prefix template should have formatting placeholders for the following arguments:
        {sender_name}, {sender_email}, {package_title}, {package_id}

        :param pkg_id: package id
        :type pkg_id: string
        :param recipient_id: id of the recipient, as returned by utils.get_package_contacts
        :type recipient_id: string
        :param subject: the subject of the message
        :type subject: string
        :param prefix_template: the template for the prefix to be automatically included before the user message
        :type prefix_template: unicode
        :param suffix: an additional note to be automatically included after the user message
        :type suffix: unicode
        """

        url = h.url_for(controller='package', action='read', id=pkg_id)

        if asbool(config.get('kata.contact_captcha')):
            try:
                captcha.check_recaptcha(request)
            except captcha.CaptchaError:
                h.flash_error(_(u'Bad Captcha. Please try again.'))
                redirect(url)

        if not request.params.get('accept_logging'):
            h.flash_error(_(u"Message not sent as logging wasn't permitted"))
            return redirect(url)

        if asbool(config.get('kata.disable_contact')):
            h.flash_error(_(u"Sending contact emails is prohibited for now. Please try again later or contact customer "
u"service."))
            return redirect(url)

        package = Package.get(pkg_id)
        package_title = package.title if package.title else package.name

        sender_addr = request.params.get('from_address')
        sender_name = request.params.get('from_name')
        recipient = self._get_contact_email(pkg_id, recipient_id)

        if not recipient:
            abort(404, _('Recipient not found'))

        user_msg = request.params.get('msg', '')

        if request.params.get('hp'):
            h.flash_error(_(u"Message not sent. Couldn't confirm human interaction (spam bot control)"))
            return redirect(url)

        if sender_addr and sender_name and \
                isinstance(sender_name, basestring) and len(sender_name) >= 3:
            if user_msg:
                prefix = prefix_template.format(
                    sender_name=sender_name,
                    sender_email=sender_addr,
                    package_title=package_title,
                    package_id=pkg_id
                    # above line was: metadata_pid=utils.get_primary_data_pid_from_package(package)
                )

                log.info(u"Message {m} sent from {a} ({b}) to {r} about {c}, IP: {d}"
                         .format(m=user_msg, a=sender_name, b=sender_addr, r=recipient, c=pkg_id,
                                 d=request.environ.get('REMOTE_ADDR', 'No remote address')))

                full_msg = u"{a}{b}{c}".format(a=prefix, b=user_msg, c=suffix)
                self._send_message(subject, full_msg, recipient.get('email'), recipient.get('name'))
                h.flash_success(_(u"Message sent"))
            else:
                h.flash_error(_(u"No message"))
        else:
            h.flash_error(_(u"Message not sent. Please, provide reply address and name. Name must contain \
at least three letters."))

        return redirect(url)
Example #48
0
 def success(self, label=None):
     label = request.params.get("label", label)
     h.flash_success("Upload successful")
     c.file_url = h.url_for("storage_file", label=label, qualified=True)
     c.upload_url = h.url_for("storage_upload")
     return render("storage/success.html")