github.com/bitcubate/cryptojournal@v1.2.5-0.20171102134152-f578b3d788ab/src/comments/actions/create.go (about)

     1  package commentactions
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  
     7  	"github.com/fragmenta/auth/can"
     8  	"github.com/fragmenta/mux"
     9  	"github.com/fragmenta/server"
    10  	"github.com/fragmenta/server/log"
    11  	"github.com/fragmenta/view"
    12  
    13  	"github.com/bitcubate/cryptojournal/src/comments"
    14  	"github.com/bitcubate/cryptojournal/src/lib/session"
    15  	"github.com/bitcubate/cryptojournal/src/stories"
    16  )
    17  
    18  // HandleCreateShow serves the create form via GET for comments.
    19  func HandleCreateShow(w http.ResponseWriter, r *http.Request) error {
    20  
    21  	comment := comments.New()
    22  
    23  	// Authorise
    24  	err := can.Create(comment, session.CurrentUser(w, r))
    25  	if err != nil {
    26  		return server.NotAuthorizedError(err)
    27  	}
    28  
    29  	// Render the template
    30  	view := view.NewRenderer(w, r)
    31  	view.AddKey("comment", comment)
    32  	return view.Render()
    33  }
    34  
    35  // HandleCreate handles the POST of the create form for comments
    36  func HandleCreate(w http.ResponseWriter, r *http.Request) error {
    37  
    38  	comment := comments.New()
    39  
    40  	// Check the authenticity token
    41  	err := session.CheckAuthenticity(w, r)
    42  	if err != nil {
    43  		return err
    44  	}
    45  
    46  	// Authorise
    47  	currentUser := session.CurrentUser(w, r)
    48  	err = can.Create(comment, currentUser)
    49  	if err != nil {
    50  		return server.NotAuthorizedError(err)
    51  	}
    52  
    53  	// Check permissions - if not logged in and above 0 points, redirect
    54  	if !currentUser.CanComment() {
    55  		return server.NotAuthorizedError(nil, "Sorry", "You need to be registered and have more than 0 points to comment.")
    56  	}
    57  
    58  	// Get Params
    59  	params, err := mux.Params(r)
    60  	if err != nil {
    61  		return server.InternalError(err)
    62  	}
    63  
    64  	text := params.Get("text")
    65  
    66  	// Disallow empty comments
    67  	if len(text) < 5 {
    68  		return server.NotAuthorizedError(nil, "Comment too short", "Your comment is too short. Please try to post substantive comments which others will find useful.")
    69  	}
    70  
    71  	// Disallow comments which are too long
    72  	if len(text) > 5000 {
    73  		return server.NotAuthorizedError(nil, "Comment too long", "Your comment is too long.")
    74  	}
    75  
    76  	// Find parent story - this must exist
    77  	story, err := stories.Find(params.GetInt("story_id"))
    78  	if err != nil {
    79  		return server.NotFoundError(err)
    80  	}
    81  
    82  	// Clean params according to role
    83  	accepted := comments.AllowedParams()
    84  	if currentUser.Admin() {
    85  		accepted = comments.AllowedParamsAdmin()
    86  	}
    87  	commentParams := comment.ValidateParams(params.Map(), accepted)
    88  
    89  	// Find the parent to set dotted id
    90  	// these are of the form xx.xx. with a trailing dot
    91  	// this saves us from saving twice on create
    92  	parentID := params.GetInt("parent_id")
    93  	if parentID > 0 {
    94  
    95  		parent, e := comments.Find(parentID)
    96  		if e != nil {
    97  			return server.NotFoundError(err)
    98  		}
    99  		commentParams["dotted_ids"] = fmt.Sprintf(parent.DottedIDs + ".")
   100  	}
   101  
   102  	// Set other params from story/user details
   103  	commentParams["story_id"] = fmt.Sprintf("%d", story.ID)
   104  	commentParams["story_name"] = story.Name
   105  	commentParams["user_id"] = fmt.Sprintf("%d", currentUser.ID)
   106  	commentParams["user_name"] = currentUser.Name
   107  	commentParams["points"] = "1"
   108  
   109  	ID, err := comment.Create(commentParams)
   110  	if err != nil {
   111  		return server.InternalError(err)
   112  	}
   113  
   114  	// Log comment creation
   115  	log.Info(log.Values{"msg": "Created comment", "comment_id": ID, "params": commentParams})
   116  
   117  	// Update the story comment count with a count of comments above 0 points
   118  	err = updateStoryCommentCount(story)
   119  	if err != nil {
   120  		return server.InternalError(err, "Error", "Could not update story.")
   121  	}
   122  
   123  	// Redirect to the new comment
   124  	comment, err = comments.Find(ID)
   125  	if err != nil {
   126  		return server.InternalError(err)
   127  	}
   128  
   129  	// Re-rank comments on this story
   130  	err = updateCommentsRank(comment.StoryID)
   131  	if err != nil {
   132  		return err
   133  	}
   134  
   135  	return server.Redirect(w, r, comment.StoryURL())
   136  }