Exemple #1
0
// HandleUpdate responds to POST /comments/update
func HandleUpdate(context router.Context) error {

	// Find the comment
	comment, err := comments.Find(context.ParamInt("id"))
	if err != nil {
		return router.NotFoundError(err)
	}

	// Authorise update comment, check auth token
	err = authorise.ResourceAndAuthenticity(context, comment)
	if err != nil {
		return router.NotAuthorizedError(err)
	}

	// Update the comment from params
	params, err := context.Params()
	if err != nil {
		return router.InternalError(err)
	}

	// Clean params according to role
	accepted := comments.AllowedParams()
	if authorise.CurrentUser(context).Admin() {
		accepted = comments.AllowedParamsAdmin()
	}
	cleanedParams := params.Clean(accepted)

	err = comment.Update(cleanedParams)
	if err != nil {
		return router.InternalError(err)
	}

	// Redirect to comment
	return router.Redirect(context, comment.URLShow())
}
Exemple #2
0
// HandleDownvote handles POST to /stories/123/downvote
func HandleDownvote(context router.Context) error {

	// Prevent CSRF
	err := authorise.AuthenticityToken(context)
	if err != nil {
		return router.NotAuthorizedError(err, "Vote Failed", "CSRF failure")
	}

	// Find the story
	story, err := stories.Find(context.ParamInt("id"))
	if err != nil {
		return router.NotFoundError(err)
	}
	user := authorise.CurrentUser(context)
	ip := getUserIP(context)

	if !user.Admin() {
		// Check we have no votes already from this user, if we do fail
		if storyHasUserVote(story, user) {
			return router.NotAuthorizedError(err, "Vote Failed", "Sorry you are not allowed to vote twice, nice try!")
		}
	}

	// Authorise upvote on story for this user - our rules are:
	if !user.CanDownvote() {
		return router.NotAuthorizedError(err, "Vote Failed", "Sorry, you can't downvote yet")
	}

	err = authorise.Resource(context, story)
	if err != nil {
		return router.NotAuthorizedError(err, "Vote Failed", "Sorry you are not allowed to vote")
	}

	err = adjustUserPoints(user, -1)
	if err != nil {
		return err
	}

	// Adjust points on story and add to the vote table
	err = addStoryVote(story, user, ip, -1)
	if err != nil {
		return err
	}

	return updateStoriesRank()
}
Exemple #3
0
// HandleFlag handles POST to /stories/123/flag
func HandleFlag(context router.Context) error {

	// Protect against CSRF
	err := authorise.AuthenticityToken(context)
	if err != nil {
		return router.NotAuthorizedError(err, "Flag Failed", "CSRF failure")
	}

	// Find the story
	story, err := stories.Find(context.ParamInt("id"))
	if err != nil {
		return router.NotFoundError(err)
	}
	user := authorise.CurrentUser(context)
	ip := getUserIP(context)

	// Check we have no votes already from this user, if we do fail
	if storyHasUserFlag(story, user) {
		return router.NotAuthorizedError(err, "Flag Failed", "Sorry you are not allowed to flag twice, nice try!")
	}

	// Authorise upvote on story for this user
	if !user.CanFlag() {
		return router.NotAuthorizedError(err, "Flag Failed", "Sorry, you can't flag yet")
	}

	err = authorise.Resource(context, story)
	if err != nil {
		return router.NotAuthorizedError(err, "Flag Failed", "Sorry you are not allowed to flag")
	}

	err = adjustUserPoints(user, -1)
	if err != nil {
		return err
	}

	err = addStoryVote(story, user, ip, -5)
	if err != nil {
		return err
	}
	return updateStoriesRank()
}
Exemple #4
0
// HandleDownvote handles POST to /comments/123/downvote
func HandleDownvote(context router.Context) error {

	// Prevent CSRF
	err := authorise.AuthenticityToken(context)
	if err != nil {
		return router.NotAuthorizedError(err, "Vote Failed", "CSRF failure")
	}

	// Find the comment
	comment, err := comments.Find(context.ParamInt("id"))
	if err != nil {
		return router.NotFoundError(err)
	}
	user := authorise.CurrentUser(context)
	ip := getUserIP(context)

	if !user.Admin() {
		// Check we have no votes already from this user, if we do fail
		if commentHasUserVote(comment, user) {
			return router.NotAuthorizedError(err, "Vote Failed", "Sorry you are not allowed to vote twice, nice try!")
		}
	}

	// Authorise upvote on comment for this user - our rules are:
	if !user.CanDownvote() {
		return router.NotAuthorizedError(err, "Vote Failed", "Sorry, you can't downvote yet")
	}

	// CURRENT User burns points for downvoting
	err = adjustUserPoints(user, -1)
	if err != nil {
		return err
	}

	// Adjust points on comment and add to the vote table
	err = addCommentVote(comment, user, ip, -1)
	if err != nil {
		return err
	}

	return updateCommentsRank(comment.StoryId)
}
Exemple #5
0
// HandleLoginShow shows the page at /users/login
func HandleLoginShow(context router.Context) error {
	// Setup context for template
	view := view.New(context)

	// Check we're not already logged in, if so redirect with a message
	// we could alternatively display an error here?
	if !authorise.CurrentUser(context).Anon() {
		return router.Redirect(context, "/?warn=already_logged_in")
	}

	switch context.Param("error") {
	case "failed_email":
		view.AddKey("warning", "Sorry, we couldn't find a user with that email.")
	case "failed_password":
		view.AddKey("warning", "Sorry, the password was incorrect, please try again.")
	}

	// Serve
	return view.Render()
}
Exemple #6
0
// HandleUpdate handles the POST of the form to update a story
func HandleUpdate(context router.Context) error {

	// Find the story
	story, err := stories.Find(context.ParamInt("id"))
	if err != nil {
		return router.NotFoundError(err)
	}

	// Authorise update story
	err = authorise.ResourceAndAuthenticity(context, story)
	if err != nil {
		return router.NotAuthorizedError(err)
	}

	// Update the story from params
	params, err := context.Params()
	if err != nil {
		return router.InternalError(err)
	}

	// Clean params according to role
	accepted := stories.AllowedParams()
	if authorise.CurrentUser(context).Admin() {
		accepted = stories.AllowedParamsAdmin()
	}
	cleanedParams := params.Clean(accepted)

	err = story.Update(cleanedParams)
	if err != nil {
		return err // Create returns a router.Error
	}

	err = updateStoriesRank()
	if err != nil {
		return router.InternalError(err)
	}

	// Redirect to story
	return router.Redirect(context, story.URLShow())
}
Exemple #7
0
// HandleUpdate or PUT /users/1/update
func HandleUpdate(context router.Context) error {

	// Find the user
	id := context.ParamInt("id")
	user, err := users.Find(id)
	if err != nil {
		context.Logf("#error Error finding user %s", err)
		return router.NotFoundError(err)
	}

	// Authorise
	err = authorise.ResourceAndAuthenticity(context, user)
	if err != nil {
		return router.NotAuthorizedError(err)
	}

	// Get the params
	params, err := context.Params()
	if err != nil {
		return router.InternalError(err)
	}

	// Clean params according to role
	accepted := users.AllowedParams()
	if authorise.CurrentUser(context).Admin() {
		accepted = users.AllowedParamsAdmin()
	}
	allowedParams := params.Clean(accepted)
	err = user.Update(allowedParams)
	if err != nil {
		return router.InternalError(err)
	}

	// Redirect to user
	return router.Redirect(context, user.URLShow())
}
// HandleCreate handles the POST of the create form for comments
func HandleCreate(context router.Context) error {

	// Authorise csrf token
	err := authorise.AuthenticityToken(context)
	if err != nil {
		return router.NotAuthorizedError(err)
	}

	// Check permissions - if not logged in and above 0 points, redirect
	if !authorise.CurrentUser(context).CanComment() {
		return router.NotAuthorizedError(nil, "Sorry", "You need to be registered and have more than 0 points to comment.")
	}

	// Setup context
	params, err := context.Params()
	if err != nil {
		return router.InternalError(err)
	}

	// Find parent story - this must exist
	story, err := stories.Find(params.GetInt("story_id"))
	if err != nil {
		return router.NotFoundError(err)
	}

	params.SetInt("story_id", story.Id)
	params.Set("story_name", story.Name)

	// Set a few params
	user := authorise.CurrentUser(context)
	params.SetInt("user_id", user.Id)
	params.Set("user_name", user.Name)
	params.SetInt("points", 1)

	// Find the parent and set dotted id
	// these are of the form xx.xx. with a trailing dot
	// this saves us from saving twice on create
	parentID := context.ParamInt("parent_id")
	if parentID > 0 {
		parent, err := comments.Find(parentID)
		if err != nil {
			return router.NotFoundError(err)
		}
		context.Logf("PARENT:%d - %s", parent.Id, parent.DottedIds)
		params.Set("dotted_ids", fmt.Sprintf(parent.DottedIds+"."))
	}

	id, err := comments.Create(params.Map())
	if err != nil {
		return router.InternalError(err)
	}

	// Log creation
	context.Logf("#info Created comment id,%d", id)

	// Update the story comment Count

	storyParams := map[string]string{"comment_count": fmt.Sprintf("%d", story.CommentCount+1)}
	err = story.Update(storyParams)
	if err != nil {
		return router.InternalError(err, "Error", "Could not update story.")
	}

	// Redirect to the new comment
	m, err := comments.Find(id)
	if err != nil {
		return router.InternalError(err)
	}

	// Re-rank comments on this story
	err = updateCommentsRank(m.StoryId)
	if err != nil {
		return err
	}

	return router.Redirect(context, m.URLStory())
}
// HandleCreate handles the POST of the create form for stories
func HandleCreate(context router.Context) error {

	// Check csrf token
	err := authorise.AuthenticityToken(context)
	if err != nil {
		return router.NotAuthorizedError(err)
	}

	// Check permissions - if not logged in and above 1 points, redirect to error
	if !authorise.CurrentUser(context).CanSubmit() {
		return router.NotAuthorizedError(nil, "Sorry", "You need to be registered and have more than 1 points to submit stories.")
	}

	// Get user details
	user := authorise.CurrentUser(context)
	ip := getUserIP(context)

	// Check that no story with this url already exists
	q := stories.Where("url=?", context.Param("url"))
	duplicates, err := stories.FindAll(q)
	if err != nil {
		return router.InternalError(err)
	}

	if len(duplicates) > 0 {
		dupe := duplicates[0]
		// Add a point to dupe
		addStoryVote(dupe, user, ip, 1)

		return router.Redirect(context, dupe.URLShow())
	}

	// Setup context
	params, err := context.Params()
	if err != nil {
		return router.InternalError(err)
	}

	// Set a few params
	params.SetInt("points", 1)
	params.SetInt("user_id", user.Id)
	params.Set("user_name", user.Name)

	id, err := stories.Create(params.Map())
	if err != nil {
		return err // Create returns a router.Error
	}

	// Log creation
	context.Logf("#info Created story id,%d", id)

	// Redirect to the new story
	story, err := stories.Find(id)
	if err != nil {
		return router.InternalError(err)
	}

	// We need to add a vote to the story here too by adding a join to the new id
	err = recordStoryVote(story, user, ip, +1)
	if err != nil {
		return err
	}

	// Re-rank stories
	err = updateStoriesRank()
	if err != nil {
		return err
	}

	return router.Redirect(context, story.URLIndex())
}
Exemple #10
0
// HandleCreate handles the POST of the create form for stories
func HandleCreate(context router.Context) error {

	// Check csrf token
	err := authorise.AuthenticityToken(context)
	if err != nil {
		return router.NotAuthorizedError(err)
	}

	// Check permissions - if not logged in and above 1 points, redirect to error
	if !authorise.CurrentUser(context).CanSubmit() {
		return router.NotAuthorizedError(nil, "Sorry", "You need to be registered and have more than 1 points to submit stories.")
	}

	// Get params
	params, err := context.Params()
	if err != nil {
		return router.InternalError(err)
	}

	// Get user details
	user := authorise.CurrentUser(context)
	ip := getUserIP(context)
	url := params.Get("url")

	// Strip trailing slashes on url before comparisons
	// we could possibly also strip url fragments
	if strings.HasSuffix(url, "/") {
		url = strings.Trim(url, "/")
		params.Set("url", url)
	}

	// Check that no story with this url already exists
	q := stories.Where("url=?", url)
	duplicates, err := stories.FindAll(q)
	if err != nil {
		return router.InternalError(err)
	}

	if len(duplicates) > 0 {
		dupe := duplicates[0]
		// Add a point to dupe and return
		addStoryVote(dupe, user, ip, 1)
		return router.Redirect(context, dupe.URLShow())
	}
	// Clean params according to role
	accepted := stories.AllowedParams()
	if authorise.CurrentUser(context).Admin() {
		accepted = stories.AllowedParamsAdmin()
	}
	cleanedParams := params.Clean(accepted)

	// Set a few params
	cleanedParams["points"] = "1"
	cleanedParams["user_id"] = fmt.Sprintf("%d", user.Id)
	cleanedParams["user_name"] = user.Name

	id, err := stories.Create(cleanedParams)
	if err != nil {
		return err // Create returns a router.Error
	}

	// Log creation
	context.Logf("#info Created story id,%d", id)

	// Redirect to the new story
	story, err := stories.Find(id)
	if err != nil {
		return router.InternalError(err)
	}

	// We need to add a vote to the story here too by adding a join to the new id
	err = recordStoryVote(story, user, ip, +1)
	if err != nil {
		return err
	}

	// Re-rank stories
	err = updateStoriesRank()
	if err != nil {
		return err
	}

	return router.Redirect(context, story.URLIndex())
}
Exemple #11
0
// HandleCreate handles the POST of the create form for stories
func HandleCreate(context router.Context) error {

	// Check csrf token
	err := authorise.AuthenticityToken(context)
	if err != nil {
		return router.NotAuthorizedError(err)
	}

	// Check permissions - if not logged in and above 1 points, redirect to error
	if !authorise.CurrentUser(context).CanSubmit() {
		return router.NotAuthorizedError(nil, "Sorry", "You need to be registered and have more than 1 points to submit stories.")
	}

	// Get params
	params, err := context.Params()
	if err != nil {
		return router.InternalError(err)
	}

	// Get user details
	user := authorise.CurrentUser(context)
	ip := getUserIP(context)

	// Process urls
	url := params.Get("url")

	// Strip trailing slashes on url before comparisons
	if strings.HasSuffix(url, "/") {
		url = strings.Trim(url, "/")
	}

	// Strip ?utm_source etc - remove all after ?utm_source
	if strings.Contains(url, "?utm_") {
		url = strings.Split(url, "?utm_")[0]
	}

	// Strip url fragments (For example trailing # on medium urls)
	if strings.Contains(url, "#") {
		url = strings.Split(url, "#")[0]
	}

	// Rewrite mobile youtube links
	if strings.HasPrefix(url, "https://m.youtube.com") {
		url = strings.Replace(url, "https://m.youtube.com", "https://www.youtube.com", 1)
	}

	params.Set("url", url)

	// Check that no story with this url already exists
	q := stories.Where("url=?", url)
	duplicates, err := stories.FindAll(q)
	if err != nil {
		return router.InternalError(err)
	}

	if len(duplicates) > 0 {
		story := duplicates[0]

		// Check we have no votes already from this user, if we do fail
		if storyHasUserVote(story, user) {
			return router.NotAuthorizedError(err, "Vote Failed", "Sorry you are not allowed to vote twice, nice try!")

		}

		// Add a point to dupe and return
		addStoryVote(story, user, ip, 1)
		return router.Redirect(context, story.URLShow())
	}
	// Clean params according to role
	accepted := stories.AllowedParams()
	if authorise.CurrentUser(context).Admin() {
		accepted = stories.AllowedParamsAdmin()
	}
	cleanedParams := params.Clean(accepted)

	// Set a few params
	cleanedParams["points"] = "1"
	cleanedParams["user_id"] = fmt.Sprintf("%d", user.Id)
	cleanedParams["user_name"] = user.Name

	id, err := stories.Create(cleanedParams)
	if err != nil {
		return err // Create returns a router.Error
	}

	// Log creation
	context.Logf("#info Created story id,%d", id)

	// Redirect to the new story
	story, err := stories.Find(id)
	if err != nil {
		return router.InternalError(err)
	}

	// We need to add a vote to the story here too by adding a join to the new id
	err = recordStoryVote(story, user, ip, +1)
	if err != nil {
		return err
	}

	// Re-rank stories
	err = updateStoriesRank()
	if err != nil {
		return err
	}

	return router.Redirect(context, story.URLIndex())
}