Beispiel #1
0
    def save(self, force_insert=False, force_update=False, *args, **kwargs):
        """
        Custom save method.  When present, replace a special token string
        (configured in django settings as **PID_REPLACEMENT_TOKEN**) in the
        target uri with the noid.  Also ensures that pid and noid stay
        synchronized, check that qualifier does not contain any invalid characters,
        and normalizes ARK qualifier so it will be resolved correctly.
        """
        # a special token in target URI should be replaced with minted noid
        if (self.uri.find(settings.PID_REPLACEMENT_TOKEN) != -1):
            # Note: not using self.noid because it doesn't seem to be set yet
            self.uri = self.uri.replace(settings.PID_REPLACEMENT_TOKEN,
                                        self.pid.pid)

        #keep noid and pid in sync
        if (not self.noid):
            self.noid = self.pid.pid
        elif (self.noid != self.pid.pid):
            raise ValidationError("Target.noid(%s) and Pid(%s) do not match)" %
                                  (self.noid, self.pid.pid))

        # if qualifier is not valid, it should not be saved
        if not (valid_qualifier(self.qualify)):
            raise ValidationError(
                "Qualifier '%s' contains invalid characters" % (self.qualify))

        # normalize so qualifier will be found by the resolver
        self.qualify = normalize_ark(self.qualify)
        return super(Target, self).save(force_insert=force_insert,
                                        force_update=force_update,
                                        *args,
                                        **kwargs)
Beispiel #2
0
    def save(self, force_insert=False, force_update=False, *args, **kwargs):
        """
        Custom save method.  When present, replace a special token string
        (configured in django settings as **PID_REPLACEMENT_TOKEN**) in the
        target uri with the noid.  Also ensures that pid and noid stay
        synchronized, check that qualifier does not contain any invalid characters,
        and normalizes ARK qualifier so it will be resolved correctly.
        """
        # a special token in target URI should be replaced with minted noid
        if (self.uri.find(settings.PID_REPLACEMENT_TOKEN) != -1):
            # Note: not using self.noid because it doesn't seem to be set yet
            self.uri = self.uri.replace(settings.PID_REPLACEMENT_TOKEN, self.pid.pid)

        #keep noid and pid in sync
        if(not self.noid):
            self.noid = self.pid.pid
        elif(self.noid != self.pid.pid):
            raise ValidationError("Target.noid(%s) and Pid(%s) do not match)"%(self.noid, self.pid.pid))

        # if qualifier is not valid, it should not be saved
        if not(valid_qualifier(self.qualify)):
            raise ValidationError("Qualifier '%s' contains invalid characters"%(self.qualify))

        # normalize so qualifier will be found by the resolver
        self.qualify = normalize_ark(self.qualify)
        return super(Target, self).save(force_insert=force_insert, force_update=force_update, *args, **kwargs)
Beispiel #3
0
 def test_valid_qualifier(self):
     self.assertTrue(valid_qualifier("45ae%"),
                     "'45ae%' is a valid qualifier")
     self.assertFalse(valid_qualifier("45ae^"),
                      "'45ae^' is not a valid qualifier")
Beispiel #4
0
    def characters_valid(self):
        for t in self.target_set.exclude(qualify=''):
            if not valid_qualifier(t.qualify):
                return "<span style='color:red'>NO</span>"

        return "<span style='color:green'>Yes</span>"
Beispiel #5
0
    def characters_valid(self):
        for t in self.target_set.exclude(qualify=''):
            if not valid_qualifier(t.qualify):
                return "<span style='color:red'>NO</span>"

        return "<span style='color:green'>Yes</span>"
