func AuthInterceptor(c *revel.Controller) revel.Result { // 全部变成首字大写 /* var controller = strings.Title(c.Name) var method = strings.Title(c.MethodName) // 是否需要验证? if !needValidate(controller, method) { return nil } */ // 验证是否已登录 // 必须是管理员 if username, ok := c.Session["Username"]; ok && username == configService.GetAdminUsername() { return nil // 已登录 } // 没有登录, 判断是否是ajax操作 if c.Request.Header.Get("X-Requested-With") == "XMLHttpRequest" { re := info.NewRe() re.Msg = "NOTLOGIN" return c.RenderJson(re) } return c.Redirect("/login") }
func MSessionFilter(c *revel.Controller, fc []revel.Filter) { sessionId := c.Session.Id() // 从memcache中得到cache, 赋给session cache := revel.Session(memcache.GetMap(sessionId)) Log("memcache") LogJ(cache) if cache == nil { cache = revel.Session{} cache.Id() } c.Session = cache // Make session vars available in templates as {{.session.xyz}} c.RenderArgs["session"] = c.Session fc[0](c, fc[1:]) // 再把session保存之 LogJ(c.Session) memcache.SetMap(sessionId, c.Session, -1) // 只留下sessionId c.Session = revel.Session{revel.SESSION_ID_KEY: sessionId} }
/* 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 }
func CheckUserAuth(controller *revel.Controller) revel.Result { if controller.Action == "Static.Serve" || controller.Action == "App.Login" || controller.Action == "User.Login" || controller.Action == "User.Logout" { return nil } var ( userAuth = new(security.UserAuth) username string sessionData = *security.GetSessionData(&controller.Session) ) security.AuthCache.Get(controller.Session.Id(), userAuth) if v, ok := sessionData["username"]; ok { username = v.(string) } if userAuth != nil && username != "" && userAuth.Equal(security.UserAuthGenerate(controller.Request)) { return nil } controller.Flash.Error("Please log in first") controller.Response.Out.Header().Set("Requires-Auth", "1") // controller.Response.Status = 401 return controller.Redirect((*User).Login) }
func adminOnly(c *revel.Controller) revel.Result { if c.Session["usertype"] == "ADMIN" { return nil } c.Flash.Error(c.Message("access.message.notallowed")) return c.Redirect(routes.App.Index()) }
func checkUser(c *revel.Controller) revel.Result { if _, ok := c.Session["user"]; ok { return nil } c.Flash.Error(c.Message("login.message.notloggedin")) return c.Redirect(routes.App.Login()) }
func CheckLoginAdmin(c *revel.Controller) revel.Result { if c.Session[LOGIN_USERID] == "" || models.Role(c.Session[LOGIN_USERROLE]) != models.ROLE_SUPER_ADMIN { return c.Redirect( revel.MainRouter.Reverse("Auth.Login", map[string]string{}).Url, ) } return nil }
// func init() { // revel.InterceptFunc(CheckLogin, revel.BEFORE, &App{}) // } func CheckLogin(c *revel.Controller) revel.Result { if c.Session[LOGIN_USERID] == "" { return c.Redirect( revel.MainRouter.Reverse("Auth.Login", map[string]string{}).Url, ) } return nil }
// search certain content func Search(key string, c *revel.Controller) revel.Result { var problems []models.Problem err := engine.Where("title = ? ", key).Find(&problems) if err != nil { c.Flash.Error("error %s", err.Error()) c.Redirect(routes.Notice.Crash()) } return c.Render(problems) }
func redirectAuthenticationPageForAdmin(c *revel.Controller) revel.Result { uidStr := c.Session["uid"] uid, _ := strconv.Atoi(uidStr) errorPage := c.RenderTemplate("errors/401.html") if len(uidStr) == 0 { return errorPage } if (models.User{}.FetchUserByUserId(uint(uid)).Status != models.UserAdmin) { return errorPage } return nil }
func checkDataTypeParam(c *revel.Controller) revel.Result { dataType, ok := c.Params.Values["dataType"] if ok && dataType[0] != "" { if _, ok := database.SynchronizationTypes[dataType[0]]; !ok { c.Response.Status = 400 return c.RenderJson("wrong dataType attribute") } return nil } c.Response.Status = 400 return c.RenderJson("mandatory parameter dataType is not present") }
func returnMessage(c *revel.Controller, message interface{}, err error) revel.Result { result := &opResult{} if err != nil { result.Result = Error result.Message = err.Error() revel.WARN.Fatalln(err) } else { result.Result = Success result.Message = message } return c.RenderJson(result) }
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} }
//authentication check func authenticate(c *revel.Controller) revel.Result { if inStringSlice(strings.ToLower(c.Action), adminPermission) { if !adminAuthentication(c) { c.Flash.Error("you are not admin") return c.Redirect("/") } } if inStringSlice(strings.ToLower(c.Action), userPermission) { if ok := connected(c); !ok { c.Flash.Error("please login first") return c.Redirect(routes.Account.Login()) } else { return nil } } if inStringSlice(strings.ToLower(c.Action), logoutCheck) { if ok := connected(c); ok { c.Flash.Error("can not repeat login") return c.Redirect("/") } else { return nil } } return nil }
// 这里得到token, 若不是login, logout等公用操作, 必须验证是否已登录 func AuthInterceptor(c *revel.Controller) revel.Result { // 得到token /api/user/info?userId=xxx&token=xxxxx token := c.Params.Values.Get("token") noToken := false if token == "" { // 若无, 则取sessionId token = c.Session.Id() noToken = true } c.Session["_token"] = token // 全部变成首字大写 var controller = strings.Title(c.Name) var method = strings.Title(c.MethodName) // 验证是否已登录 // 通过sessionService判断该token下是否有userId, 并返回userId userId := sessionService.GetUserId(token) if noToken && userId == "" { // 从session中获取, api/file/getImage, api/file/getAttach, api/file/getAllAttach // 客户端 userId, _ = c.Session["UserId"] } c.Session["_userId"] = userId // 是否需要验证? if !needValidate(controller, method) { return nil } if userId != "" { return nil // 已登录 } // 没有登录, 返回错误的信息, 需要登录 re := info.NewApiRe() re.Msg = "NOTLOGIN" return c.RenderJson(re) }
//检测登陆 func CheckLogin(c *revel.Controller) revel.Result { //登陆页面,CSS, JS, Ajax, 验证码页面 都不进行登陆验证 if c.Name == "User" && c.MethodName == "Login" || c.Name == "Ajax" || c.Name == "Static" || c.Name == "Captcha" || c.Name == "Kindeditor" { if LANG, ok := c.Session["Lang"]; ok { //设置语言 c.RenderArgs["currentLocale"] = LANG } else { //设置默认语言 c.RenderArgs["currentLocale"] = "zh" } return nil } else { UserID := utils.GetSession("UserID", c.Session) if len(UserID) > 0 { UserID, err := strconv.ParseInt(UserID, 10, 64) if err != nil { revel.WARN.Println(err) return c.Redirect("/Login/") } admin := new(models.Admin) admin_info := admin.GetById(UserID) if admin_info.Id <= 0 { return c.Redirect("/Login/") } //控制器 c.RenderArgs["Controller"] = c.Name //动作 c.RenderArgs["action"] = c.Action //模型 c.RenderArgs["Model"] = c.MethodName //登陆信息 c.RenderArgs["admin_info"] = admin_info //设置语言 c.RenderArgs["currentLocale"] = admin_info.Lang } else { //控制器 c.RenderArgs["Controller"] = c.Name //动作 c.RenderArgs["action"] = c.Action //模型 c.RenderArgs["Model"] = c.MethodName return c.Redirect("/Login/") } } return nil }
// SessionFilter is a Revel Filter that retrieves and sets the session cookie. // Within Revel, it is available as a Session attribute on Controller instances. // The name of the Session cookie is set as CookiePrefix + "_SESSION". func SessionFilter(c *revel.Controller, fc []revel.Filter) { session := restoreSession(c.Request.Request) // c.Session, 重新生成一个revel.Session给controller!!! // Log("sessoin--------") // LogJ(session) revelSession := revel.Session(session) // 强制转换 还是同一个对象, 但有个问题, 这样Session.Id()方法是用revel的了 c.Session = revelSession // 生成sessionId c.Session.Id() sessionWasEmpty := len(c.Session) == 0 // Make session vars available in templates as {{.session.xyz}} c.RenderArgs["session"] = c.Session fc[0](c, fc[1:]) // Store the signed session if it could have changed. if len(c.Session) > 0 || !sessionWasEmpty { // 转换成lea.Session session = Session(c.Session) c.SetCookie(session.cookie()) } }
func checkRole(this *revel.Controller) revel.Result { pv := models.PV{ IP: this.Request.Host, Page: this.Action, TimeStamp: time.Now().Format("2006-01-02 15:04:05")} addPV(pv) // 设置游客的访问权限 if this.Session["administrator"] == "" { if this.Action == "Admin.SignIn" || this.Action == "Picture.Show" || this.Action == "Picture.Search" || this.Action == "Picture.AddComment" || this.Action == "Picture.UploadForCheck" || this.Action == "Picture.PostUploadForCheck" || this.Action == "Picture.UniversityPictureNums" { return nil } else { this.Flash.Success("需要管理员身份才能访问该页面。") log.Println("游客访问了 " + this.Action + " 页面,已自动跳转到首页") return this.Redirect(controllers.App.Index) } } // 设置管理员的访问权限 if this.Session["administrator"] == "true" { if this.Action == "Admin.SignIn" { this.Flash.Success("您已经登录,请先注销再登录。") log.Println("管理员访问了登录页面,已自动跳转到首页") return this.Redirect(controllers.App.Index) } else { log.Println("管理员 " + this.Session["administrator"] + " 访问了 " + this.Action + " 页面") return nil } } return this.Redirect(controllers.Admin.SignIn) }
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:]) }
func GetGridJson(c *revel.Controller, count int, data interface{}) revel.Result { json := &GridJson{count, data} return c.RenderJson(json) }
func FilterForApiDoc(c *revel.Controller, fc []revel.Filter) { if record, _ := revel.Config.Bool("yaag.record"); !record { fc[0](c, fc[1:]) return } w := httptest.NewRecorder() c.Response = revel.NewResponse(w) httpVerb := c.Request.Method customParams := make(map[string]interface{}) headers := make(map[string]string) hasJson := false hasXml := false body := middleware.ReadBody(c.Request.Request) if c.Request.ContentType == "application/json" { if httpVerb == "POST" || httpVerb == "PUT" || httpVerb == "PATCH" { err := json.Unmarshal([]byte(*body), &customParams) if err != nil { log.Println("Json Error ! ", err) } else { hasJson = true } } else { err := json.Unmarshal([]byte(c.Request.URL.RawQuery), &customParams) if err != nil { log.Println("Json Error ! ", err) } else { hasJson = true } } } else if c.Request.ContentType == "application/xml" { if httpVerb == "POST" || httpVerb == "PUT" || httpVerb == "PATCH" { err := xml.Unmarshal([]byte(*body), &customParams) if err != nil { log.Println("Xml Error ! ", err) } else { hasXml = true } } else { err := xml.Unmarshal([]byte(c.Request.URL.RawQuery), &customParams) if err != nil { log.Println("Json Error ! ", err) } else { hasXml = true } } } log.Println(hasJson, hasXml) // call remaiing filters fc[0](c, fc[1:]) c.Result.Apply(c.Request, c.Response) htmlValues := yaag.APICall{} htmlValues.CommonRequestHeaders = make(map[string]string) // get headers for k, v := range c.Request.Header { isCommon := false for _, hk := range yaag.CommonHeaders { if k == hk { isCommon = true htmlValues.CommonRequestHeaders[k] = strings.Join(v, " ") break } } if !isCommon { headers[k] = strings.Join(v, " ") } } htmlValues.MethodType = httpVerb htmlValues.CurrentPath = c.Request.URL.Path htmlValues.PostForm = make(map[string]string) for k, v := range c.Params.Form { htmlValues.PostForm[k] = strings.Join(v, " ") } htmlValues.RequestBody = *body htmlValues.RequestHeader = headers htmlValues.RequestUrlParams = make(map[string]string) for k, v := range c.Request.URL.Query() { htmlValues.RequestUrlParams[k] = strings.Join(v, " ") } htmlValues.ResponseHeader = make(map[string]string) htmlValues.ResponseBody = w.Body.String() for k, v := range w.Header() { htmlValues.ResponseHeader[k] = strings.Join(v, " ") } htmlValues.ResponseCode = w.Code yaag.ApiCallValueInstance.BaseLink = c.Request.Host go yaag.GenerateHtml(&htmlValues) }
// scss 样式 func ServeSCSS(uri string, c *revel.Controller) { filePath := GetFilePath(uri) data := findInCache(filePath, buildScss) c.Result = CommonResult{Data: data, ContentType: ContentTypeCSS} }
func ServeCoffee(uri string, c *revel.Controller) { filePath := GetFilePath(uri) data := findInCache(filePath, buildCoffee) c.Result = CommonResult{Data: data, ContentType: ContentTypeJS} }
// 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 } }