198 lines
4.3 KiB
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)
|
|
}
|