Example #1
0
    def _validate_groupid(self, appstruct):
        """
        Validate the ``groupid`` to make sure it adheres to authority restrictions.

        ``groupid`` is only allowed if the authority of the group associated
        with it is not the default authority—i.e. this is a third-party group.

        :arg appstruct: Data, which may or may not contain a ``groupid`` entry
        :type appstruct: dict
        :raise h.schemas.ValidationError:

        """
        groupid = appstruct.get("groupid", None)
        if groupid is None:  # Nothing to validate
            return None

        if (self.group_authority is None) or (self.group_authority
                                              == self.default_authority):
            # This is a first-party group
            raise ValidationError("{err_msg} '{authority}'".format(
                err_msg=
                _("groupid may only be set on groups oustide of the default authority"
                  ),
                authority=self.default_authority,
            ))

        groupid_parts = split_groupid(groupid)

        if groupid_parts["authority"] != self.group_authority:
            # The authority part of the ``groupid`` doesn't match the
            # group's authority
            raise ValidationError("{err_msg} '{groupid}'".format(
                err_msg=_("Invalid authority specified in groupid"),
                groupid=groupid))
Example #2
0
    def ensure_unique(self, data, authority):
        """
        Ensure the provided `data` would constitute a new, non-duplicate user.

        Check for conflicts in email, username, identity.

        :param data: dictionary of new-user data. Will check `email`, `username`
                     and any `identities` dictionaries provided
        :raises ConflictError: if the data violate any uniqueness constraints

        :param authority: Authority against which to do a duplicate check
        """
        # pylint:disable=consider-using-f-string
        errors = []

        # check for duplicate email address
        if data.get("email", None) and (
            models.User.get_by_email(self._session, data["email"], authority)
            is not None
        ):
            errors.append(
                _("user with email address '{}' already exists".format(data["email"]))
            )

        # check for duplicate username
        if data.get("username", None) and (
            models.User.get_by_username(self._session, data["username"], authority)
            is not None
        ):
            errors.append(
                _("user with username '{}' already exists".format(data["username"]))
            )

        # check for duplicate identities
        # (provider, provider_unique_id) combinations
        identities = data.get("identities", [])
        for identity in identities:
            if self.user_service.fetch_by_identity(
                identity["provider"], identity["provider_unique_id"]
            ):
                errors.append(
                    _(
                        "user with provider '{}' and unique id '{}' already exists".format(
                            identity["provider"], identity["provider_unique_id"]
                        )
                    )
                )

        if errors:
            raise DuplicateUserError(", ".join(errors))
Example #3
0
    def ensure_unique(self, data, authority):
        """
        Ensure the provided `data` would constitute a new, non-duplicate
        user. Check for conflicts in email, username, identity.

        :param data: dictionary of new-user data. Will check `email`, `username`
                     and any `identities` dictionaries provided
        :raises ConflictError: if the data violate any uniqueness constraints

        :param authority: Authority against which to do a duplicate check
        """
        errors = []

        # check for duplicate email address
        if data.get("email", None) and (
            models.User.get_by_email(self._session, data["email"], authority)
            is not None
        ):
            errors.append(
                _("user with email address '{}' already exists".format(data["email"]))
            )

        # check for duplicate username
        if data.get("username", None) and (
            models.User.get_by_username(self._session, data["username"], authority)
            is not None
        ):
            errors.append(
                _("user with username '{}' already exists".format(data["username"]))
            )

        # check for duplicate identities
        # (provider, provider_unique_id) combinations
        identities = data.get("identities", [])
        for identity in identities:
            if self.user_service.fetch_by_identity(
                identity["provider"], identity["provider_unique_id"]
            ):
                errors.append(
                    _(
                        "user with provider '{}' and unique id '{}' already exists".format(
                            identity["provider"], identity["provider_unique_id"]
                        )
                    )
                )

        if errors:
            raise DuplicateUserError(", ".join(errors))
Example #4
0
def generate(request, user):
    """
    Generate an email for a user password reset request.

    :param request: the current request
    :type request: pyramid.request.Request
    :param user: the user to whom to send the reset code
    :type user: h.models.User

    :returns: a 4-element tuple containing: recipients, subject, text, html
    """
    serializer = request.registry.password_reset_serializer
    code = serializer.dumps(user.username)
    context = {
        'username': user.username,
        'reset_code': code,
        'reset_link': request.route_url('account_reset_with_code', code=code)
    }

    subject = _('Reset your password')

    text = render('h:templates/emails/reset_password.txt.jinja2',
                  context,
                  request=request)
    html = render('h:templates/emails/reset_password.html.jinja2',
                  context,
                  request=request)

    return [user.email], subject, text, html
Example #5
0
def generate(request, email, incontext_link):
    """
    Generate an email to notify the group admin when a group member flags an annotation.

    :param request: the current request
    :type request: pyramid.request.Request
    :param email: the group admin's email address
    :type email: text
    :param incontext_link: the direct link to the flagged annotation
    :type incontext_link: text

    :returns: a 4-element tuple containing: recipients, subject, text, html
    """
    context = {"incontext_link": incontext_link}

    subject = _("An annotation has been flagged")

    text = render(
        "h:templates/emails/flag_notification.txt.jinja2", context, request=request
    )
    html = render(
        "h:templates/emails/flag_notification.html.jinja2", context, request=request
    )

    return [email], subject, text, html
