Einladungscodes: registration_mode open|invite|closed, Admin-API /api/invites, App mit Code-Feld und Code-Verwaltung; v0.3.2
This commit is contained in:
parent
d2658de099
commit
cf5e0b1ca7
38 changed files with 665 additions and 25 deletions
|
|
@ -215,8 +215,9 @@ func (s *Server) auth(h http.Handler) http.Handler {
|
|||
}
|
||||
|
||||
type credentials struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
InviteCode string `json:"invite_code,omitempty"`
|
||||
}
|
||||
|
||||
func validUsername(u string) bool {
|
||||
|
|
@ -247,7 +248,8 @@ func (s *Server) issue(w http.ResponseWriter, r *http.Request, u store.User, cod
|
|||
|
||||
func (s *Server) register(w http.ResponseWriter, r *http.Request) {
|
||||
s.initAuth()
|
||||
if !s.AllowRegistration {
|
||||
mode := s.regMode()
|
||||
if mode == "closed" {
|
||||
writeErr(w, http.StatusForbidden, "registration disabled")
|
||||
return
|
||||
}
|
||||
|
|
@ -269,13 +271,24 @@ func (s *Server) register(w http.ResponseWriter, r *http.Request) {
|
|||
writeErr(w, http.StatusBadRequest, "password must be 8-72 characters")
|
||||
return
|
||||
}
|
||||
code := ""
|
||||
if mode == "invite" {
|
||||
if code = store.NormalizeInviteCode(c.InviteCode); code == "" {
|
||||
writeErr(w, http.StatusBadRequest, "invite code required")
|
||||
return
|
||||
}
|
||||
}
|
||||
s.limiter.Fail(ip) // every registration counts against the IP budget
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(c.Password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
s.storeErr(w, err)
|
||||
return
|
||||
}
|
||||
u, err := s.Store.CreateUser(r.Context(), c.Username, string(hash))
|
||||
u, err := s.Store.CreateUserWithInvite(r.Context(), c.Username, string(hash), code)
|
||||
if errors.Is(err, store.ErrInviteInvalid) || errors.Is(err, store.ErrInviteUsed) || errors.Is(err, store.ErrInviteExpired) {
|
||||
writeErr(w, http.StatusForbidden, err.Error())
|
||||
return
|
||||
}
|
||||
if errors.Is(err, store.ErrUserExists) {
|
||||
writeErr(w, http.StatusConflict, "username already taken")
|
||||
return
|
||||
|
|
@ -339,3 +352,15 @@ func (s *Server) owns(w http.ResponseWriter, r *http.Request, id string) bool {
|
|||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// regMode is the effective registration mode.
|
||||
func (s *Server) regMode() string {
|
||||
switch s.RegistrationMode {
|
||||
case "open", "invite", "closed":
|
||||
return s.RegistrationMode
|
||||
}
|
||||
if s.AllowRegistration {
|
||||
return "open"
|
||||
}
|
||||
return "closed"
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue