func (a *API) logout(w http.ResponseWriter, r *http.Request) { session, _ := a.store.Get(r, a.storeKey) username := session.Values["username"].(string) if username == "" { http.Error(w, "unauthorized", http.StatusInternalServerError) return } m, err := accounts.New(a.dbName, a.session) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if err := m.ClearAuthTokens(username, r.UserAgent()); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } }
func (a *API) Run() error { globalMux := http.NewServeMux() memberManager, err := accounts.New(a.dbName, a.session) if err != nil { return err } // api router; public read; auth-required write authRequired := mAuth.NewAuthRequired(memberManager, a.store, a.storeKey) apiRouter := mux.NewRouter() apiRouter.HandleFunc("/api/accounts", a.getAccounts).Methods("GET") globalMux.Handle("/api/", apiRouter) // login router; public loginRouter := mux.NewRouter() loginRouter.HandleFunc("/auth/login", a.login).Methods("POST") globalMux.Handle("/auth/", loginRouter) // member router; auth required accountRouter := mux.NewRouter() accountRouter.Handle("/accounts/changepassword", authRequired.Handler(http.HandlerFunc(a.changePassword))).Methods("POST") accountRouter.Handle("/accounts/logout", authRequired.Handler(http.HandlerFunc(a.logout))).Methods("GET") globalMux.Handle("/accounts/", accountRouter) // static handler globalMux.Handle("/", http.FileServer(http.Dir(a.publicDir))) s := &http.Server{ Addr: a.listenAddr, Handler: context.ClearHandler(globalMux), } log.Infof("api serving: addr=%s", a.listenAddr) return s.ListenAndServe() }
func (a *API) login(w http.ResponseWriter, r *http.Request) { var creds *Credentials if err := json.NewDecoder(r.Body).Decode(&creds); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } m, err := accounts.New(a.dbName, a.session) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } loginSuccessful, err := m.Authenticate(creds.Username, creds.Password) if err != nil { log.Errorf("error during login for %s from %s: %s", creds.Username, r.RemoteAddr, err) http.Error(w, err.Error(), http.StatusInternalServerError) return } if !loginSuccessful { log.Warnf("invalid login for %s from %s", creds.Username, r.RemoteAddr) http.Error(w, "invalid username/password", http.StatusForbidden) return } // return token token, err := m.NewAuthToken(creds.Username, r.UserAgent()) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if err := json.NewEncoder(w).Encode(token); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } }
func (a *API) changePassword(w http.ResponseWriter, r *http.Request) { session, _ := a.store.Get(r, a.storeKey) var creds *Credentials if err := json.NewDecoder(r.Body).Decode(&creds); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } username := session.Values["username"].(string) if username == "" { http.Error(w, "unauthorized", http.StatusInternalServerError) return } m, err := accounts.New(a.dbName, a.session) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if err := m.ChangePassword(username, creds.Password); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } }