Beispiel #1
0
// Auth is a gin middleware that checks for session cookie and
// handles permissions
func Auth(authenticated bool) gin.HandlerFunc {
	return func(c *gin.Context) {

		// error if theres no secret set
		if Secret == "" {
			c.JSON(e.ErrorMessage(e.ErrInternalError))
			c.Error(e.ErrNoSecret).SetMeta("auth.Auth")
			c.Abort()
			return
		}

		// set default anonymous user
		user := DefaultUser()

		// try and get the jwt cookie from the request
		cookie, err := c.Request.Cookie(CookieName)
		// parse jwt token if its there
		if err != http.ErrNoCookie {
			token, err := jwt.ParseWithClaims(cookie.Value, &TokenClaims{}, func(token *jwt.Token) (interface{}, error) {
				return validateToken(token, &user)
			})
			// if theres some jwt error other than no token in request or the token is
			// invalid then return unauth
			// the client side should delete any saved JWT tokens on unauth error
			if err != nil || !token.Valid {
				// delete the cookie
				http.SetCookie(c.Writer, DeleteCookie())
				c.JSON(e.ErrorMessage(e.ErrUnauthorized))
				c.Error(err).SetMeta("user.Auth")
				c.Abort()
				return
			}
		}

		// check if user needed to be authenticated
		// this needs to be like this for routes that dont need auth
		// if we just check equality then logged in users wont be able
		// to view anon pages ;P
		if authenticated && !user.IsAuthenticated {
			c.JSON(e.ErrorMessage(e.ErrForbidden))
			c.Error(e.ErrForbidden).SetMeta("user.Auth")
			c.Abort()
			return
		}

		// set user data for controllers
		c.Set("userdata", user)

		c.Next()

	}

}
Beispiel #2
0
// ErrorController handles error messages for wrong routes
func ErrorController(c *gin.Context) {

	c.JSON(e.ErrorMessage(e.ErrNotFound))

	return

}
Beispiel #3
0
// ValidateParams will loop through the route parameters to make sure theyre uint
func ValidateParams() gin.HandlerFunc {
	return func(c *gin.Context) {

		if c.Params != nil {

			var params []uint

			for _, param := range c.Params {

				pid, err := ValidateParam(param.Value)
				if err != nil {
					c.JSON(e.ErrorMessage(e.ErrInvalidParam))
					c.Error(err).SetMeta("validate.ValidateParams")
					c.Abort()
					return
				}

				params = append(params, pid)

			}

			c.Set("params", params)

		}

		c.Next()

	}
}
Beispiel #4
0
// BoardLogController will get the the board audit log
func BoardLogController(c *gin.Context) {

	// Get parameters from validate middleware
	params := c.MustGet("params").([]uint)

	if !c.MustGet("protected").(bool) {
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(e.ErrInternalError).SetMeta("BoardLogController.protected")
		return
	}

	// Initialize model struct
	m := &models.BoardLogModel{
		Ib:   params[0],
		Page: params[1],
	}

	// Get the model which outputs JSON
	err := m.Get()
	if err == e.ErrNotFound {
		c.JSON(e.ErrorMessage(e.ErrNotFound))
		c.Error(err).SetMeta("BoardLogController.Get")
		return
	} else if err != nil {
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(err).SetMeta("BoardLogController.Get")
		return
	}

	// Marshal the structs into JSON
	output, err := json.Marshal(m.Result)
	if err != nil {
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(err).SetMeta("BoardLogController.json.Marshal")
		return
	}

	c.Data(200, "application/json", output)

	return

}
Beispiel #5
0
// Verify the sent csrf token
func Verify() gin.HandlerFunc {
	return func(c *gin.Context) {

		// if this is a skippable method
		if skipMethods[c.Request.Method] {
			c.Next()
			return
		}

		// the token from the users cookie
		var csrfToken []byte

		// get the token from the cookie
		tokenCookie, err := c.Request.Cookie(CookieName)
		if err == nil {
			csrfToken = b64decode(tokenCookie.Value)
		}

		var sentToken string

		// Prefer the header over form value
		sentToken = c.Request.Header.Get(HeaderName)

		// Then POST values
		if len(sentToken) == 0 {
			sentToken = c.PostForm(FormFieldName)
		}

		// error if there was no csrf token or it isnt verified
		if csrfToken == nil || !verifyToken(csrfToken, b64decode(sentToken)) {
			c.JSON(e.ErrorMessage(e.ErrForbidden))
			c.Error(e.ErrCsrfNotValid).SetMeta("csrf.Verify")
			c.Abort()
			return
		}

		c.Next()

	}
}
Beispiel #6
0
// Protect will check to see if a user has the correct permissions
// A route protected by this middleware needs an ib parameter
func Protect() gin.HandlerFunc {
	return func(c *gin.Context) {

		// Get parameters from validate middleware
		params := c.MustGet("params").([]uint)

		// get userdata from session middleware
		userdata := c.MustGet("userdata").(User)

		// check if user is authorized
		if !userdata.IsAuthorized(params[0]) {
			c.JSON(e.ErrorMessage(e.ErrForbidden))
			c.Error(e.ErrForbidden).SetMeta("user.Protect.IsAuthorized")
			c.Abort()
			return
		}

		// this route was protected
		c.Set("protected", true)

		c.Next()

	}
}
Beispiel #7
0
// CloseThreadController will toggle a threads close bool
func CloseThreadController(c *gin.Context) {

	// Get parameters from validate middleware
	params := c.MustGet("params").([]uint)

	// get userdata from user middleware
	userdata := c.MustGet("userdata").(user.User)

	if !c.MustGet("protected").(bool) {
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(e.ErrInternalError).SetMeta("CloseThreadController.protected")
		return
	}

	// Initialize model struct
	m := &models.CloseModel{
		Ib: params[0],
		ID: params[1],
	}

	// Check the record id and get further info
	err := m.Status()
	if err == e.ErrNotFound {
		c.JSON(e.ErrorMessage(e.ErrNotFound))
		c.Error(err).SetMeta("CloseThreadController.Status")
		return
	} else if err != nil {
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(err).SetMeta("CloseThreadController.Status")
		return
	}

	// toggle status
	err = m.Toggle()
	if err != nil {
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(err).SetMeta("CloseThreadController.Toggle")
		return
	}

	// Delete redis stuff
	indexKey := fmt.Sprintf("%s:%d", "index", m.Ib)
	directoryKey := fmt.Sprintf("%s:%d", "directory", m.Ib)
	threadKey := fmt.Sprintf("%s:%d:%d", "thread", m.Ib, m.ID)

	err = redis.Cache.Delete(indexKey, directoryKey, threadKey)
	if err != nil {
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(err).SetMeta("CloseThreadController.redis.Cache.Delete")
		return
	}

	var successMessage string

	// change response message depending on bool state
	if m.Closed {
		successMessage = audit.AuditOpenThread
	} else {
		successMessage = audit.AuditCloseThread
	}

	// response message
	c.JSON(http.StatusOK, gin.H{"success_message": successMessage})

	// audit log
	audit := audit.Audit{
		User:   userdata.ID,
		Ib:     m.Ib,
		Type:   audit.ModLog,
		IP:     c.ClientIP(),
		Action: successMessage,
		Info:   fmt.Sprintf("%s", m.Name),
	}

	// submit audit
	err = audit.Submit()
	if err != nil {
		c.Error(err).SetMeta("CloseThreadController.audit.Submit")
	}

	return

}
Beispiel #8
0
// DeleteTagController will delete a tag
func DeleteTagController(c *gin.Context) {

	// Get parameters from validate middleware
	params := c.MustGet("params").([]uint)

	// get userdata from user middleware
	userdata := c.MustGet("userdata").(user.User)

	if !c.MustGet("protected").(bool) {
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(e.ErrInternalError).SetMeta("DeleteTagController.protected")
		return
	}

	// Initialize model struct
	m := &models.DeleteTagModel{
		Ib: params[0],
		ID: params[1],
	}

	// Check the record id and get further info
	err := m.Status()
	if err == e.ErrNotFound {
		c.JSON(e.ErrorMessage(e.ErrNotFound))
		c.Error(err).SetMeta("DeleteTagController.Status")
		return
	} else if err != nil {
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(err).SetMeta("DeleteTagController.Status")
		return
	}

	// Delete data
	err = m.Delete()
	if err != nil {
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(err).SetMeta("DeleteTagController.Delete")
		return
	}

	// Delete redis stuff
	tagsKey := fmt.Sprintf("%s:%d", "tags", m.Ib)
	tagKey := fmt.Sprintf("%s:%d:%d", "tag", m.Ib, m.ID)
	imageKey := fmt.Sprintf("%s:%d", "image", m.Ib)

	err = redis.Cache.Delete(tagsKey, tagKey, imageKey)
	if err != nil {
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(err).SetMeta("DeleteTagController.redis.Cache.Delete")
		return
	}

	// response message
	c.JSON(http.StatusOK, gin.H{"success_message": audit.AuditDeleteTag})

	// audit log
	audit := audit.Audit{
		User:   userdata.ID,
		Ib:     m.Ib,
		Type:   audit.ModLog,
		IP:     c.ClientIP(),
		Action: audit.AuditDeleteTag,
		Info:   fmt.Sprintf("%s", m.Name),
	}

	// submit audit
	err = audit.Submit()
	if err != nil {
		c.Error(err).SetMeta("DeleteTagController.audit.Submit")
	}

	return

}
Beispiel #9
0
// ResetPasswordController will reset an ip
func ResetPasswordController(c *gin.Context) {
	var err error
	var rpf resetPasswordForm

	// Get parameters from validate middleware
	params := c.MustGet("params").([]uint)

	// get userdata from user middleware
	userdata := c.MustGet("userdata").(user.User)

	if !c.MustGet("protected").(bool) {
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(e.ErrInternalError).SetMeta("ResetPasswordController.protected")
		return
	}

	err = c.Bind(&rpf)
	if err != nil {
		c.JSON(e.ErrorMessage(e.ErrInvalidParam))
		c.Error(err).SetMeta("ResetPasswordController.Bind")
		return
	}

	// generate a random password
	password, hash, err := user.RandomPassword()
	if err != nil {
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(err).SetMeta("ResetPasswordController.RandomPassword")
		return
	}

	// update the password in the database
	err = user.UpdatePassword(hash, rpf.UID)
	if err != nil {
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(err).SetMeta("ResetPasswordController.UpdatePassword")
		return
	}

	// response message
	c.JSON(http.StatusOK, gin.H{"success_message": audit.AuditResetPassword, "password": password})

	// audit log
	audit := audit.Audit{
		User:   userdata.ID,
		Ib:     params[0],
		Type:   audit.UserLog,
		IP:     c.ClientIP(),
		Action: audit.AuditResetPassword,
		Info:   fmt.Sprintf("%d", rpf.UID),
	}

	// submit audit
	err = audit.Submit()
	if err != nil {
		c.Error(err).SetMeta("ResetPasswordController.audit.Submit")
	}

	return

}
Beispiel #10
0
// BanIPController will ban an ip
func BanIPController(c *gin.Context) {
	var err error
	var bif banIPForm

	// Get parameters from validate middleware
	params := c.MustGet("params").([]uint)

	// get userdata from user middleware
	userdata := c.MustGet("userdata").(user.User)

	if !c.MustGet("protected").(bool) {
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(e.ErrInternalError).SetMeta("BanIpController.protected")
		return
	}

	err = c.Bind(&bif)
	if err != nil {
		c.JSON(e.ErrorMessage(e.ErrInvalidParam))
		c.Error(err).SetMeta("BanIpController.Bind")
		return
	}

	// Initialize model struct
	m := &models.BanIPModel{
		Ib:     params[0],
		Thread: params[1],
		ID:     params[2],
		User:   userdata.ID,
		Reason: bif.Reason,
	}

	// Check the record id and get further info
	err = m.Status()
	if err == e.ErrNotFound {
		c.JSON(e.ErrorMessage(e.ErrNotFound))
		c.Error(err).SetMeta("BanIpController.Status")
		return
	} else if err != nil {
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(err).SetMeta("BanIpController.Status")
		return
	}

	// add ban to database
	err = m.Post()
	if err != nil {
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(err).SetMeta("BanIpController.Post")
		return
	}

	// ban the ip in cloudflare
	go u.CloudFlareBanIP(m.IP, m.Reason)

	// response message
	c.JSON(http.StatusOK, gin.H{"success_message": audit.AuditBanIP})

	// audit log
	audit := audit.Audit{
		User:   userdata.ID,
		Ib:     m.Ib,
		Type:   audit.ModLog,
		IP:     c.ClientIP(),
		Action: audit.AuditBanIP,
		Info:   fmt.Sprintf("%s", m.Reason),
	}

	// submit audit
	err = audit.Submit()
	if err != nil {
		c.Error(err).SetMeta("BanIpController.audit.Submit")
	}

	return

}
Beispiel #11
0
// UpdateTagController will update a tags properties
func UpdateTagController(c *gin.Context) {
	var err error
	var utf updateTagForm

	// Get parameters from validate middleware
	params := c.MustGet("params").([]uint)

	// get userdata from user middleware
	userdata := c.MustGet("userdata").(user.User)

	if !c.MustGet("protected").(bool) {
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(e.ErrInternalError).SetMeta("UpdateTagController.protected")
		return
	}

	err = c.Bind(&utf)
	if err != nil {
		c.JSON(e.ErrorMessage(e.ErrInvalidParam))
		c.Error(err).SetMeta("UpdateTagController.Bind")
		return
	}

	// Set parameters to UpdateTagModel
	m := models.UpdateTagModel{
		Ib:      params[0],
		ID:      utf.ID,
		Tag:     utf.Tag,
		TagType: utf.Type,
	}

	// Validate input parameters
	err = m.ValidateInput()
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error_message": err.Error()})
		c.Error(err).SetMeta("UpdateTagController.ValidateInput")
		return
	}

	// Check tag for duplicate
	err = m.Status()
	if err == e.ErrDuplicateTag {
		c.JSON(http.StatusBadRequest, gin.H{"error_message": err.Error()})
		c.Error(err).SetMeta("UpdateTagController.Status")
		return
	} else if err != nil {
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(err).SetMeta("UpdateTagController.Status")
		return
	}

	// Update data
	err = m.Update()
	if err != nil {
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(err).SetMeta("UpdateTagController.Update")
		return
	}

	// Delete redis stuff
	tagsKey := fmt.Sprintf("%s:%d", "tags", m.Ib)
	tagKey := fmt.Sprintf("%s:%d:%d", "tag", m.Ib, m.ID)
	imageKey := fmt.Sprintf("%s:%d", "image", m.Ib)

	err = redis.Cache.Delete(tagsKey, tagKey, imageKey)
	if err != nil {
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(err).SetMeta("UpdateTagController.redis.Cache.Delete")
		return
	}

	// response message
	c.JSON(http.StatusOK, gin.H{"success_message": audit.AuditUpdateTag})

	// audit log
	audit := audit.Audit{
		User:   userdata.ID,
		Ib:     m.Ib,
		Type:   audit.ModLog,
		IP:     c.ClientIP(),
		Action: audit.AuditUpdateTag,
		Info:   fmt.Sprintf("%s", m.Tag),
	}

	// submit audit
	err = audit.Submit()
	if err != nil {
		c.Error(err).SetMeta("UpdateTagController.audit.Submit")
	}

	return

}