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))
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))
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})
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)
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)
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"})
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))
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.'})