Example #6
0
def generate(request, id, email, activation_code):
    """
    Generate an email for a user signup.

    :param request: the current request
    :type request: pyramid.request.Request
    :param id: the new user's primary key ID
    :type id: int
    :param email: the new user's email address
    :type email: text
    :param activation_code: the activation code
    :type activation_code: text

    :returns: a 4-element tuple containing: recipients, subject, text, html
    """
    context = {
        "activate_link": request.route_url("activate", id=id, code=activation_code)
    }

    subject = _("Please activate your account")

    text = render("h:templates/emails/signup.txt.jinja2", context, request=request)
    html = render("h:templates/emails/signup.html.jinja2", context, request=request)

    return [email], subject, text, html
Example #7
0
def generate(request, email, incontext_link):
    """
    Generate an email to notify the group admin when a group member flags an annotation.

    :param request: the current request
    :type request: pyramid.request.Request
    :param email: the group admin's email address
    :type email: text
    :param incontext_link: the direct link to the flagged annotation
    :type incontext_link: text

    :returns: a 4-element tuple containing: recipients, subject, text, html
    """
    context = {"incontext_link": incontext_link}

    subject = _("An annotation has been flagged")

    text = render(
        "h:templates/emails/flag_notification.txt.jinja2", context, request=request
    )
    html = render(
        "h:templates/emails/flag_notification.html.jinja2", context, request=request
    )

    return [email], subject, text, html
Example #8
0
def generate(request, id, email, activation_code):
    """
    Generate an email for a user signup.

    :param request: the current request
    :type request: pyramid.request.Request
    :param id: the new user's primary key ID
    :type id: int
    :param email: the new user's email address
    :type email: text
    :param activation_code: the activation code
    :type activation_code: text

    :returns: a 4-element tuple containing: recipients, subject, text, html
    """
    context = {
        'activate_link':
        request.route_url('activate', id=id, code=activation_code),
    }

    subject = _('Please activate your account')

    text = render('h:templates/emails/signup.txt.jinja2',
                  context,
                  request=request)
    html = render('h:templates/emails/signup.html.jinja2',
                  context,
                  request=request)

    return [email], subject, text, html
Example #9
0
def json_error(request):
    """Handle an unexpected exception where the request asked for JSON."""
    handle_exception(request)
    message = _("Hypothesis had a problem while handling this request. "
                "Our team has been notified. Please contact [email protected]"
                " if the problem persists.")
    return {'status': 'failure', 'reason': message}
Example #10
0
def create(request):
    """Create a group from the POST payload."""
    appstruct = CreateGroupAPISchema(
        default_authority=request.default_authority,
        group_authority=client_authority(request)
        or request.default_authority).validate(_json_payload(request))

    group_service = request.find_service(name='group')
    group_create_service = request.find_service(name='group_create')

    # Check for duplicate group
    groupid = appstruct.get('groupid', None)
    if groupid is not None:
        duplicate_group = group_service.fetch(pubid_or_groupid=groupid)
        if duplicate_group:
            raise ConflictError(
                _("group with groupid '{}' already exists").format(groupid))

    group = group_create_service.create_private_group(
        name=appstruct['name'],
        userid=request.user.userid,
        description=appstruct.get('description', None),
        groupid=groupid,
    )
    return GroupJSONPresenter(GroupContext(
        group, request)).asdict(expand=['organization'])
Example #11
0
File: groups.py Project: kaydoh/h
def create(request):
    """Create a group from the POST payload."""
    appstruct = CreateGroupAPISchema(
        default_authority=request.default_authority,
        group_authority=request.effective_authority,
    ).validate(_json_payload(request))

    group_service = request.find_service(name="group")
    group_create_service = request.find_service(name="group_create")

    # Check for duplicate group
    groupid = appstruct.get("groupid", None)
    if groupid is not None:
        duplicate_group = group_service.fetch(pubid_or_groupid=groupid)
        if duplicate_group:
            raise HTTPConflict(
                _("group with groupid '{}' already exists").format(groupid))

    group = group_create_service.create_private_group(
        name=appstruct["name"],
        userid=request.user.userid,
        description=appstruct.get("description", None),
        groupid=groupid,
    )
    return GroupJSONPresenter(
        group, request).asdict(expand=["organization", "scopes"])
Example #12
0
def create(request):
    """Create a group from the POST payload."""
    appstruct = CreateGroupAPISchema(
        default_authority=request.default_authority,
        group_authority=client_authority(request) or request.default_authority,
    ).validate(_json_payload(request))

    group_service = request.find_service(name="group")
    group_create_service = request.find_service(name="group_create")

    # Check for duplicate group
    groupid = appstruct.get("groupid", None)
    if groupid is not None:
        duplicate_group = group_service.fetch(pubid_or_groupid=groupid)
        if duplicate_group:
            raise HTTPConflict(
                _("group with groupid '{}' already exists").format(groupid)
            )

    group = group_create_service.create_private_group(
        name=appstruct["name"],
        userid=request.user.userid,
        description=appstruct.get("description", None),
        groupid=groupid,
    )
    return GroupJSONPresenter(GroupContext(group, request)).asdict(
        expand=["organization", "scopes"]
    )
