def view_user(request): # TODO # Add in auth tokens (if exists) and access tokens (if exists) session = DBSession() matchdict = request.matchdict if (request.logged_in != int(matchdict["user_id"])): return HTTPForbidden(_("You are not allowed to view information about a user other than yourself.")) user = session.query(User).join(User.groups).join(Group.group_info).filter(User.id == matchdict["user_id"]).one() request_key_url = "" key = "" secret = "" token = "" token_secret = "" keySecret = ConsumerKeySecret.getByUserID(request.logged_in) if (keySecret): key = keySecret.consumer_key secret = keySecret.consumer_secret tokenData = Token.getTokenByConsumerID(keySecret.id) if (tokenData): token = tokenData.token token_secret = tokenData.token_secret else: request_key_url = route_url("api_request_key", request) return dict(username = user.username, homepage = user.homepage, title = _("Viewing ") + " " + user.username, key = key, secret = secret, token = token, token_secret = token_secret, request_key_url = request_key_url)
def doViewBlog(request = None, page_num = 1, limit = 10): session = DBSession() p = Pager(session.query(Post).join(User).order_by(desc(Post.created_time)), page_num, limit) posts = p.results # TODO # horribly inefficient; probably a much better way of doing things, perhaps in the template itself? modifiedPosts = [] for post in posts: # TODO # move these to classmethod post.username = post.user.username post.post_url = route_url("view_blog_post", request, post_id = post.id) post.formattedContent = post.getFormattedContent() post.ISOTime = post.getISOTime() post.formattedTime = post.getFormattedTime() modifiedPosts.append(post) if (page_num < p.pages): next_page = page_num + 1 else: next_page = 0 if (page_num > 1): previous_page = page_num - 1 else: previous_page = 0 return dict(title = _("Fluid Nexus Blog"), posts = modifiedPosts, pages = p.pages, page_num = page_num, previous_page = previous_page, next_page = next_page)
def api_nexus_hashes(request): session = DBSession() hashes = session.query(NexusMessage.message_hash).join(User).order_by(desc(NexusMessage.created_time)).all() result = {'hashes': []} for message_hash in hashes: result['hashes'].append(message_hash[0]) return result
def groupfinder(userid, request): session = DBSession() user = session.query(User).join(User.groups).join(Group.group_info).filter(User.id==userid).one() groupNames = [] if (user is not None): groups = user.groups for group in groups: groupNames.append("group:" + group.group_info.group_name) return groupNames
def edit_users(request): session = DBSession() users = session.query(User).order_by(User.id).all() modifiedUsers = [] for user in users: user.edit_url = route_url("edit_user", request, user_id = user.id) modifiedUsers.append(user) return dict(users = modifiedUsers, title = _("Edit users"))
def view_page(request): """View a given page.""" session = DBSession() matchdict = request.matchdict page_location = matchdict["page_location"] try: page = session.query(Page).filter(Page.location == page_location).one() except NoResultFound: return HTTPNotFound(detail = "Requested page not found.") return dict(title = page.title, content = textile.textile(page.content))
def rss(request): num_posts = 10 num_nexus = 10 session = DBSession() posts = session.query(Post).join(User).order_by(desc(Post.created_time)).limit(num_posts) nexus = session.query(NexusMessage).join(User).order_by(desc(NexusMessage.created_time)).limit(num_nexus) items = [] # add a link to each item newPosts = [] for post in posts: link = "http://fluidnexus.net/blog/post/" + str(post.id) setattr(post, "link", link) setattr(post, "guid", link) setattr(post, "categories", ["blog"]) newPosts.append(post) [items.append(post) for post in newPosts] newNexus = [] for message in nexus: link = "http://fluidnexus.net/nexus" setattr(message, "link", link) setattr(message, "guid", message.message_hash) setattr(message, "categories", ["nexus"]) newNexus.append(message) [items.append(message) for message in newNexus] items = sorted(items, key=attrgetter("created_time"), reverse = True) rssItems = [] for item in items: rssItem = PyRSS2Gen.RSSItem(title = item.title, description = textile.textile(item.content), pubDate = datetime.datetime.fromtimestamp(item.created_time), link = item.link, guid = PyRSS2Gen.Guid(item.guid), categories = item.categories, author = item.user.username) rssItems.append(rssItem) rss = PyRSS2Gen.RSS2( title = "Fluid Nexus RSS Feed", link = "http://fluidnexus.net/feed/rss", description = "RSS feed of Nexus and Blog posts from Fluid Nexus", lastBuildDate = datetime.datetime.utcnow(), items = rssItems ) return Response(rss.to_xml(encoding = "utf-8"), content_type="application/rss+xml")
def view_nexus_message(request): session = DBSession() matchdict = request.matchdict message = session.query(NexusMessage).filter(NexusMessage.id == matchdict["message_id"]).one() user = session.query(User).filter(User.id == message.user_id).one() message.username = user.username message.formattedContent = message.getFormattedContent() message.ISOTime = message.getISOTime() message.formattedTime = message.getFormattedTime() # TODO # Add in comment supports; needs a new, separate NexusComment table # message_comment_url = route_url("view_nexus_message", request, message_id = message.id) return dict(title=message.title + _(" || Nexus Message"), message=message)
def edit_pages(request): """List pages to edit.""" session = DBSession() pages = session.query(Page).join(User).order_by(desc(Page.modified_time)).all() modifiedPages = [] for page in pages: page.formatted_time = time.ctime(page.modified_time) page.username = page.user.username page.page_url = route_url("edit_page", request, page_id = page.id) modifiedPages.append(page) # TODO # Figure out how to delete using checkboxes new_page_url = route_url("new_page", request) return dict(title = "Edit pages", new_page_url = new_page_url, pages = modifiedPages)
def register_user(request): session = DBSession() matchdict = request.matchdict if (request.logged_in): request.session.flash(_("You are already logged in and therefore cannot register for a new account.")) return HTTPFound(location = route_url("home", request)) login_url = route_url('login', request) referrer = request.url if (referrer == login_url): referrer = '/' # never use the login form itself as came_from came_from = request.params.get('came_from', referrer) fs = None if 'submitted' in request.params: fs = RegisterUserFieldSet().bind(User, session = session, data = request.params or None) valid = fs.validate() if valid: user = User() password = bcrypt.hashpw(fs.password1.value, bcrypt.gensalt()) # TODO # Shouldn't have to do this, but doing it for simplicity now user.username = fs.username.value user.password = password user.given_name = fs.given_name.value user.surname = fs.surname.value user.homepage = fs.homepage.value #user.email = fs.email.value user.email = bcrypt.hashpw(fs.email.value, bcrypt.gensalt()) user.created_time = time.time() user.user_type = User.NORMAL session.add(user) session.flush() User.addToGroup(fs.username.value, "nexus") request.session["username"] = fs.username.value headers = remember(request, User.getID(fs.username.value)) request.session.flash(_("You have successfully created a new account!")) return HTTPFound(location = route_url("home", request), headers = headers) if (fs is None): fs = RegisterUserFieldSet().bind(User, session = session) form = fs.render() return dict(form = form, title = _("Register new user"))
def doNexusMessages(request=None, page_num=1, limit=10): session = DBSession() # messages = session.query(NexusMessage).join(User).order_by(desc(NexusMessage.created_time)).all() p = Pager(session.query(NexusMessage).join(User).order_by(desc(NexusMessage.created_time)), page_num, limit) messages = p.results # TODO # horribly inefficient; probably a much better way of doing things, perhaps in the template itself? modifiedMessages = [] for message in messages: # TODO # move these to classmethod message.username = message.user.username message.message_url = route_url("view_nexus_message", request, message_id=message.id) message.formattedContent = message.getFormattedContent() message.ISOTime = message.getISOTime() message.formattedTime = message.getFormattedTime() if message.attachment_path != "": fullPath, extension = os.path.splitext(message.attachment_original_filename) message.massaged_attachment_path = ( "/static/attachments/" + os.path.basename(message.attachment_path) + extension ) message.massaged_attachment_path_tn = ( "/static/attachments/" + os.path.basename(message.attachment_path) + "_tn" + extension ) modifiedMessages.append(message) if page_num < p.pages: next_page = page_num + 1 else: next_page = 0 if page_num > 1: previous_page = page_num - 1 else: previous_page = 0 return dict( title=_("Nexus Messages"), messages=modifiedMessages, pages=p.pages, page_num=page_num, previous_page=previous_page, next_page=next_page, )
def edit_blog(request): session = DBSession() posts = session.query(Post).join(User).order_by(desc(Post.modified_time)).all() new_blog_post_url = route_url("new_blog_post", request) modifiedPosts = [] for post in posts: post.formatted_time = time.ctime(post.modified_time) post.username = post.user.username post.post_url = route_url("edit_blog_post", request, post_id = post.id) modifiedPosts.append(post) # TODO # Figure out how to delete using checkboxes #g = Grid(Post, posts) #g.configure(options = [g["title"].readonly()], exclude = [g["modified_time"], g["user"], g["created_time"], g["content"]]) #form = g.render() return dict(title = _("Edit blog posts"), posts = modifiedPosts, new_blog_post_url = new_blog_post_url)
def api_nexus_messages(request): session = DBSession() messages = session.query(NexusMessage).join(User).order_by(desc(NexusMessage.created_time)).all() result = {'messages': []} for message in messages: jsonMessage = {} jsonMessage['title'] = message.title jsonMessage['content'] = message.content jsonMessage['message_hash'] = message.message_hash jsonMessage['created_time'] = message.created_time jsonMessage['attachment_path'] = message.attachment_path jsonMessage['attachment_original_filename'] = message.attachment_original_filename jsonMessage["username"] = message.user.username result['messages'].append(jsonMessage) return result
def new_blog_post(request): session = DBSession() if 'submitted' in request.params: post = Post() fs = FieldSet(Post, data=request.params) post.title = fs.title.value post.content = fs.content.value now = time.time() post.modified_time = now post.created_time = now post.user_id = authenticated_userid(request) session.add(post) return HTTPFound(location = route_url("edit_blog", request)) new_blog_post_url = route_url("new_blog_post", request) fs = FieldSet(Post, session = session) fs.configure(options=[fs.content.textarea(size=(45, 10))], exclude = [fs["modified_time"], fs["user"], fs["comments"], fs["created_time"]]) form = fs.render() return dict(title = _("New Fluid Nexus Blog Post"), form = form, new_blog_post_url = new_blog_post_url)
def edit_blog_post(request): session = DBSession() matchdict = request.matchdict post = session.query(Post).filter(Post.id == matchdict["post_id"]).one() if 'submitted' in request.params: fs = FieldSet(post, data=request.params) # TODO # Not sure why this is necessary...shouldn't I just be able to pass the session to FieldSet and have it sync? post.title = fs.title.value post.content = fs.content.value post.modified_time = time.time() session.add(post) return HTTPFound(location = route_url("view_blog_post", request, post_id = post.id)) if 'delete' in request.params: session.delete(post) return HTTPFound(location = route_url("edit_blog", request)) edit_blog_post_url = route_url("edit_blog_post", request, post_id = post.id) fs = FieldSet(post) fs.configure(options=[fs.content.textarea(size=(45, 10))], exclude = [fs["modified_time"], fs["created_time"], fs["user"]]) form = fs.render() return dict(form = form, title = post.title, edit_blog_post_url = edit_blog_post_url)
def edit_page(request): """Edit a given page.""" session = DBSession() matchdict = request.matchdict page = session.query(Page).join(User).filter(Page.id == matchdict["page_id"]).order_by(desc(Page.modified_time)).one() if 'submitted' in request.params: fs = FieldSet(page, data=request.params) # TODO # add validation # Not sure why this is necessary...shouldn't I just be able to pass the session to FieldSet and have it sync? page.title = fs.title.value page.content = fs.content.value page.modified_time = time.time() page.location = fs.location.value session.add(page) return HTTPFound(location = route_url("view_page", request, page_location = page.location)) elif 'delete' in request.params: session.delete(page) return HTTPFound(location = route_url("edit_pages", request)) edit_blog_post_url = route_url("edit_page", request, page_id = page.id) fs = FieldSet(page) fs.configure(options=[fs.content.textarea(size=(45, 10))], exclude = [fs["modified_time"], fs["created_time"], fs["user"]]) form = fs.render() # TODO # Figure out how to delete using checkboxes return dict(title = "Edit '%s'" % page.title, save_name = save_name, delete_name = delete_name, form = form)
def api_do_authorize_token(request): session = DBSession() matchdict = request.matchdict appType = matchdict.get("appType", "") # First check that the logged in user is the holder of this token given_token = request.params.get("token") token = Token.getByToken(given_token) consumer = ConsumerKeySecret.getByConsumerID(token.consumer_key_secret.id) if (not consumer): request.session.flash(_("Unable to find consumer key in the database; this should never happen!")) return HTTPFound(location = route_url("home", request)) if (token): if (token.consumer_key_secret.user.id != request.logged_in): request.session.flash(_("Attempt to use an authorization token that does not belong to you.")) return HTTPFound(location = route_url("home", request)) else: request.session.flash(_("Malformed authorization token parameters.")) return HTTPFound(location = route_url("home", request)) # Generate a new token to replace this now non-useful authorization token randomData = hashlib.sha1(str(random.random())).hexdigest() key = generateRandomKey() secret = generateRandomKey() token.token = key token.token_secret = secret token.consumer_id = consumer.id token.timestamp = time.time() token.setAccessType() if (appType == "android"): token.callback_url = token.callback_url + "?oauth_token=%s&oauth_token_secret=%s" % (token.token, token.token_secret) session.add(token) return HTTPFound(location = token.callback_url)
def new_page(request): session = DBSession() if 'submitted' in request.params: page = Page() fs = FieldSet(Page, data=request.params) page.title = fs.title.value page.content = fs.content.value page.location = fs.location.value.lower() now = time.time() page.modified_time = now page.created_time = now page.user_id = authenticated_userid(request) session.add(page) return HTTPFound(location = route_url("edit_pages", request)) new_page_url = route_url("new_page", request) fs = FieldSet(Page, session = session) fs.configure(options=[fs.content.textarea(size=(45, 10))], exclude = [fs["modified_time"], fs["user"], fs["created_time"]]) form = fs.render() return dict(title = "Create new Fluid Nexus page", save_name = save_name, form = form)
def edit_user(request): session = DBSession() matchdict = request.matchdict if (request.logged_in != int(matchdict["user_id"])): return HTTPForbidden(_("You are not allowed to view information about a user other than yourself.")) user = session.query(User).join(User.groups).join(Group.group_info).filter(User.id == matchdict["user_id"]).one() if (user.user_type == User.OPENID): fs = UserNoPasswordFieldSet().bind(user, session = session, data = request.POST or None) else: fs = UserFieldSet().bind(user, session = session, data = request.POST or None) if 'submitted' in request.params: valid = fs.validate() if valid: if user.user_type == User.NORMAL: user.password = bcrypt.hashpw(fs.password1.value, bcrypt.gensalt()) fs.sync() return HTTPFound(location = route_url("view_user", request, user_id = request.logged_in)) form = fs.render() return dict(form = form, title = _("Edit") + " " + user.username)
def api_request_key(request): session = DBSession() if (not request.logged_in): request.session.flash(_("You must be registered and logged in to request a consumer key and secret.")) return HTTPForbidden(location = route_url("home", request)) keySecret = ConsumerKeySecret.getByUserID(request.logged_in) if (keySecret): key = keySecret.consumer_key secret = keySecret.consumer_secret else: # generate a consumer key and secret randomData = hashlib.sha1(str(random.random())).hexdigest() keySecret = ConsumerKeySecret() key = generateRandomKey() secret = generateRandomKey() keySecret.consumer_key = key keySecret.consumer_secret = secret keySecret.user_id = request.logged_in keySecret.setNormalStatus() session.add(keySecret) return dict(key = key, secret = secret, title = _("Fluid Nexus Key and Secret"))
def reset_password(request): session = DBSession() matchdict = request.matchdict token = matchdict["token"] forgotPassword = ForgotPassword.getByToken(token) if (not forgotPassword): request.session.flash(_("Reset password token not found in database.")) return HTTPFound(location = route_url("home", request)) if (request.logged_in): request.session.flash(_("You are already logged in and therefore cannot reset a password.")) return HTTPFound(location = route_url("home", request)) login_url = route_url('login', request) referrer = request.url if (referrer == login_url): referrer = '/' # never use the login form itself as came_from came_from = request.params.get('came_from', referrer) user = User.getByID(forgotPassword.user.id) fs = None if 'submitted' in request.params: fs = ResetPasswordFieldSet().bind(User, session = session, data = request.params or None) valid = fs.validate() if valid: user = User.getByID(request.params["user_id"]) password = bcrypt.hashpw(fs.password1.value, bcrypt.gensalt()) user.password = password user.user_type = User.NORMAL session.add(user) session.flush() session.query(ForgotPassword).filter(ForgotPassword.user_id == user.id).delete() request.session["username"] = user.username headers = remember(request, user.id) request.session.flash(_("You have successfully updated your password!")) return HTTPFound(location = route_url("home", request), headers = headers) if (fs is None): fs = ResetPasswordFieldSet().bind(User, session = session) form = fs.render() return dict(form = form, user_id = user.id, title = _("Forgot your password?"))
def register_user_openid(request): session = DBSession() matchdict = request.matchdict if (request.logged_in): request.session.flash(_("You are already logged in and therefore cannot register for a new account.")) return HTTPFound(location = route_url("home", request)) fs = OpenIDUserFieldSet().bind(User, session = session) fs.append(Field("openid_url", value = request.params.get("openid_url", "")).hidden()) if 'submitted' in request.params: fs = OpenIDUserFieldSet().bind(User, session = session, data = request.params or None) valid = fs.validate() if valid: user = User() # TODO # Shouldn't have to do this, but doing it for simplicity now # Should validate that the username is unique user.username = fs.username.value user.given_name = fs.given_name.value user.surname = fs.surname.value user.homepage = fs.homepage.value user.user_type = User.OPENID now = time.time() user.created_time = now user.password = bcrypt.hashpw(str(int(now)), bcrypt.gensalt()) session.add(user) session.flush() User.addToGroup(fs.username.value, "nexus") request.session["username"] = fs.username.value user_id = User.getID(fs.username.value) openid = OpenID(openid_url = request.params.get("openid_url", ""), user_id = user_id) session.add(openid) headers = remember(request, user_id) request.session["username"] = fs.username.value request.session.flash(_("You have successfully registered!")) return HTTPFound(location = route_url("home", request), headers = headers) form = fs.render() return dict(form = form, title = _("Register new user"))
def view_blog_post(request): session = DBSession() matchdict = request.matchdict post = session.query(Post).filter(Post.id == matchdict["post_id"]).one() user = session.query(User).filter(User.id == post.user_id).one() post.username = user.username post_comment_url = route_url("view_blog_post", request, post_id = post.id) fs = None # TODO # * make form validation better and more attractive # * add in field that asks for user to type word to submit form if 'submitted' in request.params: comment = Comment() fs = CommentFieldSet().bind(Comment, session = session, data = request.POST or None) valid = fs.validate() if valid: comment.name = fs.name.value comment.email = fs.email.value comment.homepage = fs.homepage.value comment.content = fs.content.value now = time.time() comment.created_time = now comment.post_id = post.id session.add(comment) request.session.flash(_("Your comment was successfully posted.")) fs = None comments = session.query(Comment).filter(Comment.post_id == post.id).order_by(desc(Comment.created_time)) if (fs is None): fs = CommentFieldSet().bind(Comment, session = session) comment_form = fs.render() return dict(title = post.title + _(" || Fluid Nexus Blog Post"), post = post, comments = comments, comment_form = comment_form, post_comment_url = post_comment_url)
def forgot_password(request): session = DBSession() matchdict = request.matchdict if (request.logged_in): request.session.flash(_("You are already logged in and therefore cannot request a new password.")) return HTTPFound(location = route_url("home", request)) login_url = route_url('login', request) referrer = request.url if (referrer == login_url): referrer = '/' # never use the login form itself as came_from came_from = request.params.get('came_from', referrer) fs = None if 'submitted' in request.params: fs = ForgotPasswordFieldSet().bind(User, session = session, data = request.params or None) valid_user = User.checkEmail(fs.username.value, fs.email.value) if (not valid_user): request.session.flash(_("E-mail and password combination do not match.")) return HTTPFound(location = route_url("home", request)) #user = User.getByEmail(fs.email.value) token = str(time.time()) # Generate salt for x in xrange(0, 10): token += str(random.randint(0, 100)) token = hashlib.sha256(token).hexdigest() fp = ForgotPassword(token = token) fp.user_id = valid_user.id session.add(fp) valid_user.user_type = User.FORGOT_PASSWORD session.add(valid_user) # Import smtplib for the actual sending function import smtplib # Import the email modules we'll need from email.mime.text import MIMEText text = """Please go to the following link to reset your password: http://fluidnexus.net/reset_password/%s If you have any questions please reply to this e-mail. Best, fluidnexus.net""" % token msg = MIMEText(text) msg["Subject"] = "Forgotten password for %s" % (fs.email.value) msg["From"] = "*****@*****.**" msg["To"] = fs.email.value s = smtplib.SMTP("localhost") s.sendmail("*****@*****.**", [fs.email.value], msg.as_string()) s.quit() request.session.flash(_("Please check your e-mail for the link to reset your password.")) return HTTPFound(location = route_url("home", request)) if (fs is None): fs = ForgotPasswordFieldSet().bind(User, session = session) form = fs.render() return dict(form = form, title = _("Forgot your password?"))
def api_request_token(request): session = DBSession() auth_header = {} matchdict = request.matchdict appType = matchdict.get("appType", False) if ('Authorization' in request.headers): auth_header = {'Authorization': request.headers['Authorization']} req = oauth2.Request.from_request( request.method, request.url, headers = auth_header, parameters = dict([(k,v) for k,v in request.params.iteritems()])) consumer = ConsumerKeySecret.getByConsumerKey(req.get("oauth_consumer_key")) #if (request.logged_in != consumer.id): # request.session.flash(_("You are trying to request a token using credentials that do not belong to you.")) # return HTTPForbidden(location = route_url("home", request)) try: oauth_server.verify_request(req, consumer, None) # Check that this user doesn't already have an access token consumerToken = Token.getByConsumerID(consumer.id) if consumerToken: if (consumerToken.token_type == consumerToken.ACCESS): return Response(simplejson.dumps({'result': route_url('api_access_token', request)})) elif (consumerToken.token_type == consumerToken.AUTHORIZATION): # TODO # Check that the token hasn't already expired token = oauth2.Token(consumerToken.token, consumerToken.token_secret) if (appType == "android"): return Response(token.to_string()) else: return Response(simplejson.dumps({'result': route_url('api_authorize_token', request, appType = appType) + '?' + token.to_string()})) nonce = ConsumerNonce.getByNonce(req.get("oauth_nonce")) if (nonce): return simplejson.dumps({"error": "Nonce is already registered for an authorization token; please generate another request token, or wait five minutes and try again."}) else: nonce = ConsumerNonce() nonce.consumer_id = consumer.id nonce.timestamp = req.get("oauth_timestamp") nonce.nonce = req.get("oauth_nonce") session.add(nonce) randomData = hashlib.sha1(str(random.random())).hexdigest() key = generateRandomKey() secret = generateRandomKey() token = oauth2.Token(key, secret) token.callback_confirmed = True tokenData = Token() tokenData.token = key tokenData.token_secret = secret tokenData.consumer_id = consumer.id tokenData.timestamp = time.time() tokenData.callback_url = req.get("oauth_callback") tokenData.setAuthorizationType() session.add(tokenData) if (appType == "android"): return Response(token.to_string()) elif (appType == "desktop"): result = {'result': route_url('api_authorize_token', request, appType = appType) + '?' + token.to_string()} return Response(simplejson.dumps(result)) except oauth2.Error, e: return Response(simplejson.dumps({"oauth2 error": str(e)}))