oauth2/oauth2server/server/users.go

94 lines
2.2 KiB
Go

package server
import (
"crypto/hmac"
"crypto/md5"
"crypto/sha256"
"encoding/hex"
"fmt"
"local/oauth2/oauth2server/config"
"local/router"
"net/http"
"github.com/google/uuid"
)
func (s *Server) usersLog(w http.ResponseWriter, r *http.Request) {
scope := ""
router.Params(r, &scope)
s.limiter.Wait(r.Context())
q := r.URL.Query()
fmt.Fprintln(w, `
<html>
<body>
<form method="post" action="/authorize/`+scope+`?`+q.Encode()+`">
<input type="password" name="username"></input>
<input type="submit"></input>
</form>
</body>
</html>
`)
}
func (s *Server) usersRegister(w http.ResponseWriter, r *http.Request) {
scope := ""
router.Params(r, &scope)
s.limiter.Wait(r.Context())
fmt.Fprintln(w, `
<html>
<body>
<form method="post" action="/users/submit/`+scope+`">
<input type="text" name="username"></input>
<input type="submit"></input>
</form>
</body>
</html>
`)
}
func (s *Server) usersSubmit(w http.ResponseWriter, r *http.Request) {
scope := ""
router.Params(r, &scope)
s.limiter.Wait(r.Context())
if r.Method != "POST" {
http.NotFound(w, r)
return
}
id := scope + "." + r.FormValue("username")
if _, ok := s.getUser(id); ok {
http.Error(w, "user already exists", http.StatusConflict)
return
}
s.genUser(id)
}
func (s *Server) genUser(id string) {
user := uuid.New().String()
salt := uuid.New().String()
s.store.Set(id, []byte(salt), SALT)
obscured := s.obscureID(id)
s.store.Set(obscured, []byte(user), USERS)
}
func (s *Server) getUser(id string) (string, bool) {
obscured := s.obscureID(id)
user, err := s.store.Get(obscured, USERS)
return string(user), err == nil
}
func (s *Server) obscureID(id string) string {
salt, _ := s.store.Get(id, SALT)
a := s.obscure(string(salt)+id, config.SecretA)
b := s.obscure(string(salt)+id, config.SecretB)
return a + b
}
func (s *Server) obscure(payload, secret string) string {
hash := md5.New()
hash.Write([]byte(secret))
key := hash.Sum(nil)
sig := hmac.New(sha256.New, key)
sig.Write([]byte(payload))
return hex.EncodeToString(sig.Sum(nil))
}