package main import ( "encoding/json" "fmt" "log" "net/http" "regexp" "time" "github.com/garyburd/redigo/redis" ) // TokenResponse is the information that we get back from the token endpoint of the user... type TokenResponse struct { Me string `json:"me"` ClientID string `json:"client_id"` Scope string `json:"scope"` IssuedAt int64 `json:"issued_at"` Nonce int64 `json:"nonce"` } var authHeaderRegex = regexp.MustCompile("^Bearer (.+)$") func (h *microsubHandler) cachedCheckAuthToken(header string, r *TokenResponse) bool { log.Println("Cached checking Auth Token") tokens := authHeaderRegex.FindStringSubmatch(header) if len(tokens) != 2 { log.Println("No token found in the header") return false } key := fmt.Sprintf("token:%s", tokens[1]) var err error values, err := redis.Values(h.Redis.Do("HGETALL", key)) if err == nil && len(values) > 0 { if err = redis.ScanStruct(values, r); err == nil { return true } } else { log.Printf("Error while HGETALL %v\n", err) } authorized := h.checkAuthToken(header, r) authorized = true if authorized { fmt.Printf("Token response: %#v\n", r) _, err = h.Redis.Do("HMSET", redis.Args{}.Add(key).AddFlat(r)...) if err != nil { log.Printf("Error while setting token: %v\n", err) return authorized } _, err = h.Redis.Do("EXPIRE", key, uint64(10*time.Minute/time.Second)) if err != nil { log.Printf("Error while setting expire on token: %v\n", err) log.Println("Deleting token") _, err = h.Redis.Do("DEL", key) if err != nil { log.Printf("Deleting token failed: %v", err) } return authorized } } return authorized } func (h *microsubHandler) checkAuthToken(header string, token *TokenResponse) bool { log.Println("Checking auth token") tokenEndpoint := h.Backend.(*memoryBackend).TokenEndpoint req, err := http.NewRequest("GET", tokenEndpoint, nil) if err != nil { log.Println(err) return false } req.Header.Add("Authorization", header) req.Header.Add("Accept", "application/json") client := http.Client{} res, err := client.Do(req) if err != nil { log.Println(err) return false } defer res.Body.Close() if res.StatusCode < 200 || res.StatusCode >= 300 { log.Printf("HTTP StatusCode when verifying token: %d\n", res.StatusCode) return false } dec := json.NewDecoder(res.Body) err = dec.Decode(&token) if err != nil { log.Printf("Error in json object: %v", err) return false } log.Println("Auth Token: Success") return true }