예제 #1
0
def authorize(request, client):
    # TODO: Get rid of the JSON responses in this view, it's called by the
    # user-agent, not the client.
    user_client_relation = OAuthUserClient.query.filter(
            (OAuthUserClient.user == request.user)
            & (OAuthUserClient.client == client))

    if user_client_relation.filter(OAuthUserClient.state ==
            u'approved').count():
        redirect_uri = None

        if client.type == u'public':
            if not client.redirect_uri:
                return json_response({
                    'status': 400,
                    'errors':
                        [u'Public clients MUST have a redirect_uri pre-set']},
                        _disable_cors=True)

            redirect_uri = client.redirect_uri

        if client.type == u'confidential':
            redirect_uri = request.GET.get('redirect_uri', client.redirect_uri)
            if not redirect_uri:
                return json_response({
                    'status': 400,
                    'errors': [u'Can not find a redirect_uri for client: {0}'\
                            .format(client.name)]}, _disable_cors=True)

        code = OAuthCode()
        code.code = unicode(uuid4())
        code.user = request.user
        code.client = client
        code.save()

        redirect_uri = ''.join([
            redirect_uri,
            '?',
            urlencode({'code': code.code})])

        _log.debug('Redirecting to {0}'.format(redirect_uri))

        return exc.HTTPFound(location=redirect_uri)
    else:
        # Show prompt to allow client to access data
        # - on accept: send the user agent back to the redirect_uri with the
        # code parameter
        # - on deny: send the user agent back to the redirect uri with error
        # information
        form = AuthorizationForm(request.form)
        form.client_id.data = client.id
        form.next.data = request.url
        return render_to_response(
                request,
                'oauth/authorize.html',
                {'form': form,
                'client': client})
def post_entry(request):
    _log.debug('Posting entry')

    if request.method == 'OPTIONS':
        return json_response({'status': 200})

    if request.method != 'POST':
        _log.debug('Must POST against post_entry')
        raise BadRequest()

    if not 'file' in request.files \
            or not isinstance(request.files['file'], FileStorage) \
            or not request.files['file'].stream:
        _log.debug('File field not found')
        raise BadRequest()

    media_file = request.files['file']

    media_type, media_manager = sniff_media(media_file)

    entry = request.db.MediaEntry()
    entry.media_type = unicode(media_type)
    entry.title = unicode(request.form.get('title')
            or splitext(media_file.filename)[0])

    entry.description = unicode(request.form.get('description'))
    entry.license = unicode(request.form.get('license', ''))

    entry.uploader = request.user.id

    entry.generate_slug()

    # queue appropriately
    queue_file = prepare_queue_task(request.app, entry, media_file.filename)

    with queue_file:
        queue_file.write(request.files['file'].stream.read())

    # Save now so we have this data before kicking off processing
    entry.save()

    if request.form.get('callback_url'):
        metadata = request.db.ProcessingMetaData()
        metadata.media_entry = entry
        metadata.callback_url = unicode(request.form['callback_url'])
        metadata.save()

    # Pass off to processing
    #
    # (... don't change entry after this point to avoid race
    # conditions with changes to the document via processing code)
    run_process_media(entry)

    return json_response(get_entry_serializable(entry, request.urlgen))
예제 #3
0
def post_entry(request):
    _log.debug("Posting entry")

    if request.method == "OPTIONS":
        return json_response({"status": 200})

    if request.method != "POST":
        _log.debug("Must POST against post_entry")
        raise BadRequest()

    if not check_file_field(request, "file"):
        _log.debug("File field not found")
        raise BadRequest()

    media_file = request.files["file"]

    media_type, media_manager = sniff_media(media_file)

    entry = request.db.MediaEntry()
    entry.media_type = unicode(media_type)
    entry.title = unicode(request.form.get("title") or splitext(media_file.filename)[0])

    entry.description = unicode(request.form.get("description"))
    entry.license = unicode(request.form.get("license", ""))

    entry.uploader = request.user.id

    entry.generate_slug()

    # queue appropriately
    queue_file = prepare_queue_task(request.app, entry, media_file.filename)

    with queue_file:
        queue_file.write(request.files["file"].stream.read())

    # Save now so we have this data before kicking off processing
    entry.save()

    if request.form.get("callback_url"):
        metadata = request.db.ProcessingMetaData()
        metadata.media_entry = entry
        metadata.callback_url = unicode(request.form["callback_url"])
        metadata.save()

    # Pass off to processing
    #
    # (... don't change entry after this point to avoid race
    # conditions with changes to the document via processing code)
    feed_url = request.urlgen("mediagoblin.user_pages.atom_feed", qualified=True, user=request.user.username)
    run_process_media(entry, feed_url)

    return json_response(get_entry_serializable(entry, request.urlgen))
