def basic_auth(): auth = request.authorization if not auth: raise SwordError(status=401, empty=True) authobj = check_auth(auth.username, auth.password) if authobj is None: raise SwordError(status=401, empty=True) return authobj
def check_auth(username, password, obo=None): authenticator = Authenticator(config) auth = None try: auth = authenticator.basic_authenticate(username, password, obo) except AuthException as e: if e.authentication_failed: raise SwordError(status=401, empty=True) elif e.target_owner_unknown: raise SwordError(error_uri=Errors.target_owner_unknown, msg="unknown user " + str(obo) + " as on behalf of user", author="JPER") return auth
def get_deposit(auth): d = DepositRequest() mapped_headers = request.headers h = HttpHeaders() d.set_from_headers(h.get_sword_headers(mapped_headers)) if d.content_length > config.max_upload_size: raise SwordError( error_uri=Errors.max_upload_size_exceeded, msg="Max upload size is " + str(config.max_upload_size) + "; incoming content length was " + str(d.content_length), author="JPER") # get the body as a stream (which should be available as the mimetype # is not handled by default by Flask, we hope!) d.content_file = request.stream # set the filename d.filename = h.extract_filename(mapped_headers) # now just attach the authentication data and return d.auth = auth return d
def entry(entry_id): """ GET a representation of the container in the appropriate (content negotiated) format as identified by the supplied id Args: - entry_id: The ID of the container as supplied in the request URL Returns a representation of the container: SSS will return either the Atom Entry identical to the one supplied as a deposit receipt or the pure RDF/XML Statement depending on the Accept header """ # authenticate try: auth = basic_auth() ss = SwordServer(config, auth) # first thing we need to do is check that there is an object to return, because otherwise we may throw a # 415 Unsupported Media Type without looking first to see if there is even any media to content negotiate for # which would be weird from a client perspective if not ss.container_exists(entry_id): abort(404) # get the content negotiation headers accept_header = request.headers.get("Accept") accept_packaging_header = request.headers.get("Accept-Packaging") # do the negotiation default_accept_parameters, acceptable = config.get_container_formats() cn = ContentNegotiator(default_accept_parameters, acceptable) accept_parameters = cn.negotiate(accept=accept_header) app.logger.info("Container requested in format: " + str(accept_parameters)) # did we successfully negotiate a content type? if accept_parameters is None: raise SwordError(error_uri=Errors.content, status=415, empty=True) # now actually get hold of the representation of the container and send it to the client cont = ss.get_container(entry_id, accept_parameters) resp = make_response(cont) if cont is not None: resp.mimetype = accept_parameters.content_type.mimetype() return resp except SwordError as e: return raise_error(e)