Beispiel #6
0
def create_pid(request, type):
    '''On POST, create a new ARK or PURL.  On successful creation, returns a
    response with status code 201 (Created), and response content is the resolvables
    url for the newly minted ARK or PURL.  If required parameters are missing
    or any parameters are invalid (e.g., referencing a Proxy or Policy that does
    not exist), the returned response will have a status code 400 (Bad Request),
    and the content of the response will be an explanatory message.

    Supported POST parameters:
        * domain - REQUIRED; domain should be in URI resource format, e.g.
          http://pid.emory.edu/domains/1/
        * target_uri - REQUIRED; URL that the new ARK or PURL should resolve to
        * name - label or title for the new pid
        * external_system_id - external system name
        * external_system_key - key or identifier in the specified external system
        * policy - policy by name (if this pid needs a different policy from its
          domain)
        * proxy - proxy to use when resolving target url; specify by name
        * qualifier - target should be created with the specified target; **ARK only**

    :param type: type of pid to create - ark or purl

    Example create urls::

        http://pid.emory.edu/ark/ - create a new ARK
        http://pid.emory.edu/purl/ - create a new PURL

    '''
    if request.method == 'POST':
        # TODO: require ssl ?
        if not request.user.is_authenticated():
            # 401 unauthorized - not logged in or invalid credentials
            return HttpResponseUnauthorized(BASIC_AUTH_REALM)
        elif not request.user.has_perm('pid.add_pid'):
            # 403 Forbidden - logged in but insufficient permissions
            return HttpResponseForbidden()

        try:
            # if required fields are not present, return an error message
            if 'domain' not in request.POST or 'target_uri' not in request.POST:
                raise BadRequest('domain and target_uri are required')
            # incompatible options - qualifier only makes sense for purls
            if 'qualifier' in request.POST and type == 'purl':
                raise BadRequest('Purl targets can not have qualifiers')

            # domain should be passed in as resource URI - resolve to model instance
            domain = _domain_from_uri(request.POST['domain'])

            # assemble the data for creating the new pid
            # - required fields
            pid_opts = {
                'type':
                type.title(),  # url uses lower case, model requires title case
                'domain': domain,
                'creator_id': request.user.id,
                'editor_id': request.user.id
            }
            # - optional fields
            if 'name' in request.POST:
                pid_opts['name'] = request.POST['name']
            # could you have an external system id and not a ext-sys key? or vice versa?
            if 'external_system_id' in request.POST:
                try:
                    pid_opts['ext_system'] = ExtSystem.objects.get(
                        name=request.POST['external_system_id'])
                except ObjectDoesNotExist:
                    raise BadRequest("External System '%s' not found" %
                                     request.POST['external_system_id'])
            if 'external_system_key' in request.POST:
                pid_opts['ext_system_key'] = request.POST[
                    'external_system_key']
            if 'policy' in request.POST:
                try:
                    pid_opts['policy'] = Policy.objects.get(
                        title=request.POST['policy'])
                except ObjectDoesNotExist:
                    raise BadRequest("Policy '%s' not found" %
                                     request.POST['policy'])

            # target can't be created until after the noid is minted
            # - init target options before creating pid to be sure they are valid
            #   (i.e., if a proxy is specified, it exists)
            target_opts = {'uri': request.POST['target_uri']}
            if 'proxy' in request.POST:
                try:
                    target_opts['proxy'] = Proxy.objects.get(
                        name=request.POST['proxy'])
                except ObjectDoesNotExist:
                    raise BadRequest("Proxy '%s' not found" %
                                     request.POST['proxy'])
            if 'qualifier' in request.POST:
                # an invalid qualifier would normally get caught when a target is saved
                # checking here to avoid creating a new Pid if the qualifier is invalid
                if not valid_qualifier(request.POST['qualifier']):
                    raise BadRequest(
                        "Qualifier '%s' contains invalid characters" %
                        request.POST['qualifier'])
                target_opts['qualify'] = request.POST['qualifier']

            # create the pid, and then save to mint the noid before target is created
            p = Pid(**pid_opts)
            p.save()
            _log_rest_action(request, p, ADDITION,
                             'Added pid:%s via rest api' % p.__unicode__())
            t = p.target_set.create(**target_opts)
            _log_rest_action(
                request, t, ADDITION,
                'Added target:%s for pid:%s via rest api' %
                (t.__unicode__(), p.__unicode__()))

            # return the resolvable url (purl/ark) for the new target
            return HttpResponse(t.get_resolvable_url(),
                                status=201)  # 201 Created

        except BadRequest as err:
            # return a response with status code 400, Bad Request
            return HttpResponseBadRequest('Error: %s' % err)

    # if request method is not POST, return 405 method not allowed
    return HttpResponseNotAllowed(['POST'])
