Skip to content
Snippets Groups Projects
Select Git revision
  • 7cff2e8d38a30274c7cfc352c3f1d6c70cf9ecd8
  • master default protected
  • renovate/golang.org-x-net-0.x
  • renovate/golang.org-x-crypto-0.x
  • renovate/git.autistici.org-ai3-go-common-digest
  • renovate/github.com-miekg-dns-1.x
  • renovate/github.com-prometheus-client_golang-1.x
  • v3
  • v2
9 results

span.go

  • server.go 2.64 KiB
    package server
    
    import (
    	"log"
    	"net/http"
    
    	"git.autistici.org/ai3/go-common/serverutil"
    
    	"git.autistici.org/id/keystore"
    )
    
    var emptyResponse struct{}
    
    type keyStoreServer struct {
    	*KeyStore
    }
    
    func (s *keyStoreServer) handleOpen(w http.ResponseWriter, r *http.Request) {
    	var req keystore.OpenRequest
    	if !serverutil.DecodeJSONRequest(w, r, &req) {
    		return
    	}
    
    	err := s.KeyStore.Open(r.Context(), req.Username, req.Password, req.SessionID, req.TTL)
    	if err == errNoKeys {
    		log.Printf("Open(%s): no encrypted keys found in database", req.Username)
    	} else if err != nil {
    		log.Printf("Open(%s): error: %v", req.Username, err)
    		http.Error(w, err.Error(), http.StatusInternalServerError)
    		requestsCounter.WithLabelValues("Open", "error").Inc()
    		return
    	} else {
    		log.Printf("Open(%s): decrypted key, ttl=%d", req.Username, req.TTL)
    		decryptedKeysCounter.Inc()
    	}
    
    	requestsCounter.WithLabelValues("Open", "ok").Inc()
    	serverutil.EncodeJSONResponse(w, &emptyResponse)
    }
    
    func (s *keyStoreServer) handleGet(w http.ResponseWriter, r *http.Request) {
    	var req keystore.GetRequest
    	if !serverutil.DecodeJSONRequest(w, r, &req) {
    		return
    	}
    
    	var resp keystore.GetResponse
    	key, err := s.KeyStore.Get(req.Username, req.SSOTicket)
    	if err == errNoKeys {
    		log.Printf("Get(%s): no unlocked keys found in memory", req.Username)
    	} else if err != nil {
    		// Return an appropriate error code.
    		switch err {
    		case errUnauthorized, errBadUser:
    			http.Error(w, err.Error(), http.StatusForbidden)
    		default:
    			log.Printf("Get(%s): error: %v", req.Username, err)
    			http.Error(w, err.Error(), http.StatusInternalServerError)
    		}
    		requestsCounter.WithLabelValues("Get", "error").Inc()
    		return
    	} else {
    		resp.HasKey = true
    		resp.Key = key
    		log.Printf("Get(%s): fetched key", req.Username)
    		unlockedKeysServedCounter.Inc()
    	}
    
    	requestsCounter.WithLabelValues("Get", "ok").Inc()
    	serverutil.EncodeJSONResponse(w, &resp)
    }
    
    func (s *keyStoreServer) handleClose(w http.ResponseWriter, r *http.Request) {
    	var req keystore.CloseRequest
    	if !serverutil.DecodeJSONRequest(w, r, &req) {
    		return
    	}
    
    	if s.KeyStore.Close(req.Username, req.SessionID) {
    		log.Printf("Close(%s): discarded key", req.Username)
    	}
    
    	requestsCounter.WithLabelValues("Close", "ok").Inc()
    	serverutil.EncodeJSONResponse(w, &emptyResponse)
    }
    
    func (s *keyStoreServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    	switch r.URL.Path {
    	case "/api/open":
    		s.handleOpen(w, r)
    	case "/api/get_key":
    		s.handleGet(w, r)
    	case "/api/close":
    		s.handleClose(w, r)
    	default:
    		http.NotFound(w, r)
    	}
    }
    
    // NewServer wraps the HTTP API around a KeyStore.
    func NewServer(ks *KeyStore) http.Handler {
    	return &keyStoreServer{ks}
    }