// It is handler for POST /organizations/{globalid}/members func (api OrganizationsAPI) globalidownersPost(w http.ResponseWriter, r *http.Request) { globalid := mux.Vars(r)["globalid"] var m member if err := json.NewDecoder(r.Body).Decode(&m); err != nil { http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } orgMgr := NewManager(r) org, err := orgMgr.GetByName(globalid) if err != nil { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } // Check if user exists userMgr := user.NewManager(r) if ok, err := userMgr.Exists(m.Username); err != nil || !ok { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } for _, membername := range org.Owners { if membername == m.Username { http.Error(w, http.StatusText(http.StatusConflict), http.StatusConflict) return } } // Create JoinRequest invitationMgr := invitations.NewInvitationManager(r) orgReq := &invitations.JoinOrganizationInvitation{ Role: invitations.RoleOwner, Organization: globalid, User: m.Username, Status: invitations.RequestPending, } if err := invitationMgr.Save(orgReq); err != nil { log.Error("Error inviting owner: ", err.Error()) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(orgReq) }
//ProcessLoginForm logs a user in if the credentials are valid func (service *Service) ProcessLoginForm(w http.ResponseWriter, request *http.Request) { //TODO: validate csrf token //TODO: limit the number of failed/concurrent requests log.Debug(request.RequestURI) err := request.ParseForm() if err != nil { log.Debug("ERROR parsing registration form") http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } values := request.Form username := values.Get("login") //validate the username exists var userexists bool userMgr := user.NewManager(request) if userexists, err = userMgr.Exists(username); err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } var validpassword bool passwdMgr := password.NewManager(request) if validpassword, err = passwdMgr.Validate(username, values.Get("password")); err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } var validtotpcode bool totpMgr := totp.NewManager(request) if validtotpcode, err = totpMgr.Validate(username, values.Get("totpcode")); err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } validcredentials := userexists && validpassword && validtotpcode if !validcredentials { service.renderLoginForm(w, request, true, request.RequestURI) return } if err := service.SetLoggedInUser(w, request, username); err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } sessions.Save(request, w) log.Debugf("Successfull login by '%s'", username) redirectURL := "" queryValues := request.URL.Query() endpoint := queryValues.Get("endpoint") if endpoint != "" { queryValues.Del("endpoint") redirectURL = endpoint + "?" + queryValues.Encode() } http.Redirect(w, request, redirectURL, http.StatusFound) }
//ProcessRegistrationForm processes the user registration form func (service *Service) ProcessRegistrationForm(w http.ResponseWriter, request *http.Request) { err := request.ParseForm() if err != nil { log.Debug("ERROR parsing registration form:", err) http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } validationErrors := make([]string, 0, 0) values := request.Form totpsession, err := service.GetSession(request, SessionForRegistration, "totp") if err != nil { log.Error("EROR while getting the totp registration session", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } if totpsession.IsNew { //TODO: indicate expired registration session log.Debug("New registration session while processing the registration form") service.ShowRegistrationForm(w, request) return } totpsecret, ok := totpsession.Values["secret"].(string) if !ok { log.Error("Unable to convert the stored session totp secret to a string") http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } newuser := &user.User{ Username: values.Get("login"), Email: map[string]string{"registration": values.Get("email")}, } //TODO: validate newuser //validate the username is not taken yet userMgr := user.NewManager(request) //TODO: distributed lock userExists, err := userMgr.Exists(newuser.Username) if err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } if userExists { validationErrors = append(validationErrors, "duplicateusername") log.Debug("USER ", newuser.Username, " already registered") service.renderRegistrationFrom(w, request, validationErrors, totpsecret) return } totpcode := values.Get("totpcode") token := totp.TokenFromSecret(totpsecret) if !token.Validate(totpcode) { log.Debug("Invalid totp code") validationErrors = append(validationErrors, "invalidtotpcode") service.renderRegistrationFrom(w, request, validationErrors, totpsecret) return } userMgr.Save(newuser) passwdMgr := password.NewManager(request) passwdMgr.Save(newuser.Username, values.Get("password")) totpMgr := totp.NewManager(request) totpMgr.Save(newuser.Username, totpsecret) log.Debugf("Registered %s", newuser.Username) service.SetLoggedInUser(w, request, newuser.Username) sessions.Save(request, w) http.Redirect(w, request, "/", http.StatusFound) }