Example #13
0
def generate(request, user):
    """
    Generate an email for a user password reset request.

    :param request: the current request
    :type request: pyramid.request.Request
    :param user: the user to whom to send the reset code
    :type user: h.models.User

    :returns: a 4-element tuple containing: recipients, subject, text, html
    """
    serializer = request.registry.password_reset_serializer
    code = serializer.dumps(user.username)
    context = {
        "username": user.username,
        "reset_code": code,
        "reset_link": request.route_url("account_reset_with_code", code=code),
    }

    subject = _("Reset your password")

    text = render(
        "h:templates/emails/reset_password.txt.jinja2", context, request=request
    )
    html = render(
        "h:templates/emails/reset_password.html.jinja2", context, request=request
    )

    return [user.email], subject, text, html
Example #14
0
def json_error(context, request):
    """Handle an unexpected exception in an API view."""
    handle_exception(request, exception=context)
    message = _(
        "Hypothesis had a problem while handling this request. "
        "Our team has been notified. Please contact [email protected]"
        " if the problem persists.")
    return {"status": "failure", "reason": message}
Example #15
0
def back_link(_context, request):
    """
    A link which takes the user back to the previous page on the site.
    """

    referrer_path = urlparse(request.referrer or "").path
    current_username = request.user.username

    if referrer_path == request.route_path("activity.user_search",
                                           username=current_username):
        back_label = _("Back to your profile page")
    elif _matches_route(referrer_path, request, "group_read"):
        back_label = _("Back to group overview page")
    else:
        back_label = None

    return {"back_label": back_label, "back_location": request.referrer}
Example #16
0
def back_link_label(request):
    """
    Get a link which takes the user back to the previous page on the site.

    This is used in `templates/includes/back_link.html.jinja2`
    """

    referrer_path = urlparse(request.referrer or "").path
    current_username = request.user.username

    if referrer_path == request.route_path("activity.user_search",
                                           username=current_username):
        return _("Back to your profile page")

    if _matches_route(referrer_path, request, route_name="group_read"):
        return _("Back to group overview page")

    return None
Example #17
0
File: nipsa.py Project: mari-ja/h
def _form_request_user(request, param):
    username = request.params[param]
    user = models.User.get_by_username(request.db, username)

    if user is None:
        raise UserNotFoundError(
            _("Could not find user with username %s" % username))

    return user
Example #18
0
    def search(self):
        check_slug(self.group, self.request)

        result = super(GroupSearchController, self).search()

        result["opts"] = {"search_groupname": self.group.name}

        if self.request.authenticated_user not in self.group.members:
            return result

        def user_annotation_count(aggregation, userid):
            for user in aggregation:
                if user["user"] == userid:
                    return user["count"]
            return 0

        q = query.extract(self.request)
        users_aggregation = result["search_results"].aggregations.get("users", [])
        members = [
            {
                "username": u.username,
                "userid": u.userid,
                "count": user_annotation_count(users_aggregation, u.userid),
                "faceted_by": _faceted_by_user(self.request, u.username, q),
            }
            for u in self.group.members
        ]
        members = sorted(members, key=lambda k: k["username"].lower())

        group_annotation_count = None
        if self.request.feature("total_shared_annotations"):
            group_annotation_count = self.request.find_service(name="annotation_stats").group_annotation_count(
                self.group.pubid
            )

        result["stats"] = {"annotation_count": group_annotation_count}

        result["group"] = {
            "created": self.group.created.strftime("%B, %Y"),
            "description": self.group.description,
            "name": self.group.name,
            "pubid": self.group.pubid,
            "url": self.request.route_url("group_read", pubid=self.group.pubid, slug=self.group.slug),
            "members": members,
        }

        if self.request.has_permission("admin", self.group):
            result["group_edit_url"] = self.request.route_url("group_edit", pubid=self.group.pubid)

        result["more_info"] = "more_info" in self.request.params

        if not result.get("q"):
            result["zero_message"] = Markup(
                _("The group “{name}” has not made any annotations yet.").format(name=Markup.escape(self.group.name))
            )

        return result
Example #19
0
def json_error(context, request):
    """Handle an unexpected exception where the request asked for JSON."""
    handle_exception(request, exception=context)
    message = _(
        "Hypothesis had a problem while handling this request. "
        "Our team has been notified. Please contact [email protected]"
        " if the problem persists."
    )
    return {"status": "failure", "reason": message}
Example #20
0
def admins_add(request):
    """Make a given user an admin."""
    username = request.params['add']
    try:
        accounts.make_admin(username)
    except accounts.NoSuchUserError:
        request.session.flash(
            _("User {username} doesn't exist.".format(username=username)),
            "error")
    return admins_index(request)