예제 #4
0
def authorize(request, client):
    # TODO: Get rid of the JSON responses in this view, it's called by the
    # user-agent, not the client.
    user_client_relation = OAuthUserClient.query.filter(
        (OAuthUserClient.user == request.user) & (OAuthUserClient.client == client)
    )

    if user_client_relation.filter(OAuthUserClient.state == u"approved").count():
        redirect_uri = None

        if client.type == u"public":
            if not client.redirect_uri:
                return json_response(
                    {"status": 400, "errors": [u"Public clients MUST have a redirect_uri pre-set"]}, _disable_cors=True
                )

            redirect_uri = client.redirect_uri

        if client.type == u"confidential":
            redirect_uri = request.GET.get("redirect_uri", client.redirect_uri)
            if not redirect_uri:
                return json_response(
                    {"status": 400, "errors": [u"Can not find a redirect_uri for client: {0}".format(client.name)]},
                    _disable_cors=True,
                )

        code = OAuthCode()
        code.code = unicode(uuid4())
        code.user = request.user
        code.client = client
        code.save()

        redirect_uri = "".join([redirect_uri, "?", urlencode({"code": code.code})])

        _log.debug("Redirecting to {0}".format(redirect_uri))

        return redirect(request, location=redirect_uri)
    else:
        # Show prompt to allow client to access data
        # - on accept: send the user agent back to the redirect_uri with the
        # code parameter
        # - on deny: send the user agent back to the redirect uri with error
        # information
        form = AuthorizationForm(request.form)
        form.client_id.data = client.id
        form.next.data = request.url
        return render_to_response(request, "oauth/authorize.html", {"form": form, "client": client})
예제 #5
0
    def wrapper(request, *args, **kw):
        if not request.GET.get('client_id'):
            return json_response({
                'status': 400,
                'errors': [u'No client identifier in URL']},
                _disable_cors=True)

        client = OAuthClient.query.filter(
                OAuthClient.identifier == request.GET.get('client_id')).first()

        if not client:
            return json_response({
                'status': 400,
                'errors': [u'No such client identifier']},
                _disable_cors=True)

        return controller(request, client)
예제 #6
0
def access_token(request):
    if request.GET.get('code'):
        code = OAuthCode.query.filter(OAuthCode.code ==
                request.GET.get('code')).first()

        if code:
            if code.client.type == u'confidential':
                client_identifier = request.GET.get('client_id')

                if not client_identifier:
                    return json_response({
                        'error': 'invalid_request',
                        'error_description':
                            'Missing client_id in request'})

                client_secret = request.GET.get('client_secret')

                if not client_secret:
                    return json_response({
                        'error': 'invalid_request',
                        'error_description':
                            'Missing client_secret in request'})

                if not client_secret == code.client.secret or \
                        not client_identifier == code.client.identifier:
                    return json_response({
                        'error': 'invalid_client',
                        'error_description':
                            'The client_id or client_secret does not match the'
                            ' code'})

            token = OAuthToken()
            token.token = unicode(uuid4())
            token.user = code.user
            token.client = code.client
            token.save()

            access_token_data = {
                'access_token': token.token,
                'token_type': 'bearer',
                'expires_in': int(
                    round(
                        (token.expires - datetime.now()).total_seconds()))}
            return json_response(access_token_data, _disable_cors=True)
        else:
            return json_response({
                'error': 'invalid_request',
                'error_description':
                    'Invalid code'})
    else:
        return json_response({
            'error': 'invalid_request',
            'error_descriptin':
                'Missing `code` parameter in request'})
def get_entries(request):
    entries = request.db.MediaEntry.query

    # TODO: Make it possible to fetch unprocessed media, or media in-processing
    entries = entries.filter_by(state=u'processed')

    # TODO: Add sort order customization
    entries = entries.order_by(request.db.MediaEntry.created.desc())

    # TODO: Fetch default and upper limit from config
    entries = entries.limit(int(request.GET.get('limit') or 10))

    entries_serializable = []

    for entry in entries:
        entries_serializable.append(get_entry_serializable(entry, request.urlgen))

    return json_response(entries_serializable)
예제 #8
0
def access_token(request):
    if request.GET.get("code"):
        code = OAuthCode.query.filter(OAuthCode.code == request.GET.get("code")).first()

        if code:
            if code.client.type == u"confidential":
                client_identifier = request.GET.get("client_id")

                if not client_identifier:
                    return json_response(
                        {"error": "invalid_request", "error_description": "Missing client_id in request"}
                    )

                client_secret = request.GET.get("client_secret")

                if not client_secret:
                    return json_response(
                        {"error": "invalid_request", "error_description": "Missing client_secret in request"}
                    )

                if not client_secret == code.client.secret or not client_identifier == code.client.identifier:
                    return json_response(
                        {
                            "error": "invalid_client",
                            "error_description": "The client_id or client_secret does not match the" " code",
                        }
                    )

            token = OAuthToken()
            token.token = unicode(uuid4())
            token.user = code.user
            token.client = code.client
            token.save()

            # expire time of token in full seconds
            # timedelta.total_seconds is python >= 2.7 or we would use that
            td = token.expires - datetime.now()
            exp_in = 86400 * td.days + td.seconds  # just ignore µsec

            access_token_data = {"access_token": token.token, "token_type": "bearer", "expires_in": exp_in}
            return json_response(access_token_data, _disable_cors=True)
        else:
            return json_response({"error": "invalid_request", "error_description": "Invalid code"})
    else:
        return json_response({"error": "invalid_request", "error_descriptin": "Missing `code` parameter in request"})
