Exemple #1
0
    def delete(cls, id, account, dry_run=False):
        # as long as authentication (in the layer above) has been successful, and the account exists, then
        # we are good to proceed
        if account is None:
            raise Api401Error()

        applicationService = DOAJ.applicationService()
        authService = DOAJ.authorisationService()

        if dry_run:
            application, _ = applicationService.application(id)
            if application is not None:
                try:
                    authService.can_edit_application(account, application)
                except AuthoriseException as e:
                    if e.reason == e.WRONG_STATUS:
                        raise Api403Error()
                    raise Api404Error()
            else:
                raise Api404Error()
        else:
            try:
                applicationService.delete_application(id, account)
            except AuthoriseException as e:
                if e.reason == e.WRONG_STATUS:
                    raise Api403Error()
                raise Api404Error()
            except NoSuchObjectException as e:
                raise Api404Error()
Exemple #2
0
    def retrieve(cls, id, account):

        # is the article id valid?
        ar = models.Article.pull(id)
        if ar is None:
            raise Api404Error()

        # at this point we're happy to return the article if it's
        # meant to be seen by the public
        if ar.is_in_doaj():
            try:
                return OutgoingArticleDO.from_model(ar)
            except:
                raise Api500Error()

        # as long as authentication (in the layer above) has been successful, and the account exists, then
        # we are good to proceed
        if account is None or account.is_anonymous:
            raise Api401Error()

        # Check we're allowed to retrieve this article
        articleService = DOAJ.articleService()
        if not articleService.is_legitimate_owner(ar, account.id):
            raise Api404Error()  # not found for this account

        # Return the article
        oa = OutgoingArticleDO.from_model(ar)
        return oa
Exemple #3
0
    def retrieve(cls, jid, account):
        # is the journal id valid
        try:
            j = models.Journal.pull(jid)
        except Exception as e:
            raise Api400Error(str(e))
        if j is None:
            raise Api404Error()

        # at this point we're happy to return the journal if it's
        # meant to be seen by the public
        if j.is_in_doaj():
            return OutgoingJournal.from_model(j)

        # as long as authentication (in the layer above) has been successful, and the account exists, then
        # we are good to proceed
        if account is None:
            raise Api401Error()

        # this journal's metadata is not currently published in DOAJ, so
        # we need to check ownership
        # is the current account the owner of the journal
        # if not we raise a 404 because that id does not exist for that user account.
        if account.is_anonymous or j.owner != account.id:
            raise Api404Error()

        return OutgoingJournal.from_model(j)
Exemple #4
0
    def retrieve(cls, id, account):
        # as long as authentication (in the layer above) has been successful, and the account exists, then
        # we are good to proceed
        if account is None:
            raise Api401Error()

        # is the application id valid
        ap = models.Suggestion.pull(id)
        if ap is None:
            raise Api404Error()

        # is the current account the owner of the application
        # if not we raise a 404 because that id does not exist for that user account.
        if ap.owner != account.id:
            raise Api404Error()

        # if we get to here we're going to give the user back the application
        oa = OutgoingApplication.from_model(ap)
        return oa
Exemple #5
0
    def delete(cls, id, account, dry_run=False):
        # as long as authentication (in the layer above) has been successful, and the account exists, then
        # we are good to proceed
        if account is None:
            raise Api401Error()

        # now see if there's something for us to delete
        ar = models.Article.pull(id)
        if ar is None:
            raise Api404Error()

        # Check we're allowed to retrieve this article
        articleService = DOAJ.articleService()
        if not articleService.is_legitimate_owner(ar, account.id):
            raise Api404Error()  # not found for this account

        # issue the delete (no record of the delete required)
        if not dry_run:
            ar.delete()
