def message_send(token, channel_id, message): #add error checking for valid channel id? """ Send a message from authorised_user to the channel specified by channel_id. Parameters: token (str): Authorisation hash for user channel_id (int): Channels' channel ID message (str): Message from user Returns: {} (dict): Empty dictionary """ if not isinstance(token, str): raise AccessError('Token is invalid') if len(message) > 1000: raise InputError("The message is longer than 1000 characters") auth_user = get_user_id(token) channel_data = get_channel(channel_id) is_auth = auth_user not in channel_data["owner_members"] + channel_data[ "all_members"] if is_auth: raise AccessError('User is not a member of the channel') max_msg_id = len(data["messages"]) current_date = datetime.today() react_list = [] data["messages"].append({ "message_id": max_msg_id + 1, "u_id": get_user_id(token), "message": message, "time_created": int(time.mktime(current_date.timetuple())), "channel_id": channel_id, "reacts": [{ 'react_id': 0, 'u_ids': react_list, }], "is_pinned": False }) return {"message_id": max_msg_id + 1}
def get_dose_set(): doses = [ dose for dose in dose_set if dose['UserId'] == get_user_id(auth.username()) ] #return make_response(dumps(list(map(make_public_dose, doses)))) return jsonify(list(map(make_public_dose, doses)))
def get_thumbnail(request): # most of this is copied from the download page above if 'fileid' not in request.GET: return render_error(request, "You did not specify a file.", 'filelist.html') # displays filelist upon error file_id = request.GET['fileid'] try: file_entry = MediaFile.objects.get(file_id=file_id) except MediaFile.DoesNotExist: # Essentially a 404, what else could we do with the return? return render_error(request, "Not Found: The thumbnail you are trying to access does not exist.", status=404) if file_entry.user_id != user.get_user_id(): # Essentially a 403 return render_error(request, "Forbidden: You are trying to access a thumbnail for file that you didn't upload.", status=403) if not file_entry.has_thumb: #TODO: Return correct type of thumbnail based on content-type or category if file_entry.category in ('image', 'video', 'audio'): return redirect('/static/%s_thumb.png' % (file_entry.category,)) return redirect('/static/generic_thumb.png') key = 't/'+file_id # Sign a URL for the user url = s3util.sign_url('s3.mediasnak.com', key, expiry=60, format=s3util.URL_CUSTOM) # Redirect user to the calculated S3 download link return redirect(url)
def welcome(): if "username" in session: username = session["username"] #displays a list of edited stories return render_template("home.html", username = session["username"], \ stories=user.get_stories(user.get_user_id(username))) return redirect(url_for("auth"))
def admin_user_permission_change(token, u_id, permission_id): """Admin user permission change""" if not isinstance(token, str): raise AccessError('Token is invalid') if user.check_user_exists(token): auth_id = user.get_user_id(token) else: raise AccessError("Auth User does not exist") # u_id Error if not user.check_uid_exists(u_id): raise InputError("u_id does not refer to a valid user") # Permission Error if permission_id not in [1, 2]: raise InputError("permission_id does not refer to a value permission") # authorised is not an owner list_of_auth_users = data["permissions"][0]["users"] if auth_id not in list_of_auth_users: raise AccessError("The authorised user is not an owner") list_of_regular_users = data["permissions"][1]["users"] if permission_id == 1 and u_id in list_of_regular_users: list_of_regular_users.remove(u_id) elif permission_id == 2 and u_id in list_of_auth_users: list_of_auth_users.remove(u_id) if permission_id == 1: list_of_auth_users.append(u_id) elif permission_id == 2: list_of_regular_users.append(u_id) return {}
def channels_list(token): """ Provides a list of all channels that the authorised user is part of. Parameters: token (str): Authorisation hash for user Returns: dict_of_list (dict): A dictionary containing a list of channels """ if not isinstance(token, str): raise AccessError('Token is invalid.') if user.check_user_exists(token): user_id = user.get_user_id(token) else: raise AccessError("Token is invalid.") # User who exists and is not in channel can still access this. # List channels as a list of dicts dict_of_list = list(filter(lambda user: user_id in user["all_members"] \ + user["owner_members"], data["channels"])) list_of_dict = list( map(lambda d: dict(itertools.islice(d.items(), 2)), dict_of_list)) return {"channels": list_of_dict}
def channel_removeowner(token, channel_id, u_id): """ Remove user with user ID 'u_id' as an owner of this channel. Parameters: token (str): Authorisation hash for the user channel_id (int): Channels' channel ID u_id (int): Users' user ID Returns: {} (dict): Empty dictionary """ if not isinstance(token, str): raise AccessError('Token is invalid') if not valid_channel_id(token, channel_id): raise InputError('Channel ID is not a valid channel') owner_id = get_user_id(token) channel_data = get_channel(channel_id) if not u_id in channel_data["owner_members"]: raise InputError('User is not an owner of the channel') list_of_auth_users = data["permissions"][0]["users"] if owner_id not in channel_data["owner_members"] + list_of_auth_users: raise AccessError( 'User is not an owner of the channel or an owner of the flockr') channel_data["owner_members"].remove(u_id) channel_data["all_members"].append(u_id) channel_data = get_channel(channel_id) return {}
def channel_leave(token, channel_id): """ Given a channel ID, the user is removed as a member of this channel. Parameters: token (str): Authorisation hash for the user channel_id (int): Channels' channel ID Returns: {} (dict): Empty dictionary """ if not isinstance(token, str): raise AccessError('Token is invalid') if not valid_channel_id(token, channel_id): raise InputError('Channel ID is not a valid channel') channel_data = get_channel(channel_id) user_id = get_user_id(token) result_access = user_id in channel_data["all_members"] + channel_data["owner_members"] and \ channel_data["channel_id"] == channel_id if not result_access: raise AccessError('User is not a member of the channel') # If member of channel wants to leave we remove it. Otherwise we remove a owner member. if user_id in channel_data["all_members"]: channel_data["all_members"].remove(user_id) else: # Remove user_id for owner. channel_data["owner_members"].remove(user_id) return {}
def message_unpin(token, message_id): """ Given a pinned message within a channel, remove its mark as pinned. Parameters: token (str): Authorisation hash for user message_id (int): Messages' message ID Returns: {} (dict): Empty dictionary """ if not isinstance(token, str): raise AccessError('Token is invalid') # Input Errors: # 1. Message_id is not a valid message message_list = list(filter(lambda msg: msg["message_id"] == message_id, \ data["messages"])) if len(message_list) == 0: raise InputError("Message does not exist") # 2. Message ID is already pinned if message_list[0]["is_pinned"] is False: raise InputError("Message already unpinned") if auth.check_token_exists(token): auth_user = get_user_id(token) else: raise AccessError("User does not exist.") # Access Errors: # 1. Unauthorised user channel_id = message_list[0]["channel_id"] channel_data = get_channel(channel_id) if auth_user not in channel_data["owner_members"]: raise AccessError("User is not authorised") message_list[0]["is_pinned"] = False return {}
def channel_join(token, channel_id): """ Given a channel ID of a channel that the authorised user can join, adds them to the channel. Parameters: token (str): Authorisation hash for the user channel_id (int): Channels' channel ID Returns: {} (dict): Empty dictionary """ if not isinstance(token, str): raise AccessError('Token is invalid') # Check Token exists. if not valid_channel_id(token, channel_id): raise InputError('Channel ID is not a valid channel') u_id = get_user_id(token) channel_data = get_channel(channel_id) if verify_user_member(channel_id, u_id): raise InputError("User already exists in channel.") list_of_auth_users = data["permissions"][0]["users"] # If channel not public and user not authorised. if not channel_data["public"] and (u_id not in list_of_auth_users): raise AccessError("Channel is private and user is not a global owner") channel_data["all_members"].append(u_id) return {}
def stories(): if "username" not in session: flash('You must be logged in to view stories!') return redirect(url_for('login')) username = session["username"] #display all unedited stories return render_template('stories.html', stories=user.all_unedited(user.get_user_id(username)))
def edit(): if "username" not in session: flash('You must be logged in to edit!') return redirect(url_for('login')) story_id = request.args['story'] user_id = user.get_user_id(session['username']) if user.edited(story_id, user_id): #story was already edited by this user flash("You've already edited this story!") return redirect(url_for('welcome')) if request.method == "POST": #user filled out the form to edit a story try: #SUCCESS! form was filled out correctly content = request.form['content'] except KeyError: flash('You have not filled out all the required fields') return redirect(url_for('edit'), story=story_id) #add the user's edit to database story.add_edit(story_id, user_id, content) flash("Edited story") return redirect(url_for('welcome')) else: #user hasn't filled out the form to edit this story. display the form return render_template('edit.html', story_title=story.get_title(story_id), last_update=story.latest_story_edit(story_id), story=story_id)
def download_page(request): "Displays a page with a link to download a file, or redirects to the download itself." # The friendly download link isn't necessarily part of a story, but is good functionality atleast for our use if 'fileid' not in request.GET: return render_error(request, "You did not specify which file to download.", 'filelist.html') # displays filelist upon error file_id = request.GET['fileid'] try: file_entry = MediaFile.objects.get(file_id=file_id) except MediaFile.DoesNotExist: # Essentially a 404, what else could we do with the return? return render_error(request, "Not Found: The file you are trying to download does not exist.", status=404) if file_entry.user_id != user.get_user_id(): # Essentially a 403 return render_error(request, "Forbidden: You are trying to access a file that you didn't upload.", status=403) key = 'u/'+file_id # Increment view count MediaFile.objects.filter(file_id=file_id).update(view_count=F("view_count")+1) # Sign a URL for the user url = s3util.sign_url('s3.mediasnak.com', key, expiry=60, format=s3util.URL_CUSTOM) # Redirect user to the calculated S3 download link return redirect(url)
def get_dose(dose_id): doses = [dose for dose in dose_set if dose['Id'] == dose_id] if len(doses) == 0: abort(404) dose = doses[0] if dose['UserId'] != get_user_id(auth.username()): abort(404) return jsonify(make_public_dose(dose))
def standup_send(token, channel_id, message): """ Send a message to get buffered in the standup queue, assuming a standup is currently active. Parameters: token (str): Authorisation hash for user channel_id (int): Channels' channel ID message (str): Message from userz Returns: {} (dict): Empty dictionary """ if not isinstance(token, str): raise AccessError('Token is invalid') if auth.check_token_exists(token): auth_user = get_user_id(token) else: raise AccessError("User does not exist.") if not valid_channel_id(token, channel_id): raise InputError('Channel ID is not a valid channel') if len(message) > 1000: raise InputError("The message is longer than 1000 characters") channel_data = get_channel(channel_id) if channel_data["is_active"] is False: raise InputError( 'An active standup is not currently running in this channel') auth_id = get_user_id(token) if not verify_user_member(channel_id, auth_id): raise AccessError('Authorised user is not a member of the channel') usr = get_user_profile(auth_user) handle = usr["handle_str"] global msg msg += f"{handle}: {message}\n" return {}
def get_token_auth(token, message_id): """Matches user ID from message with message ID 'message_id' with user ID from back-end in database to verify authorization.""" # Get user_id from message_id. u_id_message = get_user_id_message(message_id) # Get user_id from token. u_id_token = get_user_id(token) return u_id_message == u_id_token
def delete_dose(dose_id): doses = [dose for dose in dose_set if dose['Id'] == dose_id] if len(doses) == 0: abort(404) dose = doses[0] if dose['UserId'] != get_user_id(auth.username()): abort(404) dose_set.remove(doses[0]) return jsonify({'Result': True})
def create_dose(): if not request.json: abort(400) dose = {'Id': dose_set[-1]['Id'] + 1 if len(dose_set) else 1} dose['UserId'] = get_user_id(auth.username()) if not create_record(dose_class, request, dose): abort(400) dose_set.append(dose) return jsonify(make_public_dose(dose)), 201
def update_dose(dose_id): doses = [dose for dose in dose_set if dose['Id'] == dose_id] if len(doses) == 0 or not request.json: abort(404) dose = doses[0] if dose['UserId'] != get_user_id(auth.username()): abort(404) update_record(dose_class, request, dose) return jsonify(make_public_dose(dose))
def create_forecast(): if not request.json: abort(400) user_doses = [ dose for dose in dose_set if dose['UserId'] == get_user_id(auth.username()) ] forecasts = run_algorithms(request.json, user_doses) return jsonify(forecasts), 201
def upload_form(request): "Produces an upload form for submitting files to S3." logging.debug("Started upload view") bucketname = "s3.mediasnak.com" user_id = user.get_user_id() page_parameters = upload.upload_form_parameters(bucketname, user_id) logging.debug("Completed upload view") # Use render_to_response to fill out the HTML template return render_to_response('upload.html', page_parameters, context_instance=RequestContext(request))
def view(): if "username" not in session: flash('You must be logged in to view stories!') return redirect(url_for('login')) story_id = request.args['story'] #print story_id edited = user.edited(story_id, user.get_user_id(session['username'])) if edited: #show entire story if the user already edited content = story.get_story(story_id) else: #show latest update if the user hasnt edited content = story.latest_story_edit(story_id) return render_template('storypage.html', story_title=story.get_title(story_id), content=content, edited=edited, story=story_id)
def channels_create(token, channel_name, is_public): """ Creates a new channel with name 'channel_name' that is either a public or private channel. Parameters: token (str): Authorisation hash for user channel_name (str): Name of new channel is_public (Bool): Whether or not the channel is public or private Returns: new_dict (dict): A dictionary containing a key-value pair of the channel name and ID """ if not isinstance(token, str): raise AccessError('Token is invalid.') if len(channel_name) > 20: raise InputError('Name is more than 20 characters long') list_of_channels = data['channels'] owner = user.get_user_id(token) # find the max value of any id in the channels list in database # Max element is assigned only if data exists. max_ele = len(list_of_channels) is_public_str = isinstance(is_public, str) is_public = bool( distutils.util.strtobool(is_public)) if is_public_str else is_public # append a new dictionary containing details of the new channel to the # list of channels in database list_of_channels.append({ 'channel_id': max_ele + 1, 'name': channel_name, 'owner_members': [owner], 'all_members': [], 'public': is_public, 'is_active': False, 'time_finish': None }) # create a copy of the original new_dict = list_of_channels[max_ele].copy() # delete unnecessary keys del new_dict['name'] del new_dict['all_members'] # return a dictionary containing only the key-value pair like # 'channel_id' : 3 return {"channel_id": max_ele + 1}
def delete_file(request): """ Posting a fileid to this view with confirm=yes permanently deletes the file from the system, including file stored on S3, and all metadata. """ user_id = user.get_user_id() bucketname = "s3.mediasnak.com" if 'fileid' not in request.POST: return render_error(request, 'You did not specify which file to delete.', 'filelist.html') file_id = request.POST['fileid'] if 'confirm' not in request.POST or request.POST['confirm'] != 'yes': return render_to_response('confirm_delete.html', {'file_id': file_id}, context_instance=RequestContext(request)) try: delete.delete_file(bucketname, user_id, file_id) except MediasnakError, err: return render_error(request, err, 'filelist.html')
def message_sendlater(token, channel_id, message, time_sent): """ Send a message from the authorised_user to the channel specified by channel_id automatically at a specified time in the future. Parameters: token (str): Authorisation hash for user channel_id (int): Channels' channel ID message (str): Message from user time_sent (int): Unix timestamp Returns: message_id (int): Messages' message ID """ if not isinstance(token, str): raise AccessError('Token is invalid') if len(message) > 1000: raise InputError("The message is longer than 1000 characters") if not valid_channel_id(token, channel_id): raise InputError('Channel ID is not a valid channel') auth_id = get_user_id(token) if not verify_user_member(channel_id, auth_id): raise AccessError('User is not a member of the channel') current_date = datetime.today() current_unix_time = time.mktime(current_date.timetuple()) time_difference = time_sent - current_unix_time if time_difference < 0: raise InputError('Time specified is a time in the past') with concurrent.futures.ThreadPoolExecutor() as executor: executor_instance = executor.submit(message_send, token, channel_id, message, time_difference) msg_result = executor_instance.result() return {"message_id": msg_result["message_id"]}
def upload_success(request): "Handles the return process from S3 upload produced by upload_form and returns a success page to the user." # This view creates database entries for a file, the input is upload return values from S3 user_id = user.get_user_id() # If they don't have the S3 return values, just send them to the upload page if not ('bucket' in request.GET and 'key' in request.GET and 'etag' in request.GET) : return http.HttpResponseRedirect('upload') if request.GET['bucket'] != 's3.mediasnak.com': # 'magic-string', could maybe put in S3utils error = "Apparently somehow this file was uploaded to the wrong bucket or the wrong bucket is being returned." return render_error(request, error) bucketname = request.GET['bucket'] key = request.GET['key'] # this was created when upload page was requested etag = request.GET['etag'] # unused try: template_vars = upload.process_return_from_upload(bucketname, user_id, key, etag) except MediasnakError, err: return render_error(request, err)
def message_remove(token, message_id): """ Given a message_id for a message, this message is removed from the channel. Parameters: token (str): Authorisation hash for user message_id (int): Messages' message ID Returns: {} (dict): Empty dictionary """ message_list = list( filter(lambda msg: msg["message_id"] == message_id, data["messages"])) if not isinstance(token, str): raise AccessError('Token is invalid') if len(message_list) == 0: raise InputError("Message does not exist") message_list = message_list[0] channel_id = message_list["channel_id"] channel_data = get_channel(channel_id) if auth.check_token_exists(token): auth_user = get_user_id(token) else: raise AccessError("User does not exist.") list_of_auth_users = data["permissions"][0]["users"] is_owner = auth_user in channel_data["owner_members"] + list_of_auth_users is_auth = get_token_auth(token, message_id) if not is_owner and not is_auth: raise AccessError("You are not authorised to remove this message") data["messages"].remove(message_list) return {}
def channel_invite(token, channel_id, u_id): """ Invites a user with ID 'u_id' to join a channel with ID 'channel_id'. Once invited, the user is added to the channel immediately. Parameters: token (str): Authorisation hash for user channel_id (int): Channels' channel ID u_id (int): Users' user ID Returns: {} (dict): Empty dictionary """ #step 0: error testing if not isinstance(token, str): raise AccessError('Token is invalid') if not valid_channel_id(token, channel_id): raise InputError('Channel ID is not a valid channel') # Check user id exists. if not check_uid_exists(u_id): raise InputError('User ID does not refer to a valid user') # Check auth user exists. # if check_user_exists(token): auth_id = get_user_id(token) if not verify_user_member(channel_id, auth_id): raise AccessError('Authorised user is not a member of the channel') channel_data = get_channel(channel_id) # Check for user exists. if u_id in channel_data["all_members"] + channel_data["owner_members"]: raise InputError("User already exists!") channel_data["all_members"].append(u_id) return {}
def message_edit(token, message_id, message): """ Given a message, update it's text with new text. If the new message is an empty string, the message is deleted. Parameters: token (str): Authorisation hash for user message_id (int): Messages' message ID message (str): Message from user Returns: {} (dict): Empty dictionary """ message_list = list( filter(lambda msg: msg["message_id"] == message_id, data["messages"])) if not isinstance(token, str): raise AccessError('Token is invalid') if len(message_list) == 0: raise InputError("Message does not exist") message_list = message_list[0] channel_id = message_list["channel_id"] channel_data = get_channel(channel_id) if auth.check_token_exists(token): auth_user = get_user_id(token) else: raise AccessError("User does not exist.") list_of_auth_users = data["permissions"][0]["users"] is_owner = auth_user in channel_data["owner_members"] + list_of_auth_users is_auth = get_token_auth(token, message_id) if not is_owner and not is_auth: raise AccessError("You are not authorised to edit this message") message_list["message"] = message return {}
def create(): if "username" not in session: flash('You must be logged in to create a story!') return redirect(url_for('login')) if request.method == "POST": #form to create a story has been filled out try: #form filled out correctly title = request.form['title'] content = request.form['content'] except KeyError: flash('You have not filled out all the required fields') return redirect(url_for('create')) #add story and edit to databases username = session['username'] story_id = story.add_story(title) user_id = user.get_user_id(username) story.add_edit(story_id, user_id, content) flash("Story successfully created") #display the story return redirect(url_for('view', story=story_id)) #form to create a story hasn't been filled out return render_template("create.html")
def message_react(token, message_id, react_id): """ Given a message within a channel the authorised user is part of, add a "react" to that particular message. Parameters: token (str): Authorisation hash for user message_id (int): Messages' message ID react_id (int): Reacts' react ID Returns: {} (dict): Empty dictionary """ if not isinstance(token, str): raise AccessError('Token is invalid') # Input Errors: # Raise Input Error if message_id is invalid message_list = message_reaction_checks(message_id, react_id) # 2. React_id is not a valid react --> only 1 if react_id != 1: raise InputError("Not a valid react") if auth.check_token_exists(token): auth_user = get_user_id(token) else: raise AccessError("User does not exist.") list_of_reactors = message_list[0]["reacts"][0]["u_ids"] for user in list_of_reactors: if auth_user == user: raise InputError("This message already contains a valid react") message_list[0]["reacts"][0]["u_ids"].append(auth_user) if message_list[0]["reacts"][0]["react_id"] == 0: message_list[0]["reacts"][0]["react_id"] = react_id message_list = list( filter(lambda msg: msg["message_id"] == message_id, data["messages"])) # if message_list[0]["u_id"] in message_list[0]["reacts"][0]["u_ids"]: # message_list[0]["reacts"][0]["is_this_user_reacted"] = True return {}
def list_files_page(request): "Displays the page with a list of all the user's files" user_id = user.get_user_id() bucketname = "s3.mediasnak.com" # This might be useful, to use the same page to list files in a category, or even for searches # category = request.GET['category'] orderby = None if 'sort' in request.GET: orderby = request.GET['sort'] # We use this to change the view type viewtype = 'thumb' if 'view' in request.GET: viewtype = request.GET['view'] browseby = None if 'type' in request.GET: browseby = request.GET['type'] #def search_files(request): #"displays a list of files matching the request" if 'searchterm' in request.GET: #.. return render_to_response('base.html',{'error':'No serch term specified'}); search_term = request.GET['searchterm'] if 'searchby' in request.GET: search_by = request.GET['searchby'] else: search_by = 'default' #.. return render_to_response('base.html',{'error':'Nothing specified to search by.'}) try: template_vars = listfiles.search_files(bucketname, user_id, search_by, search_term, orderby); except MediasnakError, err: return render_error(request, err, 'filelist.html')
def message_unreact(token, message_id, react_id): """ Given a message within a channel the authorised user is part of, remove a "react" to that particular message. Parameters: token (str): Authorisation hash for user message_id (int): Messages' message ID react_id (int): Reacts' react ID Returns: {} (dict): Empty dictionary """ if not isinstance(token, str): raise AccessError('Token is invalid') # ESSENTIALLY SAME AS UNREACT BUT CHANGING VALID REACT TO 0 INSTEAD OF 1 message_list = message_reaction_checks(message_id, react_id) # 2. React_id is not a valid react --> only 0 if react_id != 1: raise InputError("Not a valid react") if auth.check_token_exists(token): auth_user = get_user_id(token) else: raise AccessError("User does not exist.") if message_list[0]["reacts"][0]["react_id"] == 0: raise InputError("Message does not contain an active react") list_of_reactors = message_list[0]["reacts"][0]["u_ids"] if auth_user not in list_of_reactors: raise InputError("User has not reacted to this message") message_list[0]["reacts"][0]["u_ids"].remove(auth_user) message_list = list( filter(lambda msg: msg["message_id"] == message_id, data["messages"])) if message_list[0]["reacts"][0]["u_ids"] == []: message_list[0]["reacts"][0]["react_id"] = 0 # if message_list[0]["u_id"] not in message_list[0]["reacts"][0]["u_ids"]: # message_list[0]["reacts"][0]["is_this_user_reacted"] = False return {}
def channel_details(token, channel_id): """ Given a channel with ID 'channel_id' that the authorised user is a part of, provide basic details about the channel. Parameters: token (str): Authorisation hash for the user channel_id (int): Channels' channel ID Returns: {} (dict): Empty dictionary """ #step 0: error testing if not isinstance(token, str): raise AccessError('Token is invalid') if not valid_channel_id(token, channel_id): raise InputError('Channel ID is not a valid channel') channel_data = get_channel(channel_id) auth_user = get_user_id(token) if auth_user not in channel_data["owner_members"] + channel_data[ "all_members"]: raise AccessError('User is not a member of the channel') owners_list = list(map(list_members, channel_data["owner_members"])) members_list = owners_list + list( map(list_members, channel_data["all_members"])) return { "name": channel_data["name"], "owner_members": owners_list, "all_members": members_list, # ensure that profile_img_url is also returned }
def file_details_page(request): "Displays the page with the detailed metadata about a file" #test: http://localhost:8081/file-details?fileid=file1 user_id = user.get_user_id() bucketname = "s3.mediasnak.com" if 'fileid' not in request.GET: return render_error(request, "You did not specify which file to view the details of.", 'filelist.html') file_id = request.GET['fileid'] editing = 'edit' in request.GET and request.GET['edit'] == "true" # Note: Python's "and" does short-circuit evaluation try: file_entry = MediaFile.objects.get(file_id=file_id) except MediaFile.DoesNotExist: # Essentially a 404, what else could we do with the page? return render_error(request, 'There is no file by this ID!', status=404) except MediaFile.MultipleObjectsReturned: return render_error(request, 'There are multiple files by this ID - this shouldn\'t happen!') # Process edits to details if they have been submitted # These user input fields need checking #### WHAT ARE THE DATABASE INJECTION RISKS OF DJANGO ?? #### # submitting the following complex string as a filename does not work as expected # <QueryDict: {u'fileviewcount': [u'100'], u'submit': [u'Submit Edits'], u'filename': [u'<QueryDict: {u\'fileviewcount\': [u\'100\'], # u\'submit\': [u\'Submit Edits\'], u\'filename\': [u\'<QueryDict: {u\\\'fileviewcount\\\': [u\\\'100\\\'], u\\\'submit\\\': # [u\\\'Submit Edits\\\'], u\\\'filename\\\': [u\\\'<QueryDict: {u\\\\\\\'fileviewcount\\\\\\\': [u\\\\\\\'100\\\\\\\'], u\\\\\\\ #'filename\\\\\\\': [u"<QueryDict: {u\\\\\\\' #fileviewcount\\\\\\\': [u\\\\\\\'100\\\\\\\'], u\\\\\\\'filename\\\\\\\': [u\\\\\\\'<QueryDict: {}>\\\\\\\']}>"]}>\\\']}>\']}>']}> # does not check lengths for instance #also, how does django display values (does it encode html special characters?) if 'submit_changes' in request.POST: if 'f_title' in request.POST: file_entry.title = request.POST['f_title'] if 'f_name' in request.POST: # Should filename be editable? file_entry.filename = request.POST['f_name'] if 'f_viewcount' in request.POST: # Should viewcount be editable? file_entry.view_count = request.POST['f_viewcount'] if 'f_comment' in request.POST: file_entry.comment = request.POST['f_comment'][:998] if 'f_category' in request.POST: # Should category be editable? file_entry.category = request.POST['f_category'] if 'f_tags' in request.POST: file_entry.tags = request.POST['f_tags'] file_entry.save() editing = False; template_vars = { 'editing' : editing, 'file_id' : file_entry.file_id, 'file': { 'name' : file_entry.filename, 'title' : file_entry.title, 'upload_time' : file_entry.upload_time, 'viewcount' : file_entry.view_count, 'comment' : file_entry.comment, 'category' : file_entry.category, 'tags' : file_entry.tags } } return render_to_response('filedetails.html', template_vars, context_instance=RequestContext(request))
def login_template_etag(request, *args, **kwargs): return hashlib.sha1(str(user.get_user_id()) + environ['CURRENT_VERSION_ID']).hexdigest()
def fbconnect(): if request.args.get('state') != login_session['state']: response = make_response(json.dumps('Invalid state parameter.'), 401) response.headers['Content-Type'] = 'application/json' return response access_token = request.data print "access token received %s " % access_token app_id = json.loads(open('client_secrets_facebook.json', 'r').read())[ 'web']['app_id'] app_secret = json.loads( open('client_secrets_facebook.json', 'r').read())['web']['app_secret'] url = 'https://graph.facebook.com/oauth/access_token?grant_type=fb_exchange_token&client_id=%s&client_secret=%s&fb_exchange_token=%s' % ( app_id, app_secret, access_token) h = httplib2.Http() result = h.request(url, 'GET')[1] # Use token to get user info from API userinfo_url = "https://graph.facebook.com/v2.8/me" ''' Due to the formatting for the result from the server token exchange we have to split the token first on commas and select the first index which gives us the key : value for the server access token then we split it on colons to pull out the actual token value and replace the remaining quotes with nothing so that it can be used directly in the graph api calls ''' token = result.split(',')[0].split(':')[1].replace('"', '') url = 'https://graph.facebook.com/v2.8/me?access_token=%s&fields=name,id,email' % token h = httplib2.Http() result = h.request(url, 'GET')[1] # print "url sent for API access:%s"% url # print "API JSON result: %s" % result data = json.loads(result) login_session['provider'] = 'facebook' login_session['username'] = data["name"] login_session['email'] = data["email"] login_session['facebook_id'] = data["id"] # The token must be stored in the login_session in order to properly logout login_session['access_token'] = token # Get user picture url = 'https://graph.facebook.com/v2.8/me/picture?access_token=%s&redirect=0&height=200&width=200' % token h = httplib2.Http() result = h.request(url, 'GET')[1] data = json.loads(result) login_session['picture'] = data["data"]["url"] # see if user exists user_id = get_user_id(login_session['email']) if not user_id: user_id = create_user(login_session) login_session['user_id'] = user_id output = '' output += '<h1>Welcome, ' output += login_session['username'] output += '!</h1>' output += '<img src="' output += login_session['picture'] output += ' " style = "width: 300px; height: 300px;border-radius: 150px;-webkit-border-radius: 150px;-moz-border-radius: 150px;"> ' flash("Now logged in as %s" % login_session['username']) return output
def gconnect(): # Validate state token if request.args.get('state') != login_session['state']: response = make_response(json.dumps('Invalid state parameter.'), 401) response.headers['Content-Type'] = 'application/json' return response # Obtain authorization code code = request.data try: # Upgrade the authorization code into a credentials object oauth_flow = flow_from_clientsecrets(GOOGLE_CLIENT_SECRET, scope='') oauth_flow.redirect_uri = 'postmessage' credentials = oauth_flow.step2_exchange(code) except FlowExchangeError: response = make_response( json.dumps('Failed to upgrade the authorization code.'), 401) response.headers['Content-Type'] = 'application/json' return response # Check that the access token is valid. access_token = credentials.access_token url = ('https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=%s' % access_token) h = httplib2.Http() result = json.loads(h.request(url, 'GET')[1]) # If there was an error in the access token info, abort. if result.get('error') is not None: response = make_response(json.dumps(result.get('error')), 500) response.headers['Content-Type'] = 'application/json' return response # Verify that the access token is used for the intended user. gplus_id = credentials.id_token['sub'] if result['user_id'] != gplus_id: response = make_response( json.dumps("Token's user ID doesn't match given user ID."), 401) response.headers['Content-Type'] = 'application/json' return response # Verify that the access token is valid for this app. if result['issued_to'] != GOOGLE_CLIENT_ID: response = make_response( json.dumps("Token's client ID does not match app's."), 401) print "Token's client ID does not match app's." response.headers['Content-Type'] = 'application/json' return response stored_access_token = login_session.get('access_token') stored_gplus_id = login_session.get('gplus_id') if stored_access_token is not None and gplus_id == stored_gplus_id: response = make_response(json.dumps('Current user is already connected.'), 200) response.headers['Content-Type'] = 'application/json' return response # Store the access token in the session for later use. login_session['access_token'] = credentials.access_token login_session['gplus_id'] = gplus_id # Get user info userinfo_url = "https://www.googleapis.com/oauth2/v1/userinfo" params = {'access_token': credentials.access_token, 'alt': 'json'} answer = requests.get(userinfo_url, params=params) data = answer.json() login_session['username'] = data['name'] login_session['picture'] = data['picture'] login_session['email'] = data['email'] # ADD PROVIDER TO LOGIN SESSION login_session['provider'] = 'google' # see if user exists, if it doesn't make a new one user_id = get_user_id(data["email"]) if not user_id: user_id = create_user(login_session) login_session['user_id'] = user_id output = '' output += '<h1>Welcome, ' output += login_session['username'] output += '!</h1>' output += '<img src="' output += login_session['picture'] output += ' " style = "width: 300px; height: 300px;border-radius: 150px;-webkit-border-radius: 150px;-moz-border-radius: 150px;"> ' flash("you are now logged in as %s" % login_session['username']) print "done!" return output