Beispiel #7
0
def create_pid(request, type):
    """On POST, create a new ARK or PURL.  On successful creation, returns a
    response with status code 201 (Created), and response content is the resolvables
    url for the newly minted ARK or PURL.  If required parameters are missing
    or any parameters are invalid (e.g., referencing a Proxy or Policy that does
    not exist), the returned response will have a status code 400 (Bad Request),
    and the content of the response will be an explanatory message.

    Supported POST parameters:
        * domain - REQUIRED; domain should be in URI resource format, e.g.
          http://pid.emory.edu/domains/1/
        * target_uri - REQUIRED; URL that the new ARK or PURL should resolve to
        * name - label or title for the new pid
        * external_system_id - external system name
        * external_system_key - key or identifier in the specified external system
        * policy - policy by name (if this pid needs a different policy from its
          domain)
        * proxy - proxy to use when resolving target url; specify by name
        * qualifier - target should be created with the specified target; **ARK only**

    :param type: type of pid to create - ark or purl

    Example create urls::

        http://pid.emory.edu/ark/ - create a new ARK
        http://pid.emory.edu/purl/ - create a new PURL

    """
    if request.method == "POST":
        # TODO: require ssl ?
        if not request.user.is_authenticated():
            # 401 unauthorized - not logged in or invalid credentials
            return HttpResponseUnauthorized(BASIC_AUTH_REALM)
        elif not request.user.has_perm("pid.add_pid"):
            # 403 Forbidden - logged in but insufficient permissions
            return HttpResponseForbidden()

        try:
            # if required fields are not present, return an error message
            if "domain" not in request.POST or "target_uri" not in request.POST:
                raise BadRequest("domain and target_uri are required")
            # incompatible options - qualifier only makes sense for purls
            if "qualifier" in request.POST and type == "purl":
                raise BadRequest("Purl targets can not have qualifiers")

            # domain should be passed in as resource URI - resolve to model instance
            domain = _domain_from_uri(request.POST["domain"])

            # assemble the data for creating the new pid
            # - required fields
            pid_opts = {
                "type": type.title(),  # url uses lower case, model requires title case
                "domain": domain,
                "creator_id": request.user.id,
                "editor_id": request.user.id,
            }
            # - optional fields
            if "name" in request.POST:
                pid_opts["name"] = request.POST["name"]
            # could you have an external system id and not a ext-sys key? or vice versa?
            if "external_system_id" in request.POST:
                try:
                    pid_opts["ext_system"] = ExtSystem.objects.get(name=request.POST["external_system_id"])
                except ObjectDoesNotExist:
                    raise BadRequest("External System '%s' not found" % request.POST["external_system_id"])
            if "external_system_key" in request.POST:
                pid_opts["ext_system_key"] = request.POST["external_system_key"]
            if "policy" in request.POST:
                try:
                    pid_opts["policy"] = Policy.objects.get(title=request.POST["policy"])
                except ObjectDoesNotExist:
                    raise BadRequest("Policy '%s' not found" % request.POST["policy"])

            # target can't be created until after the noid is minted
            # - init target options before creating pid to be sure they are valid
            #   (i.e., if a proxy is specified, it exists)
            target_opts = {"uri": request.POST["target_uri"]}
            if "proxy" in request.POST:
                try:
                    target_opts["proxy"] = Proxy.objects.get(name=request.POST["proxy"])
                except ObjectDoesNotExist:
                    raise BadRequest("Proxy '%s' not found" % request.POST["proxy"])
            if "qualifier" in request.POST:
                # an invalid qualifier would normally get caught when a target is saved
                # checking here to avoid creating a new Pid if the qualifier is invalid
                if not valid_qualifier(request.POST["qualifier"]):
                    raise BadRequest("Qualifier '%s' contains invalid characters" % request.POST["qualifier"])
                target_opts["qualify"] = request.POST["qualifier"]

            # create the pid, and then save to mint the noid before target is created
            p = Pid(**pid_opts)
            p.save()
            _log_rest_action(request, p, ADDITION, "Added pid:%s via rest api" % p.__unicode__())
            t = p.target_set.create(**target_opts)
            _log_rest_action(
                request, t, ADDITION, "Added target:%s for pid:%s via rest api" % (t.__unicode__(), p.__unicode__())
            )

            # return the resolvable url (purl/ark) for the new target
            return HttpResponse(t.get_resolvable_url(), status=201)  # 201 Created

        except BadRequest as err:
            # return a response with status code 400, Bad Request
            return HttpResponseBadRequest("Error: %s" % err)

    # if request method is not POST, return 405 method not allowed
    return HttpResponseNotAllowed(["POST"])
Beispiel #8
0
 def test_valid_qualifier(self):
     self.assertTrue(valid_qualifier("45ae%"), "'45ae%' is a valid qualifier")
     self.assertFalse(valid_qualifier("45ae^"), "'45ae^' is not a valid qualifier")