Example #21
0
def admins_add(request):
    """Make a given user an admin."""
    username = request.params['add']
    try:
        accounts.make_admin(username)
    except accounts.NoSuchUserError:
        request.session.flash(
            _("User {username} doesn't exist.".format(username=username)),
            "error")
    return admins_index(request)
Example #22
0
def _form_request_user(request, param):
    username = request.params[param]
    user = models.User.get_by_username(request.db, username)

    if user is None:
        raise UserNotFoundError(
            _("Could not find user with username %s" % username)
        )

    return user
Example #23
0
def json_error(request):
    """Handle an unexpected exception where the request asked for JSON."""
    handle_exception(request)
    message = _("Uh-oh, something went wrong! We're very sorry, our "
                "application wasn't able to load this page. The team has "
                "been notified and we'll fix it shortly. If the problem "
                "persists or you'd like more information please email "
                "[email protected] with the subject 'Internal Server "
                "Error'.")
    return {'status': 'failure', 'reason': message}
Example #24
0
def json_error(request):
    """Handle an unexpected exception where the request asked for JSON."""
    handle_exception(request)
    message = _("Uh-oh, something went wrong! We're very sorry, our "
                "application wasn't able to load this page. The team has "
                "been notified and we'll fix it shortly. If the problem "
                "persists or you'd like more information please email "
                "[email protected] with the subject 'Internal Server "
                "Error'.")
    return {'status': 'failure', 'reason': message}
Example #25
0
def back_link(context, request):
    """
    A link which takes the user back to the previous page on the site.
    """

    referrer_path = urlparse.urlparse(request.referrer or '').path
    current_username = request.authenticated_user.username

    if referrer_path == request.route_path('activity.user_search',
                                           username=current_username):
        back_label = _('Back to your profile page')
    elif _matches_route(referrer_path, request, 'group_read'):
        back_label = _('Back to group overview page')
    else:
        back_label = None

    return {
        'back_label': back_label,
        'back_location': request.referrer,
    }
Example #26
0
def nipsa_remove(request):
    userid = request.params["remove"]
    user = request.db.query(models.User).filter_by(userid=userid).first()
    if user is None:
        raise UserNotFoundError(_("Could not find user with userid %s" % userid))

    nipsa_service = request.find_service(name="nipsa")
    nipsa_service.unflag(user)

    index = request.route_path("admin.nipsa")
    return httpexceptions.HTTPSeeOther(index)
Example #27
0
def back_link(context, request):
    """
    A link which takes the user back to the previous page on the site.
    """

    referrer_path = urlparse.urlparse(request.referrer or '').path
    current_username = request.user.username

    if referrer_path == request.route_path('activity.user_search',
                                           username=current_username):
        back_label = _('Back to your profile page')
    elif _matches_route(referrer_path, request, 'group_read'):
        back_label = _('Back to group overview page')
    else:
        back_label = None

    return {
        'back_label': back_label,
        'back_location': request.referrer,
    }
def nipsa_remove(request):
    userid = request.params["remove"]
    user = request.db.query(models.User).filter_by(userid=userid).first()
    if user is None:
        raise UserNotFoundError(_("Could not find user with userid %s" % userid))

    nipsa_service = request.find_service(name="nipsa")
    nipsa_service.unflag(user)

    index = request.route_path("admin.nipsa")
    return httpexceptions.HTTPSeeOther(index)
Example #29
0
def upsert(context, request):
    """
    Create or update a group from a PUT payload.

    If no group model is present in the passed ``context`` (on ``context.group``),
    treat this as a create action and delegate to ``create``.

    Otherwise, replace the existing group's resource properties entirely and update
    the object.

    :arg context:
    :type context: h.traversal.GroupUpsertContext
    """
    if context.group is None:
        return create(request)

    group = context.group

    # Because this is a PUT endpoint and not a PATCH, a full replacement of the
    # entire resource is expected. Thus, we're validating against the Create schema
    # here as we want to make sure properties required for a fresh object are present
    appstruct = CreateGroupAPISchema(
        default_authority=request.default_authority,
        group_authority=client_authority(request) or request.default_authority,
    ).validate(_json_payload(request))

    group_update_service = request.find_service(name="group_update")
    group_service = request.find_service(name="group")

    # Check for duplicate group
    groupid = appstruct.get("groupid", None)
    if groupid is not None:
        duplicate_group = group_service.fetch(pubid_or_groupid=groupid)
        if duplicate_group and (duplicate_group != group):
            raise HTTPConflict(
                _("group with groupid '{}' already exists").format(groupid)
            )

    # Need to make sure every resource-defined property is present, as this
    # is meant as a full-resource-replace operation.
    # TODO: This may be better handled in the schema at some point
    update_properties = {
        "name": appstruct["name"],
        "description": appstruct.get("description", ""),
        "groupid": appstruct.get("groupid", None),
    }

    group = group_update_service.update(group, **update_properties)

    # Note that this view takes a ``GroupUpsertContext`` but uses a ``GroupContext`` here
    return GroupJSONPresenter(GroupContext(group, request)).asdict(
        expand=["organization", "scopes"]
    )
