func (web *Web) authenticated(f func(*context) error) http.HandlerFunc { return web.log(func(w http.ResponseWriter, r *http.Request) { if r.TLS == nil { newURL := r.URL newURL.Scheme = "https" http.Redirect(w, r, newURL.String(), 301) return } username, passwd, ok := r.BasicAuth() if !ok { w.Header().Set("WWW-Authenticate", fmt.Sprintf("Basic realm=%q", realm)) http.Error(w, "Unauthenticated", 401) return } users := []user.User{} if err := web.persister.Find(persist.NewF(user.User{ Username: username, }).Add("Username"), &users); err != nil { http.Error(w, err.Error(), 500) return } if len(users) == 0 { http.Error(w, "Unauthenticated", 401) return } var user *user.User for _, found := range users { if hmac.Equal([]byte(found.Password), []byte(passwd)) { user = &found break } } if user == nil { http.Error(w, "Unauthenticated", 401) return } if err := f(&context{ user: user, req: r, resp: w, vars: mux.Vars(r), }); err != nil { if werr, ok := err.(webErr); ok { http.Error(w, werr.body, werr.status) } else { http.Error(w, err.Error(), 500) } return } }) }
func (l *Lobby) HandleClientInput(s string) error { switch l.state { case createUser: switch strings.ToLower(s) { case "y": codeBuf := &bytes.Buffer{} if err := initialHandlerTmpl.Execute(codeBuf, l.user); err != nil { return err } if err := l.persister.Transact(func(p *persist.Persister) error { if err := p.Put(l.user.Username, l.user); err != nil { return err } now := time.Now() r := &resource.Resource{ Id: l.user.Resource, Owner: l.user.Resource, Code: codeBuf.String(), UpdatedAt: now, CreatedAt: now, } if err := p.Put(r.Id, r); err != nil { return err } return nil }); err != nil { return err } return l.client.Authorize(l.user) case "n": l.state = welcome return l.client.Send(` Usage: login USERNAME PASSWORD `) } return l.client.Send(` (y/n) `) case welcome: if match := loginReg.FindStringSubmatch(s); match == nil { return l.client.Send(` Usage: login USERNAME PASSWORD `) } else { users := []user.User{} if err := l.persister.Find(persist.NewF(user.User{ Username: match[1], }).Add("Username"), &users); err != nil { return err } if len(users) == 0 { l.state = createUser l.user = &user.User{ Username: match[1], Password: match[2], Resource: fmt.Sprintf("%x%x", rand.Int63(), rand.Int63()), Container: messages.VoidResource, } return l.client.Send(` User not found, create? (y/n) `) } for index := range users { if hmac.Equal([]byte(match[2]), []byte(users[index].Password)) { return l.client.Authorize(&users[index]) } } return l.client.Send(` Incorrect password. `) } } return nil }