//A handler that filters all requests that have not been authenticated //returns 401 Unauthorized if the user's session hasn't been marked as authenticated func Protect(handler perfect.RequestHandler) perfect.RequestHandler { return func(w http.ResponseWriter, r *perfect.Request) { //get the session session, err := r.Session() if err != nil { perfect.Error(w, r, err) return } //if the session hasn't been authorized, redirect if !*session.Authenticated { redirect_path := LOGIN_PATH w.Header().Set("X-Session-Expired", "1") //forward query params if len(r.URL.RawQuery) > 0 { redirect_path += "?" + r.URL.RawQuery } perfect.Redirect(w, r, redirect_path) return } else { //extend the amount of time the session is valid session.ExtendCookie(w, r) } //must be authenticated at this point handler(w, r) } }
//Logs out a user. //returns 204 No Content on success //returns 500 Internal Server Error on failure func logout(w http.ResponseWriter, r *perfect.Request) { session, err := r.Session() if err != nil { perfect.Error(w, r, err) return } if !*session.Authenticated { perfect.NoContent(w) return } err = r.Module.Db.Remove(session) if err != nil && err != orm.ErrNotFound { perfect.Error(w, r, err) return } session.RemoveCookie(w, r) //return 204 No Content on success perfect.Redirect(w, r, "/") //note that the user has logged out go r.Module.Log.Printf("logout") }
func Login(w http.ResponseWriter, r *perfect.Request) { var ( profile_id *string err error ) //get the session session, err := r.Session() if err != nil { perfect.Error(w, r, err) return } //if the user is already authenticated, redirect to home if *session.Authenticated { perfect.Redirect(w, r, "/") return } //TODO: make this work! (and delete the hard-coded built-in strategy!) //user, err := r.Module.Auth.Login(w, r); bauth := NewBuiltinStrategy(&Config{Type: BUILTIN}) profile_id, err = bauth.Login(w, r) if err != nil { log.Println("login error:", err) perfect.JSONResult(w, r, false, err.Error()) return } //mark the session as authenticated session.Authenticated = orm.Bool(true) //regenerate the session Id session.Id = orm.String(r.Module.Db.UniqueId()) //set the current user profile id session.ProfileId = profile_id // update the session err = r.Module.Db.Save(session) if err != nil { perfect.Error(w, r, err) return } session.SetCookie(w, r) //success perfect.JSONResult(w, r, true, r.Module.MountPoint+"/") }
func (b *BuiltinStrategy) Register(w http.ResponseWriter, r *perfect.Request) { //get the session session, err := r.Session() if err != nil { perfect.Error(w, r, err) return } //if the user is already authenticated, redirect to home if *session.Authenticated { perfect.Redirect(w, r, "/") return } data := make(map[string]string) err = r.ParseJSON(&data) if err != nil { perfect.Error(w, r, err) return } username, ok1 := data["username"] password, ok2 := data["password"] name, ok3 := data["name"] email, ok4 := data["email"] //TODO: this needs to be refactored into something better if !ok1 || !ok2 || !ok3 || !ok4 || len(username) == 0 || len(password) == 0 || len(name) == 0 || len(email) == 0 { perfect.JSONResult(w, r, false, "Please complete all fields") return } _, _, err = createBuiltinProfile(username, password, email, name, r.Module.Db) if err != nil { perfect.JSONResult(w, r, true, r.Module.MountPoint+"/") return } perfect.JSONResult(w, r, false, err) }