Example #30
0
def features_save(request):
    session.check_csrf_token(request)
    for feat in models.Feature.all(request.db):
        for attr in ['everyone', 'admins', 'staff']:
            val = request.POST.get('{0}[{1}]'.format(feat.name, attr))
            if val == 'on':
                setattr(feat, attr, True)
            else:
                setattr(feat, attr, False)
    request.session.flash(_("Changes saved."), "success")
    return httpexceptions.HTTPSeeOther(
        location=request.route_url('admin_features'))
Example #31
0
def upsert(context, request):
    """
    Create or update a group from a PUT payload.

    If no group model is present in the passed ``context`` (on ``context.group``),
    treat this as a create action and delegate to ``create``.

    Otherwise, replace the existing group's resource properties entirely and update
    the object.

    :arg context:
    :type context: h.traversal.GroupUpsertContext
    """
    if context.group is None:
        return create(request)

    group = context.group

    # Because this is a PUT endpoint and not a PATCH, a full replacement of the
    # entire resource is expected. Thus, we're validating against the Create schema
    # here as we want to make sure properties required for a fresh object are present
    appstruct = CreateGroupAPISchema(
        default_authority=request.default_authority,
        group_authority=client_authority(request) or request.default_authority,
    ).validate(_json_payload(request))

    group_update_service = request.find_service(name="group_update")
    group_service = request.find_service(name="group")

    # Check for duplicate group
    groupid = appstruct.get("groupid", None)
    if groupid is not None:
        duplicate_group = group_service.fetch(pubid_or_groupid=groupid)
        if duplicate_group and (duplicate_group != group):
            raise HTTPConflict(
                _("group with groupid '{}' already exists").format(groupid)
            )

    # Need to make sure every resource-defined property is present, as this
    # is meant as a full-resource-replace operation.
    # TODO: This may be better handled in the schema at some point
    update_properties = {
        "name": appstruct["name"],
        "description": appstruct.get("description", ""),
        "groupid": appstruct.get("groupid", None),
    }

    group = group_update_service.update(group, **update_properties)

    # Note that this view takes a ``GroupUpsertContext`` but uses a ``GroupContext`` here
    return GroupJSONPresenter(GroupContext(group, request)).asdict(
        expand=["organization", "scopes"]
    )
Example #32
0
File: activity.py Project: kaydoh/h
    def search(self):
        # Make a copy of the query params to be consumed by search.
        query_params = self.parsed_query_params.copy()

        # Check whether a redirect is required.
        query.check_url(self.request, query_params)

        page_size = self.request.params.get("page_size", PAGE_SIZE)
        try:
            page_size = int(page_size)
        except ValueError:
            page_size = PAGE_SIZE

        # Fetch results.
        results = query.execute(self.request,
                                query_params,
                                page_size=page_size)

        groups_suggestions = []

        if self.request.user:
            for group in self.request.user.groups:
                groups_suggestions.append({
                    "name": group.name,
                    "pubid": group.pubid
                })

        def tag_link(tag):
            tag = parser.unparse({"tag": tag})
            return self.request.route_url("activity.search",
                                          _query=[("q", tag)])

        def username_from_id(userid):
            parts = split_user(userid)
            return parts["username"]

        def user_link(userid):
            username = username_from_id(userid)
            return self.request.route_url("activity.user_search",
                                          username=username)

        return {
            "search_results": results,
            "groups_suggestions": groups_suggestions,
            "page": paginate(self.request, results.total, page_size=page_size),
            "pretty_link": pretty_link,
            "q": self.request.params.get("q", ""),
            "tag_link": tag_link,
            "user_link": user_link,
            "username_from_id": username_from_id,
            # The message that is shown (only) if there's no search results.
            "zero_message": _("No annotations matched your search."),
        }
Example #33
0
def staff_add(request):
    """Make a given user a staff member."""
    username = request.params['add']
    user = models.User.get_by_username(username)
    if user is None:
        request.session.flash(
            _("User {username} doesn't exist.".format(username=username)),
            "error")
    else:
        user.staff = True
    index = request.route_path('admin_staff')
    return httpexceptions.HTTPSeeOther(location=index)
Example #34
0
def features_save(request):
    session.check_csrf_token(request)
    for feat in models.Feature.all():
        for attr in ['everyone', 'admins', 'staff']:
            val = request.POST.get('{0}[{1}]'.format(feat.name, attr))
            if val == 'on':
                setattr(feat, attr, True)
            else:
                setattr(feat, attr, False)
    request.session.flash(_("Changes saved."), "success")
    return httpexceptions.HTTPSeeOther(
        location=request.route_url('admin_features'))
Example #35
0
File: nipsa.py Project: djcun95/h
def nipsa_remove(request):
    username = request.params["remove"]

    if username:
        userid = util.user.userid_from_username(username, request)
        nipsa_service = request.find_service(name='nipsa')
        nipsa_service.unflag(userid)
    else:
        request.session.flash(_('Please supply a username!'), 'error')

    index = request.route_path("admin_nipsa")
    return httpexceptions.HTTPSeeOther(index)
