mirror of
				https://github.com/simon987/ws_bucket.git
				synced 2025-10-31 08:26:55 +00:00 
			
		
		
		
	Auth with global secret for admin endpoints
This commit is contained in:
		
							parent
							
								
									e2ba51b77a
								
							
						
					
					
						commit
						b095c92cfd
					
				
							
								
								
									
										23
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								README.md
									
									
									
									
									
								
							| @ -7,9 +7,32 @@ | ||||
| | `WS_BUCKET_LOGLEVEL` | `trace` | | ||||
| | `WS_BUCKET_CONNSTR` | `host=localhost user=ws_bucket dbname=ws_bucket password=ws_bucket sslmode=disable` | | ||||
| | `WS_BUCKET_DIALECT` | `postgres` | | ||||
| | `WS_BUCKET_SECRET` | `default_secret`* | | ||||
| 
 | ||||
| \* You should change this value! | ||||
| 
 | ||||
| ### Running tests | ||||
| ```bash | ||||
| export WS_BUCKET_ADDR=0.0.0.0:3021 | ||||
| export WS_BUCKET_WORKDIR=. | ||||
| 
 | ||||
| cd test/ | ||||
| go test | ||||
| ``` | ||||
| 
 | ||||
| ### Auth | ||||
| Administration endpoints require HMAC_SHA256 authentication. | ||||
| Request header: | ||||
| ``` | ||||
| { | ||||
|     "Timestamp": <Current time (RFC1123)> | ||||
|     "X-Signature": <HMAC_SHA256(BODY + TIMESTAMP)> | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| Upload endpoint requires a valid upload token: | ||||
| ``` | ||||
| { | ||||
|     "X-Upload-Token": <token> | ||||
| } | ||||
| ``` | ||||
|  | ||||
							
								
								
									
										63
									
								
								api/auth.go
									
									
									
									
									
								
							
							
						
						
									
										63
									
								
								api/auth.go
									
									
									
									
									
								
							| @ -1 +1,64 @@ | ||||
| package api | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"crypto" | ||||
| 	"crypto/hmac" | ||||
| 	"encoding/hex" | ||||
| 	"errors" | ||||
| 	"github.com/valyala/fasthttp" | ||||
| 	"math" | ||||
| 	"os" | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| var Secret = []byte(getApiSecret()) | ||||
| 
 | ||||
| func getApiSecret() string { | ||||
| 
 | ||||
| 	secret := os.Getenv("WS_BUCKET_SECRET") | ||||
| 	if secret == "" { | ||||
| 		return "default_secret" | ||||
| 	} else { | ||||
| 		return secret | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func validateRequest(ctx *fasthttp.RequestCtx) error { | ||||
| 
 | ||||
| 	signature := ctx.Request.Header.Peek("X-Signature") | ||||
| 	timeStampStr := string(ctx.Request.Header.Peek("Timestamp")) | ||||
| 
 | ||||
| 	if timeStampStr == "" { | ||||
| 		return errors.New("date is not specified") | ||||
| 	} | ||||
| 
 | ||||
| 	timestamp, err := time.Parse(time.RFC1123, timeStampStr) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if math.Abs(float64(timestamp.Unix()-time.Now().Unix())) > 60 { | ||||
| 		return errors.New("invalid Timestamp") | ||||
| 	} | ||||
| 
 | ||||
| 	var body []byte | ||||
| 	if ctx.Request.Header.IsGet() { | ||||
| 		body = ctx.Request.RequestURI() | ||||
| 	} else { | ||||
| 		body = ctx.Request.Body() | ||||
| 	} | ||||
| 
 | ||||
| 	mac := hmac.New(crypto.SHA256.New, Secret) | ||||
| 	mac.Write(body) | ||||
| 	mac.Write([]byte(timeStampStr)) | ||||
| 
 | ||||
| 	expectedMac := make([]byte, 64) | ||||
| 	hex.Encode(expectedMac, mac.Sum(nil)) | ||||
| 	matches := bytes.Compare(expectedMac, signature) == 0 | ||||
| 
 | ||||
| 	if !matches { | ||||
| 		return errors.New("signature does not match") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @ -7,7 +7,8 @@ import ( | ||||
| ) | ||||
| 
 | ||||
| type GenericResponse struct { | ||||
| 	Ok bool `json:"ok"` | ||||
| 	Ok      bool   `json:"ok"` | ||||
| 	Message string `json:"message,omitempty"` | ||||
| } | ||||
| 
 | ||||
| type AllocateUploadSlotRequest struct { | ||||
|  | ||||
							
								
								
									
										12
									
								
								api/slot.go
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								api/slot.go
									
									
									
									
									
								
							| @ -22,10 +22,18 @@ var upgrader = websocket.FastHTTPUpgrader{ | ||||
| 
 | ||||
| func (api *WebApi) AllocateUploadSlot(ctx *fasthttp.RequestCtx) { | ||||
| 
 | ||||
| 	//todo auth | ||||
| 	err := validateRequest(ctx) | ||||
| 	if err != nil { | ||||
| 		ctx.Response.Header.SetStatusCode(401) | ||||
| 		Json(GenericResponse{ | ||||
| 			Ok:      false, | ||||
| 			Message: err.Error(), | ||||
| 		}, ctx) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	req := &AllocateUploadSlotRequest{} | ||||
| 	err := json.Unmarshal(ctx.Request.Body(), req) | ||||
| 	err = json.Unmarshal(ctx.Request.Body(), req) | ||||
| 	if err != nil { | ||||
| 		ctx.Response.Header.SetStatusCode(400) | ||||
| 		Json(GenericResponse{ | ||||
|  | ||||
| @ -2,11 +2,15 @@ package test | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"crypto" | ||||
| 	"crypto/hmac" | ||||
| 	"encoding/hex" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"github.com/simon987/ws_bucket/api" | ||||
| 	"io/ioutil" | ||||
| 	"net/http" | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| func Post(path string, x interface{}) *http.Response { | ||||
| @ -19,16 +23,13 @@ func Post(path string, x interface{}) *http.Response { | ||||
| 	req, err := http.NewRequest("POST", "http://"+api.GetServerAddress()+path, buf) | ||||
| 	handleErr(err) | ||||
| 
 | ||||
| 	//ts := time.Now().Format(time.RFC1123) | ||||
| 	// | ||||
| 	//mac := hmac.New(crypto.SHA256.New, worker.Secret) | ||||
| 	//mac.Write(body) | ||||
| 	//mac.Write([]byte(ts)) | ||||
| 	//sig := hex.EncodeToString(mac.Sum(nil)) | ||||
| 	// | ||||
| 	//req.Header.Add("X-Worker-Id", strconv.FormatInt(worker.Id, 10)) | ||||
| 	//req.Header.Add("X-Signature", sig) | ||||
| 	//req.Header.Add("Timestamp", ts) | ||||
| 	ts := time.Now().Format(time.RFC1123) | ||||
| 	mac := hmac.New(crypto.SHA256.New, []byte("default_secret")) | ||||
| 	mac.Write(body) | ||||
| 	mac.Write([]byte(ts)) | ||||
| 	sig := hex.EncodeToString(mac.Sum(nil)) | ||||
| 	req.Header.Add("X-Signature", sig) | ||||
| 	req.Header.Add("Timestamp", ts) | ||||
| 
 | ||||
| 	r, err := s.Do(req) | ||||
| 	handleErr(err) | ||||
| @ -43,6 +44,14 @@ func Get(path string, token string) *http.Response { | ||||
| 	req, err := http.NewRequest("GET", "http://"+api.GetServerAddress()+path, nil) | ||||
| 	handleErr(err) | ||||
| 
 | ||||
| 	ts := time.Now().Format(time.RFC1123) | ||||
| 	mac := hmac.New(crypto.SHA256.New, []byte("default_secret")) | ||||
| 	mac.Write([]byte(path)) | ||||
| 	mac.Write([]byte(ts)) | ||||
| 	sig := hex.EncodeToString(mac.Sum(nil)) | ||||
| 	req.Header.Add("X-Signature", sig) | ||||
| 	req.Header.Add("Timestamp", ts) | ||||
| 
 | ||||
| 	req.Header.Set("X-Upload-Token", token) | ||||
| 
 | ||||
| 	r, err := s.Do(req) | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user