Example #1
0
// CsrfFilter enables CSRF request token creation and verification.
//
// Usage:
//  1) Add `csrf.CsrfFilter` to the app's filters (it must come after the revel.SessionFilter).
//  2) Add CSRF fields to a form with the template tag `{{ csrftoken . }}`. The filter adds a function closure to the `RenderArgs` that can pull out the secret and make the token as-needed, caching the value in the request. Ajax support provided through the `X-CSRFToken` header.
func CsrfFilter(c *revel.Controller, fc []revel.Filter) {
	token, foundToken := c.Session["csrf_token"]

	if !foundToken {
		RefreshToken(c)
	}

	referer, refErr := url.Parse(c.Request.Header.Get("Referer"))
	isSameOrigin := sameOrigin(c.Request.URL, referer)

	// If the Request method isn't in the white listed methods
	if !allowedMethods[c.Request.Method] && !IsExempt(c) {
		// Token wasn't present at all
		if !foundToken {
			c.Result = c.Forbidden("REVEL CSRF: Session token missing.")
			return
		}

		// Referer header is invalid
		if refErr != nil {
			c.Result = c.Forbidden("REVEL CSRF: HTTP Referer malformed.")
			return
		}

		// Same origin
		if !isSameOrigin {
			c.Result = c.Forbidden("REVEL CSRF: Same origin mismatch.")
			return
		}

		var requestToken string
		// First check for token in post data
		if c.Request.Method == "POST" {
			requestToken = c.Request.FormValue("csrftoken")
		}

		// Then check for token in custom headers, as with AJAX
		if requestToken == "" {
			requestToken = c.Request.Header.Get("X-CSRFToken")
		}

		if requestToken == "" || !compareToken(requestToken, token) {
			c.Result = c.Forbidden("REVEL CSRF: Invalid token.")
			return
		}
	}

	fc[0](c, fc[1:])

	// Only add token to RenderArgs if the request is: not AJAX, not missing referer header, and is same origin.
	if c.Request.Header.Get("X-CSRFToken") == "" && isSameOrigin {
		c.RenderArgs["_csrftoken"] = token
	}
}
Example #2
0
/*
Filter AuthFilter is Revel Filter for JWT Auth Token verification
Register it in the revel.Filters in <APP_PATH>/app/init.go

Add jwt.AuthFilter anywhere deemed appropriate, it must be register after revel.PanicFilter

	revel.Filters = []revel.Filter{
		revel.PanicFilter,
		...
		jwt.AuthFilter,		// JWT Auth Token verification for Request Paths
		...
	}

Note: If everything looks good then Claims map made available via c.Args
and can be accessed using c.Args[jwt.TOKEN_CLAIMS_KEY]
*/
func AuthFilter(c *revel.Controller, fc []revel.Filter) {
	if !anonymousPaths.MatchString(c.Request.URL.Path) {
		token, err := ParseFromRequest(c.Request.Request)
		if err == nil && token.Valid && !IsInBlocklist(GetAuthToken(c.Request)) {
			c.Args[TOKEN_CLAIMS_KEY] = token.Claims

			fc[0](c, fc[1:]) // everything looks good, move on
		} else {
			if ve, ok := err.(*jwt.ValidationError); ok {
				if ve.Errors&jwt.ValidationErrorMalformed != 0 {
					revel.ERROR.Println("That's not even a token")
				} else if ve.Errors&(jwt.ValidationErrorExpired|jwt.ValidationErrorNotValidYet) != 0 {
					revel.ERROR.Println("Timing is everything, Token is either expired or not active yet")
				} else {
					revel.ERROR.Printf("Couldn't handle this token: %v", err)
				}
			} else {
				revel.ERROR.Printf("Couldn't handle this token: %v", err)
			}

			c.Response.Status = http.StatusUnauthorized
			c.Response.Out.Header().Add("WWW-Authenticate", Realm)
			c.Result = c.RenderJson(map[string]string{
				"id":      "unauthorized",
				"message": "Invalid or token is not provided",
			})

			return
		}
	}

	fc[0](c, fc[1:]) //not applying JWT auth filter due to anonymous path
}
Example #3
0
func ServeStatic(uri, contentType string, c *revel.Controller) {
	filePath := GetFilePath(uri)
	revel.INFO.Printf("read static file %s\n", filePath)
	file, err := os.Open(filePath)
	defer file.Close()
	if err != nil {
		c.Result = CommonResult{Data: []byte(`sorry file not found`)}
		return
	}
	data, err := ioutil.ReadAll(file)
	if err != nil {
		c.Result = CommonResult{Data: []byte(`sorry file not found`)}
		return
	}
	c.Result = CommonResult{Data: data, ContentType: contentType}
}
Example #4
0
func RouterFilter(c *revel.Controller, fc []revel.Filter) {
	// 补全controller部分
	path := c.Request.Request.URL.Path

	// Figure out the Controller/Action
	var route *revel.RouteMatch = revel.MainRouter.Route(c.Request.Request)
	if route == nil {
		c.Result = c.NotFound("No matching route found: " + c.Request.RequestURI)
		return
	}

	// The route may want to explicitly return a 404.
	if route.Action == "404" {
		c.Result = c.NotFound("(intentionally)")
		return
	}

	//----------
	// life start
	/*
		type URL struct {
		    Scheme   string
		    Opaque   string    // encoded opaque data
		    User     *Userinfo // username and password information
		    Host     string    // host or host:port
		    Path     string
		    RawQuery string // encoded query values, without '?'
		    Fragment string // fragment for references, without '#'
		}
	*/
	if route.ControllerName != "Static" {
		// api设置
		// leanote.com/api/user/get => ApiUser::Get
		//*       /api/login               ApiAuth.Login,  这里的设置, 其实已经转成了ApiAuth了
		if strings.HasPrefix(path, "/api") && !strings.HasPrefix(route.ControllerName, "Api") {
			route.ControllerName = "Api" + route.ControllerName
		} else if strings.HasPrefix(path, "/member") && !strings.HasPrefix(route.ControllerName, "Member") {
			// member设置
			route.ControllerName = "Member" + route.ControllerName
		}
		// end
	}

	// Set the action.
	if err := c.SetAction(route.ControllerName, route.MethodName); err != nil {
		c.Result = c.NotFound(err.Error())
		return
	}

	// Add the route and fixed params to the Request Params.
	c.Params.Route = route.Params

	// Add the fixed parameters mapped by name.
	// TODO: Pre-calculate this mapping.
	for i, value := range route.FixedParams {
		if c.Params.Fixed == nil {
			c.Params.Fixed = make(url.Values)
		}
		if i < len(c.MethodType.Args) {
			arg := c.MethodType.Args[i]
			c.Params.Fixed.Set(arg.Name, value)
		} else {
			revel.WARN.Println("Too many parameters to", route.Action, "trying to add", value)
			break
		}
	}

	fc[0](c, fc[1:])
}
Example #5
0
// scss 样式
func ServeSCSS(uri string, c *revel.Controller) {
	filePath := GetFilePath(uri)
	data := findInCache(filePath, buildScss)
	c.Result = CommonResult{Data: data, ContentType: ContentTypeCSS}
}
Example #6
0
func ServeCoffee(uri string, c *revel.Controller) {
	filePath := GetFilePath(uri)
	data := findInCache(filePath, buildCoffee)
	c.Result = CommonResult{Data: data, ContentType: ContentTypeJS}
}