Example #36
0
    def _validate_groupid(self, appstruct):
        """
        Validate the ``groupid`` to make sure it adheres to authority restrictions.

        ``groupid`` is only allowed if the authority of the group associated
        with it is not the default authority—i.e. this is a third-party group.

        :arg appstruct: Data, which may or may not contain a ``groupid`` entry
        :type appstruct: dict
        :raise h.schemas.ValidationError:

        """
        groupid = appstruct.get("groupid", None)
        if groupid is None:  # Nothing to validate
            return None

        if (self.group_authority is None) or (
            self.group_authority == self.default_authority
        ):
            # This is a first-party group
            raise ValidationError(
                "{err_msg} '{authority}'".format(
                    err_msg=_(
                        "groupid may only be set on groups oustide of the default authority"
                    ),
                    authority=self.default_authority,
                )
            )

        groupid_parts = split_groupid(groupid)

        if groupid_parts["authority"] != self.group_authority:
            # The authority part of the ``groupid`` doesn't match the
            # group's authority
            raise ValidationError(
                "{err_msg} '{groupid}'".format(
                    err_msg=_("Invalid authority specified in groupid"), groupid=groupid
                )
            )
Example #37
0
def users_activate(request):
    username = request.params['username']
    user = models.User.get_by_username(username)

    if user is None:
        request.session.flash(
            jinja2.Markup(_(
                "User {name} doesn't exist!".format(name=username))), 'error')
        return httpexceptions.HTTPFound(
            location=request.route_path('admin_users'))

    user.activate()

    request.session.flash(
        jinja2.Markup(
            _('User {name} has been activated!'.format(name=user.username))),
        'success')

    request.registry.notify(ActivationEvent(request, user))

    return httpexceptions.HTTPFound(location=request.route_path(
        'admin_users', _query=(('username', user.username), )))
Example #38
0
def staff_add(request):
    """Make a given user a staff member."""
    username = request.params["add"].strip()
    authority = request.params["authority"].strip()
    user = models.User.get_by_username(request.db, username, authority)
    if user is None:
        request.session.flash(
            _("User {username} doesn't exist.".format(username=username)),
            "error")
    else:
        user.staff = True
    index = request.route_path("admin.staff")
    return httpexceptions.HTTPSeeOther(location=index)
Example #39
0
def staff_add(request):
    """Make a given user a staff member."""
    username = request.params["add"].strip()
    authority = request.params["authority"].strip()
    user = models.User.get_by_username(request.db, username, authority)
    if user is None:
        request.session.flash(
            _("User {username} doesn't exist.".format(username=username)), "error"
        )
    else:
        user.staff = True
    index = request.route_path("admin.staff")
    return httpexceptions.HTTPSeeOther(location=index)
Example #40
0
def admins_add(request):
    """Make a given user an admin."""
    username = request.params['add'].strip()
    authority = request.params['authority'].strip()
    user = models.User.get_by_username(request.db, username, authority)
    if user is None:
        request.session.flash(
            _("User {username} doesn't exist.".format(username=username)),
            "error")
    else:
        user.admin = True
    index = request.route_path('admin_admins')
    return httpexceptions.HTTPSeeOther(location=index)
Example #41
0
File: users.py Project: ficolo/h
def users_activate(request):
    username = request.params['username']
    user = models.User.get_by_username(username)

    if user is None:
        request.session.flash(jinja2.Markup(_(
            "User {name} doesn't exist!".format(name=username))),
            'error')
        return httpexceptions.HTTPFound(
            location=request.route_path('admin_users'))

    user.activate()

    request.session.flash(jinja2.Markup(_(
        'User {name} has been activated!'.format(name=user.username))),
        'success')

    request.registry.notify(ActivationEvent(request, user))

    return httpexceptions.HTTPFound(
        location=request.route_path('admin_users',
                                    _query=(('username', user.username),)))
Example #42
0
File: admin.py Project: ningyifan/h
def staff_add(request):
    """Make a given user a staff member."""
    try:
        username = request.params['add']
    except KeyError:
        raise httpexceptions.HTTPNotFound()

    try:
        accounts.make_staff(username)
    except accounts.NoSuchUserError:
        request.session.flash(
            _("User {username} doesn't exist.".format(username=username)),
            "error")
    return staff_index(request)
Example #43
0
    def search(self):
        # Make a copy of the query params to be consumed by search.
        q = self.parsed_query_params.copy()

        # Check whether a redirect is required.
        query.check_url(self.request, q)

        page_size = self.request.params.get('page_size', PAGE_SIZE)
        try:
            page_size = int(page_size)
        except ValueError:
            page_size = PAGE_SIZE

        # Fetch results.
        results = query.execute(self.request, q, page_size=page_size)

        groups_suggestions = []

        if self.request.user:
            for group in self.request.user.groups:
                groups_suggestions.append({
                    'name': group.name,
                    'pubid': group.pubid
                })

        def tag_link(tag):
            q = parser.unparse({'tag': tag})
            return self.request.route_url('activity.search', _query=[('q', q)])

        def username_from_id(userid):
            parts = split_user(userid)
            return parts['username']

        def user_link(userid):
            username = username_from_id(userid)
            return self.request.route_url('activity.user_search',
                                          username=username)

        return {
            'search_results': results,
            'groups_suggestions': groups_suggestions,
            'page': paginate(self.request, results.total, page_size=page_size),
            'pretty_link': pretty_link,
            'q': self.request.params.get('q', ''),
            'tag_link': tag_link,
            'user_link': user_link,
            'username_from_id': username_from_id,
            # The message that is shown (only) if there's no search results.
            'zero_message': _('No annotations matched your search.'),
        }
