Esempio n. 1
0
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
		}
	})
}
Esempio n. 2
0
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
}