github.com/hoffie/larasync@v0.0.0-20151025221940-0384d2bddcef/api/server/authorization.go (about)

     1  package server
     2  
     3  import (
     4  	"encoding/hex"
     5  	"io"
     6  	"net/http"
     7  
     8  	"github.com/gorilla/mux"
     9  
    10  	"github.com/hoffie/larasync/api/common"
    11  )
    12  
    13  // extractAuthorizationPubKey returns a public key which has been passed to the
    14  // as the var "authorizationPublicKeyString" in the URL.
    15  func extractAuthorizationPubKey(req *http.Request) (publicKey [PublicKeySize]byte) {
    16  	vars := mux.Vars(req)
    17  
    18  	publicKeyString := vars["authPublicKey"]
    19  	publicKeySlice, err := hex.DecodeString(publicKeyString)
    20  	publicKey = [PublicKeySize]byte{}
    21  	if err != nil {
    22  		publicKeySlice = []byte{}
    23  	}
    24  	copy(publicKey[:], publicKeySlice)
    25  	return publicKey
    26  }
    27  
    28  // authorizationGet requests a authorization for a passed public key.
    29  func (s *Server) authorizationGet(rw http.ResponseWriter, req *http.Request) {
    30  	vars := mux.Vars(req)
    31  
    32  	publicKey := extractAuthorizationPubKey(req)
    33  	repositoryName := vars["repository"]
    34  	repository, err := s.rm.Open(repositoryName)
    35  
    36  	var readerErr error
    37  	var reader io.ReadCloser
    38  
    39  	if err == nil {
    40  		// FIXME: This is a possible timing attack which exposes if the repository
    41  		// does exist or not. At the moment there is no fix for this.
    42  		reader, readerErr = repository.GetAuthorizationReader(publicKey)
    43  	}
    44  
    45  	if !common.ValidateRequest(req, publicKey, s.maxRequestAge) || err != nil || readerErr != nil {
    46  		http.Error(rw, "Unauthorized", http.StatusUnauthorized)
    47  		return
    48  	}
    49  
    50  	rw.Header().Set("Content-Type", "application/octet-stream")
    51  	rw.WriteHeader(http.StatusOK)
    52  
    53  	io.Copy(rw, reader)
    54  	_ = reader.Close()
    55  
    56  	repository.DeleteAuthorization(publicKey)
    57  }
    58  
    59  // authorizationPut adds a new authorization object to the repository.
    60  func (s *Server) authorizationPut(rw http.ResponseWriter, req *http.Request) {
    61  	vars := mux.Vars(req)
    62  
    63  	publicKey := extractAuthorizationPubKey(req)
    64  	repositoryName := vars["repository"]
    65  	repository, err := s.rm.Open(repositoryName)
    66  	if err != nil {
    67  		http.Error(rw, "Unauthorized", http.StatusUnauthorized)
    68  	}
    69  
    70  	err = repository.SetAuthorizationData(publicKey, req.Body)
    71  	if err != nil {
    72  		http.Error(rw, "Internal Error", http.StatusInternalServerError)
    73  	}
    74  
    75  	rw.Header().Set("Location", req.URL.String())
    76  	rw.WriteHeader(http.StatusCreated)
    77  }