Exemple #6
0
    def update(cls, id, data, account):
        # as long as authentication (in the layer above) has been successful, and the account exists, then
        # we are good to proceed
        if account is None:
            raise Api401Error()

        # now see if there's something for us to delete
        ar = models.Article.pull(id)
        if ar is None:
            raise Api404Error()

        # Check we're allowed to edit this article
        articleService = DOAJ.articleService()
        if not articleService.is_legitimate_owner(ar, account.id):
            raise Api404Error()  # not found for this account

        # next thing to do is a structural validation of the replacement data, by instantiating the object
        try:
            ia = IncomingArticleDO(data)
        except dataobj.DataStructureException as e:
            raise Api400Error(str(e))

        # if that works, convert it to an Article object bringing over everything outside the
        # incoming article from the original article
        new_ar = ia.to_article_model(ar)

        # we need to ensure that any properties of the existing article that aren't allowed to change
        # are copied over
        new_ar.set_id(id)
        new_ar.set_created(ar.created_date)
        new_ar.bibjson().set_subjects(ar.bibjson().subjects())
        new_ar = cls.__handle_journal_info(new_ar)

        # finally save the new article, and return to the caller
        new_ar.save()
        return new_ar
Exemple #7
0
    def create(cls, data, account, dry_run=False):
        # as long as authentication (in the layer above) has been successful, and the account exists, then
        # we are good to proceed
        if account is None:
            raise Api401Error()

        # first thing to do is a structural validation, but instantiating the data object
        try:
            ia = IncomingApplication(data)
        except dataobj.DataStructureException as e:
            raise Api400Error(e.message)

        # if that works, convert it to a Suggestion object
        ap = ia.to_application_model()

        # now augment the suggestion object with all the additional information it requires
        #
        # suggester name and email from the user account
        ap.set_suggester(account.name, account.email)

        # they are not allowed to set "subject"
        ap.bibjson().remove_subjects()

        # if this is an update request on an existing journal
        if ap.current_journal is not None:
            # DOAJ BLL for this request
            applicationService = DOAJ.applicationService()

            # load the update_request application either directly or by crosswalking the journal object
            vanilla_ap = None
            jlock = None
            alock = None
            try:
                vanilla_ap, jlock, alock = applicationService.update_request_for_journal(
                    ap.current_journal, account=account)
            except AuthoriseException as e:
                if e.reason == AuthoriseException.WRONG_STATUS:
                    raise Api403Error(
                        "The application is no longer in a state in which it can be edited via the API"
                    )
                else:
                    raise Api404Error()
            except lock.Locked as e:
                raise Api409Error(
                    "The application you are requesting an update for is locked for editing by another user"
                )

            # if we didn't find an application or journal, 404 the user
            if vanilla_ap is None:
                if jlock is not None: jlock.delete()
                if alock is not None: alock.delete()
                raise Api404Error()

            # convert the incoming application into the web form
            form = MultiDict(xwalk.SuggestionFormXWalk.obj2form(ap))

            fc = formcontext.ApplicationFormFactory.get_form_context(
                role="publisher", form_data=form, source=vanilla_ap)
            if fc.validate():
                try:
                    save_target = not dry_run
                    fc.finalise(save_target=save_target, email_alert=False)
                    return fc.target
                except formcontext.FormContextException as e:
                    raise Api400Error(e.message)
                finally:
                    if jlock is not None: jlock.delete()
                    if alock is not None: alock.delete()
            else:
                if jlock is not None: jlock.delete()
                if alock is not None: alock.delete()
                raise Api400Error(cls._validation_message(fc))

        # otherwise, this is a brand-new application
        else:
            # convert the incoming application into the web form
            form = MultiDict(xwalk.SuggestionFormXWalk.obj2form(ap))

            # create a template that will hold all the values we want to persist across the form submission
            template = models.Suggestion()
            template.set_owner(account.id)

            fc = formcontext.ApplicationFormFactory.get_form_context(
                form_data=form, source=template)
            if fc.validate():
                try:
                    save_target = not dry_run
                    fc.finalise(save_target=save_target, email_alert=False)
                    return fc.target
                except formcontext.FormContextException as e:
                    raise Api400Error(e.message)
            else:
                raise Api400Error(cls._validation_message(fc))
