def clean_inputs(event): request = event.request safe_post = {} safe_params = {} safe_get = {} if request.POST: p = request.POST for i in p.items(): # i[0] is field name, i[1] is actual object # do NOT do anything to FieldStorage (POST'd files) # attempting to add them to this variable results in # pickling error, cgi.FieldStorage does not define # __getstate__ apparently. # access any posted files directly via request.POST if isinstance(i[1], cgi.FieldStorage): continue if i[0] != 'body' and i[0] != 'description' and i[0] != 'description-textarea': safe_i = queries.strip_all_html(i[1]) safe_post[i[0]] = safe_i else: safe_post[i[0]] = i[1] if request.GET: get = request.GET for i in get.items(): safe_i = queries.strip_all_html(i[1]) safe_get[i[0]] = safe_i request.session['safe_get'] = safe_get request.session['safe_post'] = safe_post request.session['safe_params'] = dict(safe_get.items() + safe_post.items()) return 0
def test_create_submission(self): #@TODO: another function that should be split out of the view for easy repitition. # if the view code changes substantially, this test will not keep up user = queries.create_user(username = '******', password = '******') url = 'http://google.com' title = 'test' description = 'test' if url != '' and url is not None: url = queries.strip_all_html(url) if not re.match(r'http[s]*:\/\/', url): url = 'http://' + url else: # set to None so that NULL goes into the database url = None sub = Submission(title, description, url, user.id) self.dbsession.add(sub) self.dbsession.flush() s = queries.get_story_by_id(sub.id) self.assertEqual(s.id, sub.id)
def post(request): s = request.session p = request.session["safe_post"] r = request qs = s["safe_get"] s["message"] = "Post a story." dbsession = DBSession() stories = None new_url_text = "" new_title_text = "" # if uses came in with a share button, redirect to existing discussion if there is one if "from" in qs and qs["from"] == "button": existing_post = queries.get_story_by_url_oldest(qs["url"]) if existing_post: return HTTPFound(r.route_url("full", sub_id=existing_post.id)) new_url_text = qs["url"] if "title" in qs: new_title_text = qs["title"] if "new_post" in qs and qs["new_post"] == "y": if "logged_in" not in s: s["message"] = 'Sorry, you must <a href="{0}">log in</a> before you can share a link.'.format( r.route_url("login") ) return {"stories": [], "success": False, "code": "ENOLOGIN"} if p and "title" in p: if "logged_in" not in s: s["message"] = "Sorry, please log in first" return {"stories": [], "success": False, "code": "ENOLOGIN"} if p["url"] != "" and p["url"] is not None: p["url"] = queries.strip_all_html(p["url"]) if not re.match(r"http[s]*:\/\/", p["url"]): p["url"] = "http://" + p["url"] else: # set to None so that NULL goes into the database p["url"] = None sub = Submission(p["title"][:100], p["description"], p["url"], s["users.id"]) dbsession.add(sub) dbsession.flush() v = Vote(sub.id, s["users.id"], 1, "submission", None) v.direction = 1 dbsession.add(v) sub.slug = u"{title}-{uuid_first_octet}".format( title=slugify.slugify(unicode(p["title"][:100])), uuid_first_octet=str(sub.id)[:8] ) dbsession.add(sub) s["message"] = "Added." try: if request.registry.solr_conn: # we flush here to ensure we have a vaild id object when added to solr # we use this if statement so that the exception will be raised before # dbsession is flushed, hence avoiding an unnecessary flush if the site # is not using solr. dbsession.flush() request.registry.solr_conn.add({"id": sub.id, "title": sub.title, "description": sub.description}) request.registry.solr_conn.commit() except AttributeError: # solr is not configured for this connection pass if r.params and "op" in r.params: sub_id = r.params["sub_id"] if r.params["op"] == "del": try: story_to_del = queries.get_story_by_id(sub_id) except sqlalchemy.orm.exc.NoResultFound: story_to_del = None if story_to_del: if queries.is_user_allowed_admin_action(s["users.id"], str(story_to_del.id)): story_to_del.description = "[deleted]" story_to_del.url = "#" story_to_del.title = "[deleted]" story_to_del.deleted = True dbsession.add(story_to_del) dbsession.flush() else: print("Illegal deletion attempted on {0}".format(story_to_del.submitter.id)) if "sort.default_order" in r.registry.settings: sort = r.registry.settings["sort.default_order"] else: # default to new sort order if server-specific setting doesn't exist # this should only be the case on old clones; do NOT remove default_order # from the ini just because you want new by default. sort = "new" page_num = 1 per_page = 30 next_page = None prev_page = None # only pass through approved sort options if "sort" in qs: if qs["sort"] == "top": sort = "top" if qs["sort"] == "hot": sort = "hot" if qs["sort"] == "contro": sort = "contro" if qs["sort"] == "new": sort = "new" if "page_num" in qs: try: page_num = int(qs["page_num"]) except: page_num = 1 # @FIXME: make per_page configurable in a safe location # it is probably unwise to allow this to be set in the query string # because then a malicious user could say per_page = 10000000000 # and easily launch a DoS via that mechanism. # if 'per_page' in qs: # per_page = qs['per_page'] stories = queries.get_story_list(page_num=page_num, per_page=per_page, sort=sort, request=request) max_stories = stories["max_stories"] stories = stories["stories"] # this should be split into its own def under queries.py # as it is currently used in at least one other place if max_stories > (page_num * per_page): next_page = page_num + 1 if page_num > 1: prev_page = page_num - 1 vote_dict = {} if "logged_in" in s: vote_dict = queries.get_user_votes_on_all_submissions(s["users.id"]) for s in stories: # @TODO: Remember to not tally on every load once a real site deploys s.tally_votes() s.tally_comments() return { "stories": stories, "success": True, "code": 0, "vote_dict": vote_dict, "max_stories": max_stories, "prev_page": prev_page, "next_page": next_page, "new_url_text": new_url_text, "new_title_text": new_title_text, }
def login(request): #@FIXME: this uses a request handling method with success with which I was experimenting # it is not used elsewhere and is a pain to read and write # success = False causes a page to stop drawing and "error out" # some error conditions therefore don't set success to false because it's more convenient # to draw the rest of the page. # # someone should adapt this to be less success-centric and read less branchy. s = request.session success = True # check for facebook login, provided by Facebook's JS SDK try: fb_cookie = fb.extract_from_cookie(request) try: u = queries.get_user_by_name(fb_cookie['local_username']) except sqlalchemy.orm.exc.NoResultFound: u = fb.create_local_user(fb_cookie['info'], fb_cookie['local_username'], request = request) try: queries.login_user(request, u, None, bypass_password = True) except LoginAdapterExc: pass except LoginAdapterExc: pass if 'logout' in request.session['safe_params']: if 'logged_in' in s: del s['logged_in'] del s['users.id'] if 'u_fbgraph' in s: del s['u_fbgraph'] del s['u_fbinfo'] if 'u_twit' in s: del s['u_twit'] s['message'] = "You have been logged out, thanks." success = True else: s['message'] = "You are not logged in." success = True else: logged_in = False if 'logged_in' in s: s['message'] = "You are already logged in." logged_in = True else: if 'message' not in s: if 'last_login_status' in s: s['message'] = s['last_login_status'] del s['last_login_status'] else: s['message'] = "Please log in." p = request.session['safe_post'] prm = request.session['safe_params'] username = None if 'username' in prm: username = queries.strip_all_html(prm['username']) if p: dbsession = DBSession() if request.session['safe_get']['act'] == 'register': if logged_in: try: u = queries.get_user_by_id(s['users.id']) if u.temporary: queries.create_user(temp_to_perm = True, extant_id = s['users.id'], username = username, password = p['password'], origination = 'site') s['message'] = "Your anonymous profile has been converted, thanks." else: s['message'] = "You can't register while you're logged in." except sqlalchemy.exc.IntegrityError: s['message'] = "This username is already registered, sorry." dbsession.rollback() else: try: queries.create_user(username = username, password = p['password'], origination = 'site') s['message'] = "Successfully registered." success = True except sqlalchemy.exc.IntegrityError: s['message'] = "This username is already registered, sorry." success = False dbsession.rollback() elif request.session['safe_get']['act'] == 'update_pw': if p['new_password'] != p['new_password_confirm']: s['message'] = 'New password doesn\'t match confirmation, please try again.' else: u = queries.get_user_by_id(s['users.id']) if u.verify_pw(p['old_password']): u.password = u.hash_pw(p['new_password']) dbsession.add(u) s['message'] = 'Password updated.' success = True else: s['message'] = 'Old password invalid.' else: try: u = queries.get_user_by_name(username) try: queries.login_user(request, u, p['password']) s['message'] = "Good, logged in" success = True return HTTPFound(request.route_url('post')) except LoginAdapterExc: s['message'] = "Incorrect password." success = False except sqlalchemy.orm.exc.NoResultFound: s['message'] = "Sorry, I don't know you." success = False return {'success': success,}