Example #44
0
def users_activate(request):
    user = _form_request_user(request)

    user.activate()

    request.session.flash(jinja2.Markup(_(
        'User {name} has been activated!'.format(name=user.username))),
        'success')

    request.registry.notify(ActivationEvent(request, user))

    return httpexceptions.HTTPFound(
        location=request.route_path('admin_users',
                                    _query=(('username', user.username),)))
Example #45
0
File: admin.py Project: hylhero/h
def staff_add(request):
    """Make a given user a staff member."""
    try:
        username = request.params['add']
    except KeyError:
        raise httpexceptions.HTTPNotFound()

    try:
        accounts.make_staff(username)
    except accounts.NoSuchUserError:
        request.session.flash(
            _("User {username} doesn't exist.".format(username=username)),
            "error")
    return staff_index(request)
Example #46
0
File: activity.py Project: gnott/h
    def search(self):
        q = query.extract(self.request)

        # Check whether a redirect is required.
        query.check_url(self.request, q)

        page_size = self.request.params.get('page_size', PAGE_SIZE)
        try:
            page_size = int(page_size)
        except ValueError:
            page_size = PAGE_SIZE

        # Fetch results.
        results = query.execute(self.request, q, page_size=page_size)

        groups_suggestions = []

        if self.request.user:
            for group in self.request.user.groups:
                groups_suggestions.append({
                    'name': group.name,
                    'pubid': group.pubid
                })

        def tag_link(tag):
            q = parser.unparse({'tag': tag})
            return self.request.route_url('activity.search', _query=[('q', q)])

        def username_from_id(userid):
            parts = split_user(userid)
            return parts['username']

        def user_link(userid):
            username = username_from_id(userid)
            return self.request.route_url('activity.user_search',
                                          username=username)

        return {
            'search_results': results,
            'groups_suggestions': groups_suggestions,
            'page': paginate(self.request, results.total, page_size=page_size),
            'pretty_link': pretty_link,
            'q': self.request.params.get('q', ''),
            'tag_link': tag_link,
            'user_link': user_link,
            'username_from_id': username_from_id,
            # The message that is shown (only) if there's no search results.
            'zero_message': _('No annotations matched your search.'),
        }
Example #47
0
def cohorts_edit_remove(request):
    member_name = request.params['remove']
    cohort_id = request.matchdict['id']

    cohort = request.db.query(models.FeatureCohort).get(cohort_id)
    member = request.db.query(models.User).filter_by(username=member_name).first()
    try:
        cohort.members.remove(member)
    except ValueError:
        request.session.flash(
            _("User {member_name} doesn't exist.".format(member_name=member_name)),
            "error")

    url = request.route_url('admin_cohorts_edit', id=cohort_id)
    return httpexceptions.HTTPSeeOther(url)
Example #48
0
def nipsa_add(request):
    username = request.params['add'].strip()
    authority = request.params['authority'].strip()
    user = models.User.get_by_username(request.db, username, authority)

    if user is None:
        raise UserNotFoundError(
            _("Could not find user with username %s and authority %s" % (username, authority))
        )

    nipsa_service = request.find_service(name='nipsa')
    nipsa_service.flag(user)

    index = request.route_path("admin_nipsa")
    return httpexceptions.HTTPSeeOther(index)
Example #49
0
def cohorts_edit_add(request):
    member_name = request.params['add']
    cohort_id = request.matchdict['id']

    member = models.User.get_by_username(request.db, member_name)
    if member is None:
        request.session.flash(
            _("User {member_name} doesn't exist.".format(member_name=member_name)),
            "error")
    else:
        cohort = request.db.query(models.FeatureCohort).get(cohort_id)
        cohort.members.append(member)

    url = request.route_url('admin_cohorts_edit', id=cohort_id)
    return httpexceptions.HTTPSeeOther(url)
Example #50
0
def nipsa_add(request):
    username = request.params['add'].strip()
    authority = request.params['authority'].strip()
    user = models.User.get_by_username(request.db, username, authority)

    if user is None:
        raise UserNotFoundError(
            _("Could not find user with username %s and authority %s" %
              (username, authority)))

    nipsa_service = request.find_service(name='nipsa')
    nipsa_service.flag(user)

    index = request.route_path("admin_nipsa")
    return httpexceptions.HTTPSeeOther(index)
Example #51
0
def admins_add(request):
    """Make a given user an admin."""
    username = request.params["add"].strip()
    authority = request.params["authority"].strip()
    user = models.User.get_by_username(request.db, username, authority)
    if user is None:
        request.session.flash(
            # pylint:disable=consider-using-f-string
            _("User {username} doesn't exist.".format(username=username)),
            "error",
        )
    else:
        user.admin = True
    index = request.route_path("admin.admins")
    return httpexceptions.HTTPSeeOther(location=index)
