api

Paddy 2015-12-14 Parent:57c9412e8000

2:9b954c219259 Go to Latest

api/api.go

Update scope helpers and add access denied error. Refactor CheckScopes to take the Scopes as input instead of reading them from the passed request. Also, surface a GetScopes method that will pull the Scopes from the request and return them. While we're at it, we refactored to use the sort package instead of a manual search. We also needed an access_denied error, and that will come up a lot, so it was worth making a constant, just like our invalid_format error.

History
     1.1 --- a/api.go	Sat Dec 05 01:59:43 2015 -0800
     1.2 +++ b/api.go	Mon Dec 14 01:12:40 2015 -0800
     1.3 @@ -5,6 +5,7 @@
     1.4  	"errors"
     1.5  	"log"
     1.6  	"net/http"
     1.7 +	"sort"
     1.8  	"strings"
     1.9  
    1.10  	"bitbucket.org/ww/goautoneg"
    1.11 @@ -29,6 +30,7 @@
    1.12  var (
    1.13  	ActOfGodError      = []RequestError{{Slug: RequestErrActOfGod}}
    1.14  	InvalidFormatError = []RequestError{{Slug: RequestErrInvalidFormat, Field: "/"}}
    1.15 +	AccessDeniedError  = []RequestError{{Slug: RequestErrAccessDenied}}
    1.16  
    1.17  	Encoders = []string{"application/json"}
    1.18  
    1.19 @@ -110,24 +112,26 @@
    1.20  	})
    1.21  }
    1.22  
    1.23 -func CheckScopes(r *http.Request, scopes ...string) bool {
    1.24 -	passedStr := r.Header.Get("scopes")
    1.25 -	passed := strings.Split(passedStr, " ")
    1.26 -	for _, scope := range scopes {
    1.27 -		var found bool
    1.28 -		for _, p := range passed {
    1.29 -			if scope == strings.TrimSpace(p) {
    1.30 -				found = true
    1.31 -				break
    1.32 -			}
    1.33 -		}
    1.34 -		if !found {
    1.35 +func CheckScopes(scopes []string, checking ...string) bool {
    1.36 +	sort.Strings(scopes)
    1.37 +	for _, scope := range checking {
    1.38 +		found := sort.SearchStrings(scopes, scope)
    1.39 +		if found == len(scopes) || scopes[found] != scope {
    1.40  			return false
    1.41  		}
    1.42  	}
    1.43  	return true
    1.44  }
    1.45  
    1.46 +func GetScopes(r *http.Request) []string {
    1.47 +	scopes := strings.Split(r.Header.Get("scopes"), " ")
    1.48 +	for pos, scope := range scopes {
    1.49 +		scopes[pos] = strings.TrimSpace(scope)
    1.50 +	}
    1.51 +	sort.Strings(scopes)
    1.52 +	return scopes
    1.53 +}
    1.54 +
    1.55  func AuthUser(r *http.Request) (uuid.ID, error) {
    1.56  	rawID := r.Header.Get("User-ID")
    1.57  	if rawID == "" {