rproxy3/server/routes.go

198 lines
4.3 KiB
Go

package server
import (
"encoding/json"
"local/s2sa/s2sa/server/router"
"local/s2sa/s2sa/token"
"net/http"
"path"
"strings"
)
const clientsNS = "clients"
const accessorsNS = "accessors"
const wildcard = "{}"
const serverNS = "server"
func (s *Server) Routes() error {
appendWildcards := func(s string, cnt int) string {
s = strings.Trim(s, "/")
return path.Join(s, strings.Repeat("/"+wildcard, cnt))
}
paths := []struct {
base string
wildcards int
method http.HandlerFunc
}{
{
base: "admin/register",
wildcards: 1,
method: s.adminRegister,
},
{
base: "register",
wildcards: 1,
method: s.authenticate(s.registerClient),
},
{
base: "generate",
wildcards: 2,
method: s.authenticate(s.generateToken),
},
{
base: "retrieve",
wildcards: 3,
method: s.authenticate(s.retrieveToken),
},
{
base: "revoke",
wildcards: 2,
method: s.authenticate(s.revokeToken),
},
{
base: "lookup",
wildcards: 2,
method: s.authenticate(s.lookupToken),
},
{
base: "policies",
wildcards: 0,
method: s.authenticate(s.getPolicies),
},
}
for _, path := range paths {
if err := s.Add(appendWildcards(path.base, path.wildcards), path.method); err != nil {
return err
}
}
return nil
}
func (s *Server) authenticate(foo http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
recipient, accessorToken, ok := r.BasicAuth()
if !ok {
w.WriteHeader(http.StatusUnauthorized)
return
}
accessor := strings.Split(accessorToken, ":")[0]
tokenValue := strings.Split(accessorToken, ":")[1]
token, err := s.authdb.Get(recipient, accessor)
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
return
}
if token.Token != tokenValue {
w.WriteHeader(http.StatusUnauthorized)
return
}
if token.To != recipient {
w.WriteHeader(http.StatusUnauthorized)
return
}
foo(w, r)
}
}
func (s *Server) adminRegister(w http.ResponseWriter, r *http.Request) {
var name string
if err := router.Params(r, &name); err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
token, err := s.authdb.New(serverNS, name)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
respondWithToken(token, w, r)
}
func (s *Server) registerClient(w http.ResponseWriter, r *http.Request) {
var name string
if err := router.Params(r, &name); err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
if err := s.db.Register(name); err != nil {
w.WriteHeader(http.StatusInternalServerError)
}
}
func (s *Server) generateToken(w http.ResponseWriter, r *http.Request) {
var name, to string
if err := router.Params(r, &name, &to); err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
token, err := s.db.New(name, to)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
respondWithToken(token, w, r)
}
func (s *Server) retrieveToken(w http.ResponseWriter, r *http.Request) {
var creator, recipient, accessor string
if err := router.Params(r, &creator, &recipient, &accessor); err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
token, err := s.db.Get(recipient, accessor)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
respondWithToken(token, w, r)
}
func respondWithToken(token token.Basic, w http.ResponseWriter, r *http.Request) {
if err := json.NewEncoder(w).Encode(token); err != nil {
w.WriteHeader(http.StatusInternalServerError)
}
}
func (s *Server) revokeToken(w http.ResponseWriter, r *http.Request) {
var name, accessor string
if err := router.Params(r, &name, &accessor); err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
if err := s.db.Revoke(name, accessor); err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
}
func (s *Server) lookupToken(w http.ResponseWriter, r *http.Request) {
var creator, recipient string
if err := router.Params(r, &creator, &recipient); err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
token, err := s.db.Lookup(creator, recipient)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
respondWithToken(token, w, r)
}
func (s *Server) getPolicies(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
}