Example #52
0
File: badge.py Project: bZichett/h
def badge_add(request):
    uri = request.params['add']
    item = models.Blocklist(uri=uri)
    request.db.add(item)

    # There's a uniqueness constraint on `uri`, so we flush the session,
    # catching any IntegrityError and responding appropriately.
    try:
        request.db.flush()
    except IntegrityError:
        request.db.rollback()
        msg = _("{uri} is already blocked.").format(uri=uri)
        request.session.flash(msg, 'error')

    index = request.route_path('admin_badge')
    return httpexceptions.HTTPSeeOther(location=index)
Example #53
0
    def search(self):
        # Make a copy of the query params to be consumed by search.
        q = self.parsed_query_params.copy()

        # Check whether a redirect is required.
        query.check_url(self.request, q)

        page_size = self.request.params.get("page_size", PAGE_SIZE)
        try:
            page_size = int(page_size)
        except ValueError:
            page_size = PAGE_SIZE

        # Fetch results.
        results = query.execute(self.request, q, page_size=page_size)

        groups_suggestions = []

        if self.request.user:
            for group in self.request.user.groups:
                groups_suggestions.append({"name": group.name, "pubid": group.pubid})

        def tag_link(tag):
            q = parser.unparse({"tag": tag})
            return self.request.route_url("activity.search", _query=[("q", q)])

        def username_from_id(userid):
            parts = split_user(userid)
            return parts["username"]

        def user_link(userid):
            username = username_from_id(userid)
            return self.request.route_url("activity.user_search", username=username)

        return {
            "search_results": results,
            "groups_suggestions": groups_suggestions,
            "page": paginate(self.request, results.total, page_size=page_size),
            "pretty_link": pretty_link,
            "q": self.request.params.get("q", ""),
            "tag_link": tag_link,
            "user_link": user_link,
            "username_from_id": username_from_id,
            # The message that is shown (only) if there's no search results.
            "zero_message": _("No annotations matched your search."),
        }
Example #54
0
File: activity.py Project: gnott/h
    def search(self):
        result = super(UserSearchController, self).search()

        result['opts'] = {'search_username': self.user.username}
        result['more_info'] = 'more_info' in self.request.params

        def domain(user):
            if not user.uri:
                return None
            return urlparse.urlparse(user.uri).netloc

        annotation_count = None
        if self.request.feature('total_shared_annotations'):
            user_annotation_counts = self.request.find_service(name='annotation_stats').user_annotation_counts(self.user.userid)
            annotation_count = user_annotation_counts['public']
            if self.request.authenticated_userid == self.user.userid:
                annotation_count = user_annotation_counts['total']

        result['stats'] = {
            'annotation_count': annotation_count,
        }

        result['user'] = {
            'name': self.user.display_name or self.user.username,
            'description': self.user.description,
            'registered_date': self.user.registered_date.strftime('%B, %Y'),
            'location': self.user.location,
            'uri': self.user.uri,
            'domain': domain(self.user),
            'orcid': self.user.orcid,
        }

        if self.request.user == self.user:
            result['user']['edit_url'] = self.request.route_url(
                'account_profile')

        if not result.get('q'):
            if self.request.user == self.user:
                # Tell the template that it should show "How to get started".
                result['zero_message'] = '__SHOW_GETTING_STARTED__'
            else:
                result['zero_message'] = _(
                    "{name} has not made any annotations yet.".format(
                        name=result['user']['name']))

        return result
Example #55
0
File: navbar.py Project: gnott/h
def navbar(context, request, search=None, opts=None):
    """
    The navigation bar displayed at the top of the page.

    :param search: The current page's search state, if relevant.
    :type search: h.activity.query.ActivityResults
    """

    groups_menu_items = []
    groups_suggestions = []
    user_activity_url = None
    username = None

    if request.user:
        for group in request.user.groups:
            groups_menu_items.append({
                'title': group.name,
                'link': request.route_url('group_read', pubid=group.pubid, slug=group.slug)
            })
            groups_suggestions.append({
                'name': group.name,
                'pubid': group.pubid
            })
        user_activity_url = request.route_url('activity.user_search',
                                              username=request.user.username)
        username = request.user.username

    route = request.matched_route

    if route and route.name in ['group_read', 'activity.user_search']:
        search_url = request.current_route_url()
    else:
        search_url = request.route_url('activity.search')

    return {
        'settings_menu_items': [
            {'title': _('Account details'), 'link': request.route_url('account')},
            {'title': _('Edit profile'), 'link': request.route_url('account_profile')},
            {'title': _('Notifications'), 'link': request.route_url('account_notifications')},
            {'title': _('Developer'), 'link': request.route_url('account_developer')},
        ],
        'signout_item': {'title': _('Sign out'), 'link': request.route_url('logout')},
        'groups_menu_items': groups_menu_items,
        'groups_suggestions': groups_suggestions,
        'create_group_item':
            {'title': _('Create new group'), 'link': request.route_url('group_create')},
        'username': username,
        'username_url': user_activity_url,
        'search': search,
        'search_url': search_url,
        'q': request.params.get('q', ''),
        'opts': opts or {},
    }