package main import ( "crypto/tls" "encoding/json" "flag" "fmt" "io" "log" "net/http" "os" "time" "github.com/gorilla/handlers" ) var ( addr string ti TokenIssuer ) func main() { flag.StringVar(&addr, "addr", ":5001", "address") flag.StringVar(&ti.Issuer, "issuer", "omnibus-gitlab-issuer", "issuer name") flag.StringVar(&ti.Audience, "audience", "docker", "audience name") flag.Int64Var(&ti.Expiration, "expires", 900, "expiration") flag.Parse() log.SetFlags(log.LstdFlags | log.Lshortfile) cert, err := tls.LoadX509KeyPair("auth.crt", "auth.key") if err != nil { log.Fatal(err) } ti.SigningKey = cert.PrivateKey mux := http.NewServeMux() mux.HandleFunc("/auth", func(w http.ResponseWriter, r *http.Request) { var resp struct { Token string `json:"access_token"` RefreshToken string `json:"refresh_token,omitempty"` ExpiresIn int64 `json:"expires_in,omitempty"` } user, _, ok := r.BasicAuth() if !ok { w.Header().Set("WWW-Authenticate", "Basic realm=Restricted") w.WriteHeader(http.StatusUnauthorized) return } authRequest := ResolveScopeList(r.URL.Query().Get("scope")) if len(authRequest) == 0 { // Authentication-only request ("docker login"), pass through. resp.Token, _ = ti.CreateJWT(user, authRequest) w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(&resp) return } authResult, err := Authorized(user, authRequest) if err != nil { w.WriteHeader(http.StatusUnauthorized) return } if resp.Token, err = ti.CreateJWT(user, authResult); err != nil { log.Printf("CreateJWT %v", err) w.WriteHeader(http.StatusUnauthorized) return } resp.ExpiresIn = ti.Expiration w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(&resp) }) h := handlers.CustomLoggingHandler(os.Stdout, mux, func(w io.Writer, p handlers.LogFormatterParams) { fmt.Fprintf(w, "%s %s %d %s %d %s (%s)\n", p.TimeStamp.Format("2006/01/02 15:04:05"), p.Request.Method, p.StatusCode, p.URL.RequestURI(), p.Size, p.Request.RemoteAddr, time.Since(p.TimeStamp)) }) log.Fatal(http.ListenAndServe(addr, h)) } func Authorized(user string, actions []ResourceActions) ([]ResourceActions, error) { return actions, nil }