Exemple #8
0
    def update(cls, id, data, account):
        # as long as authentication (in the layer above) has been successful, and the account exists, then
        # we are good to proceed
        if account is None:
            raise Api401Error()

        # next thing to do is a structural validation of the replacement data, by instantiating the object
        try:
            ia = IncomingApplication(data)
        except dataobj.DataStructureException as e:
            raise Api400Error(e.message)

        # now see if there's something for us to update
        ap = models.Suggestion.pull(id)
        if ap is None:
            raise Api404Error()

        # if that works, convert it to a Suggestion object
        new_ap = ia.to_application_model()

        # now augment the suggestion object with all the additional information it requires
        #
        # suggester name and email from the user account
        new_ap.set_suggester(account.name, account.email)

        # they are not allowed to set "subject"
        new_ap.bibjson().remove_subjects()

        # DOAJ BLL for this request
        applicationService = DOAJ.applicationService()
        authService = DOAJ.authorisationService()

        # if a current_journal is specified on the incoming data
        if new_ap.current_journal is not None:
            # once an application has a current_journal specified, you can't change it
            if new_ap.current_journal != ap.current_journal:
                raise Api400Error(
                    "current_journal cannot be changed once set.  current_journal is {x}; this request tried to change it to {y}"
                    .format(x=ap.current_journal, y=new_ap.current_journal))

            # load the update_request application either directly or by crosswalking the journal object
            vanilla_ap = None
            jlock = None
            alock = None
            try:
                vanilla_ap, jlock, alock = applicationService.update_request_for_journal(
                    new_ap.current_journal, account=account)
            except AuthoriseException as e:
                if e.reason == AuthoriseException.WRONG_STATUS:
                    raise Api403Error(
                        "The application is no longer in a state in which it can be edited via the API"
                    )
                else:
                    raise Api404Error()
            except lock.Locked as e:
                raise Api409Error(
                    "The application is locked for editing by another user - most likely your application is being reviewed by an editor"
                )

            # if we didn't find an application or journal, 404 the user
            if vanilla_ap is None:
                if jlock is not None: jlock.delete()
                if alock is not None: alock.delete()
                raise Api404Error()

            # convert the incoming application into the web form
            form = MultiDict(xwalk.SuggestionFormXWalk.obj2form(new_ap))

            fc = formcontext.ApplicationFormFactory.get_form_context(
                role="publisher", form_data=form, source=vanilla_ap)
            if fc.validate():
                try:
                    fc.finalise(email_alert=False)
                    return fc.target
                except formcontext.FormContextException as e:
                    raise Api400Error(e.message)
                finally:
                    if jlock is not None: jlock.delete()
                    if alock is not None: alock.delete()
            else:
                if jlock is not None: jlock.delete()
                if alock is not None: alock.delete()
                raise Api400Error(cls._validation_message(fc))
        else:
            try:
                authService.can_edit_application(account, ap)
            except AuthoriseException as e:
                if e.reason == e.WRONG_STATUS:
                    raise Api403Error(
                        "The application is no longer in a state in which it can be edited via the API"
                    )
                else:
                    raise Api404Error()

            # convert the incoming application into the web form
            form = MultiDict(xwalk.SuggestionFormXWalk.obj2form(new_ap))

            fc = formcontext.ApplicationFormFactory.get_form_context(
                form_data=form, source=ap)
            if fc.validate():
                try:
                    fc.finalise(email_alert=False)
                    return fc.target
                except formcontext.FormContextException as e:
                    raise Api400Error(e.message)
            else:
                raise Api400Error(cls._validation_message(fc))
Exemple #9
0
def missing_resource(invalid_path):
    docs_url = app.config.get("BASE_URL", "") + url_for('.docs')
    spec_url = app.config.get("BASE_URL", "") + url_for('.api_spec')
    raise Api404Error("No endpoint at {0}. See {1} for valid paths or read the documentation at {2}.".format(invalid_path, spec_url, docs_url))