예제 #9
0
def post_entry(request):
    _log.debug('Posting entry')

    if request.method == 'OPTIONS':
        return json_response({'status': 200})

    if request.method != 'POST':
        _log.debug('Must POST against post_entry')
        return exc.HTTPBadRequest()

    if not 'file' in request.files \
            or not isinstance(request.files['file'], FileStorage) \
            or not request.files['file'].stream:
        _log.debug('File field not found')
        return exc.HTTPBadRequest()

    media_file = request.files['file']

    media_type, media_manager = sniff_media(media_file)

    entry = request.db.MediaEntry()
    entry.id = ObjectId()
    entry.media_type = unicode(media_type)
    entry.title = unicode(request.form.get('title')
            or splitext(media_file.filename)[0])

    entry.description = unicode(request.form.get('description'))
    entry.license = unicode(request.form.get('license', ''))

    entry.uploader = request.user.id

    entry.generate_slug()

    task_id = unicode(uuid.uuid4())

    # Now store generate the queueing related filename
    queue_filepath = request.app.queue_store.get_unique_filepath(
        ['media_entries',
            task_id,
            secure_filename(media_file.filename)])

    # queue appropriately
    queue_file = request.app.queue_store.get_file(
        queue_filepath, 'wb')

    with queue_file:
        queue_file.write(request.files['file'].stream.read())

    # Add queued filename to the entry
    entry.queued_media_file = queue_filepath

    entry.queued_task_id = task_id

    # Save now so we have this data before kicking off processing
    entry.save(validate=True)

    if request.form.get('callback_url'):
        metadata = request.db.ProcessingMetaData()
        metadata.media_entry = entry
        metadata.callback_url = unicode(request.form['callback_url'])
        metadata.save()

    # Pass off to processing
    #
    # (... don't change entry after this point to avoid race
    # conditions with changes to the document via processing code)
    process_media = registry.tasks[ProcessMedia.name]
    try:
        process_media.apply_async(
            [unicode(entry._id)], {},
            task_id=task_id)
    except BaseException as e:
        # The purpose of this section is because when running in "lazy"
        # or always-eager-with-exceptions-propagated celery mode that
        # the failure handling won't happen on Celery end.  Since we
        # expect a lot of users to run things in this way we have to
        # capture stuff here.
        #
        # ... not completely the diaper pattern because the
        # exception is re-raised :)
        mark_entry_failed(entry._id, e)
        # re-raise the exception
        raise

    return json_response(get_entry_serializable(entry, request.urlgen))
예제 #10
0
def access_token(request):
    '''
    Access token endpoint provides access tokens to any clients that have the
    right grants/credentials
    '''

    client = None
    user = None

    if request.GET.get('code'):
        # Validate the code arg, then get the client object from the db.
        code = OAuthCode.query.filter(OAuthCode.code ==
                request.GET.get('code')).first()

        if not code:
            return json_response({
                'error': 'invalid_request',
                'error_description':
                    'Invalid code.'})

        client = code.client
        user = code.user

    elif request.args.get('refresh_token'):
        # Validate a refresh token, then get the client object from the db.
        refresh_token = OAuthRefreshToken.query.filter(
            OAuthRefreshToken.token ==
            request.args.get('refresh_token')).first()

        if not refresh_token:
            return json_response({
                'error': 'invalid_request',
                'error_description':
                    'Invalid refresh token.'})

        client = refresh_token.client
        user = refresh_token.user

    if client:
        client_identifier = request.GET.get('client_id')

        if not client_identifier:
            return json_response({
                'error': 'invalid_request',
                'error_description':
                    'Missing client_id in request.'})

        if not client_identifier == client.identifier:
            return json_response({
                'error': 'invalid_client',
                'error_description':
                    'Mismatching client credentials.'})

        if client.type == u'confidential':
            client_secret = request.GET.get('client_secret')

            if not client_secret:
                return json_response({
                    'error': 'invalid_request',
                    'error_description':
                        'Missing client_secret in request.'})

            if not client_secret == client.secret:
                return json_response({
                    'error': 'invalid_client',
                    'error_description':
                        'Mismatching client credentials.'})


        access_token_data = create_token(client, user)

        return json_response(access_token_data, _disable_cors=True)

    return json_response({
        'error': 'invalid_request',
        'error_description':
            'Missing `code` or `refresh_token` parameter in request.'})