func (h *PolicyHandler) AddResourceToPolicy(cmd *cobra.Command, args []string) { h.M.Dry = *h.Config.Dry h.M.Endpoint = h.Config.Resolve("/policies") h.M.Client = h.Config.OAuth2Client(cmd) if len(args) < 2 { fmt.Print(cmd.UsageString()) return } policy, err := h.M.Get(args[0]) pkg.Must(err, "Could not get policy: %s", err) err = h.M.Delete(args[0]) if h.M.Dry { fmt.Printf("%s\n", err) } else { pkg.Must(err, "Could not prepare policy for update: %s", err) } p := policy.(*ladon.DefaultPolicy) p.Resources = append(p.Resources, args[1:]...) err = h.M.Create(policy) if h.M.Dry { fmt.Printf("%s\n", err) return } pkg.Must(err, "Could not update policy: %s", err) fmt.Printf("Added resources to policy %s", p.ID) }
func runHostCmd(cmd *cobra.Command, args []string) { router := httprouter.New() serverHandler := &server.Handler{} serverHandler.Start(c, router) if ok, _ := cmd.Flags().GetBool("dangerous-auto-logon"); ok { logrus.Warnln("Do not use flag --dangerous-auto-logon in production.") err := c.Persist() pkg.Must(err, "Could not write configuration file: %s", err) } http.Handle("/", router) var srv = http.Server{ Addr: c.GetAddress(), TLSConfig: &tls.Config{ Certificates: []tls.Certificate{ getOrCreateTLSCertificate(cmd), }, }, } var err error logrus.Infof("Starting server on %s", c.GetAddress()) if ok, _ := cmd.Flags().GetBool("force-dangerous-http"); ok { logrus.Warnln("HTTPS disabled. Never do this in production.") err = srv.ListenAndServe() } else { err = srv.ListenAndServeTLS("", "") } pkg.Must(err, "Could not start server: %s %s.", err) }
func (h *PolicyHandler) CreatePolicy(cmd *cobra.Command, args []string) { h.M.Dry = *h.Config.Dry h.M.Endpoint = h.Config.Resolve("/policies") h.M.Client = h.Config.OAuth2Client(cmd) files, _ := cmd.Flags().GetStringSlice("files") if len(files) > 0 { for _, path := range files { reader, err := os.Open(path) pkg.Must(err, "Could not open file %s: %s", path, err) var policy ladon.DefaultPolicy err = json.NewDecoder(reader).Decode(&policy) pkg.Must(err, "Could not parse JSON: %s", err) err = h.M.Create(&policy) pkg.Must(err, "Could not create policy: %s", err) fmt.Printf("Imported policy %s from %s.\n", policy.ID, path) } return } id, _ := cmd.Flags().GetString("id") description, _ := cmd.Flags().GetString("description") subjects, _ := cmd.Flags().GetStringSlice("subjects") resources, _ := cmd.Flags().GetStringSlice("resources") actions, _ := cmd.Flags().GetStringSlice("actions") isAllow, _ := cmd.Flags().GetBool("allow") if len(subjects) == 0 || len(resources) == 0 || len(actions) == 0 { fmt.Println(cmd.UsageString()) fmt.Println("") fmt.Println("Got empty subject, resource or action list") } effect := ladon.DenyAccess if isAllow { effect = ladon.AllowAccess } policy := &ladon.DefaultPolicy{ ID: id, Description: description, Subjects: subjects, Resources: resources, Actions: actions, Effect: effect, } err := h.M.Create(policy) if h.M.Dry { fmt.Printf("%s\n", err) return } pkg.Must(err, "Could not create policy: %s", err) fmt.Printf("Created policy %s.\n", policy.ID) }
func (h *Handler) createRS256KeysIfNotExist(c *config.Config, set, lookup string) { ctx := c.Context() generator := jwk.RS256Generator{} if _, err := ctx.KeyManager.GetKey(set, lookup); errors.Is(err, pkg.ErrNotFound) { logrus.Warnf("Key pair for signing %s is missing. Creating new one.", set) keys, err := generator.Generate("") pkg.Must(err, "Could not generate %s key: %s", set, err) err = ctx.KeyManager.AddKeySet(set, keys) pkg.Must(err, "Could not persist %s key: %s", set, err) } }
func init() { keys, err := keyGenerator.Generate("") pkg.Must(err, "") keyManager.AddKeySet(ConsentChallengeKey, keys) keys, err = keyGenerator.Generate("") pkg.Must(err, "") keyManager.AddKeySet(ConsentEndpointKey, keys) ts = httptest.NewServer(router) handler.SetRoutes(router) store.Clients["app"] = &fosite.DefaultClient{ ID: "app", Secret: []byte("secret"), RedirectURIs: []string{ts.URL + "/callback"}, ResponseTypes: []string{"id_token", "code", "token"}, GrantTypes: []string{"implicit", "refresh_token", "authorization_code", "password", "client_credentials"}, } c, _ := url.Parse(ts.URL + "/consent") handler.ConsentURL = *c h, _ := hasher.Hash([]byte("secret")) store.Clients["app-client"] = &fosite.DefaultClient{ ID: "app-client", Secret: h, RedirectURIs: []string{ts.URL + "/callback"}, ResponseTypes: []string{"id_token", "code", "token"}, GrantTypes: []string{"implicit", "refresh_token", "authorization_code", "password", "client_credentials"}, } oauthConfig = &oauth2.Config{ ClientID: "app-client", ClientSecret: "secret", Endpoint: oauth2.Endpoint{ AuthURL: ts.URL + "/oauth2/auth", TokenURL: ts.URL + "/oauth2/token", }, RedirectURL: ts.URL + "/callback", Scopes: []string{"hydra"}, } oauthClientConfig = &clientcredentials.Config{ ClientID: "app-client", ClientSecret: "secret", TokenURL: ts.URL + "/oauth2/token", Scopes: []string{"hydra"}, } }
func (h *Handler) createRootIfNewInstall(c *config.Config) { ctx := c.Context() clients, err := h.Clients.Manager.GetClients() pkg.Must(err, "Could not fetch client list: %s", err) if len(clients) != 0 { return } rs, err := pkg.GenerateSecret(16) pkg.Must(err, "Could notgenerate secret because %s", err) secret := []byte(string(rs)) logrus.Warn("No clients were found. Creating a temporary root client...") root := &fosite.DefaultClient{ Name: "This temporary client is generated by hydra and is granted all of hydra's administrative privileges. It must be removed when everything is set up.", GrantTypes: []string{"client_credentials", "authorization_code"}, ResponseTypes: []string{"token", "code"}, GrantedScopes: []string{"hydra", "core"}, RedirectURIs: []string{"http://localhost:4445/callback"}, Secret: secret, } err = h.Clients.Manager.CreateClient(root) pkg.Must(err, "Could not create temporary root because %s", err) err = ctx.LadonManager.Create(&ladon.DefaultPolicy{ Description: "This is a policy created by hydra and issued to the first client. It grants all of hydra's administrative privileges to the client and enables the client_credentials response type.", Subjects: []string{root.GetID()}, Effect: ladon.AllowAccess, Resources: []string{"rn:hydra:<.*>"}, Actions: []string{"<.*>"}, }) pkg.Must(err, "Could not create admin policy because %s", err) c.Lock() c.ClientID = root.ID c.ClientSecret = string(secret) c.Unlock() logrus.Warn("Temporary root client created.") logrus.Warnf("client_id: %s", root.GetID()) logrus.Warnf("client_secret: %s", string(secret)) logrus.Warn("The root client must be removed in production. The root's credentials could be accidentally logged.") }
func (h *JWKHandler) GetKeys(cmd *cobra.Command, args []string) { h.M.Dry = *h.Config.Dry h.M.Endpoint = h.Config.Resolve("/keys") h.M.Client = h.Config.OAuth2Client(cmd) if len(args) == 0 { fmt.Println(cmd.UsageString()) return } keys, err := h.M.GetKeySet(args[0]) if h.M.Dry { fmt.Printf("%s\n", err) return } pkg.Must(err, "Could not generate keys: %s", err) out, err := json.MarshalIndent(keys, "", "\t") pkg.Must(err, "Could not marshall keys: %s", err) fmt.Printf("%s\n", out) }
func (h *PolicyHandler) GetPolicy(cmd *cobra.Command, args []string) { h.M.Dry = *h.Config.Dry h.M.Endpoint = h.Config.Resolve("/policies") h.M.Client = h.Config.OAuth2Client(cmd) if len(args) == 0 { fmt.Print(cmd.UsageString()) return } policy, err := h.M.Get(args[0]) if h.M.Dry { fmt.Printf("%s\n", err) return } pkg.Must(err, "Could not delete policy: %s", err) out, err := json.MarshalIndent(policy, "", "\t") pkg.Must(err, "Could not retrieve policy: %s", err) fmt.Printf("%s\n", out) }
func (h *ClientHandler) ImportClients(cmd *cobra.Command, args []string) { h.M.Dry = *h.Config.Dry if len(args) == 0 { fmt.Print(cmd.UsageString()) return } for _, path := range args { reader, err := os.Open(path) pkg.Must(err, "Could not open file %s: %s", path, err) var client fosite.DefaultClient err = json.NewDecoder(reader).Decode(&client) pkg.Must(err, "Could not parse JSON: %s", err) err = h.M.CreateClient(&client) if h.M.Dry { fmt.Printf("%s\n", err) continue } pkg.Must(err, "Could not create client: %s", err) fmt.Printf("Imported client %s from %s.\n", client.ID, path) } }
func (h *ClientHandler) CreateClient(cmd *cobra.Command, args []string) { var err error h.M.Dry = *h.Config.Dry h.M.Endpoint = h.Config.Resolve("/clients") h.M.Client = h.Config.OAuth2Client(cmd) responseTypes, _ := cmd.Flags().GetStringSlice("response-types") grantTypes, _ := cmd.Flags().GetStringSlice("grant-types") allowedScopes, _ := cmd.Flags().GetStringSlice("allowed-scopes") callbacks, _ := cmd.Flags().GetStringSlice("callbacks") name, _ := cmd.Flags().GetString("name") id, _ := cmd.Flags().GetString("id") secret, err := pkg.GenerateSecret(26) pkg.Must(err, "Could not generate secret: %s", err) client := &fosite.DefaultClient{ ID: id, Secret: secret, ResponseTypes: responseTypes, GrantedScopes: allowedScopes, GrantTypes: grantTypes, RedirectURIs: callbacks, Name: name, } err = h.M.CreateClient(client) if h.M.Dry { fmt.Printf("%s\n", err) return } pkg.Must(err, "Could not create client: %s", err) fmt.Printf("Client ID: %s\n", client.ID) fmt.Printf("Client Secret: %s\n", secret) }
func (h *JWKHandler) DeleteKeys(cmd *cobra.Command, args []string) { h.M.Endpoint = h.Config.Resolve("/keys") h.M.Client = h.Config.OAuth2Client(cmd) if len(args) == 0 { fmt.Println(cmd.UsageString()) return } err := h.M.DeleteKeySet(args[0]) if h.M.Dry { fmt.Printf("%s\n", err) return } pkg.Must(err, "Could not generate keys: %s", err) fmt.Println("Key set deleted.") }
func (c *Config) Resolve(join ...string) *url.URL { c.Lock() defer c.Unlock() if c.cluster == nil { cluster, err := url.Parse(c.ClusterURL) c.cluster = cluster pkg.Must(err, "Could not parse cluster url: %s", err) } if len(join) == 0 { return c.cluster } return pkg.JoinURL(c.cluster, join...) }
func (h *ConnectionHandler) DeleteConnection(cmd *cobra.Command, args []string) { h.M.Dry = *h.Config.Dry h.M.Client = h.Config.OAuth2Client(cmd) h.M.Endpoint = h.Config.Resolve("/connections") if len(args) == 0 { fmt.Print(cmd.UsageString()) return } for _, arg := range args { err := h.M.Delete(arg) if h.M.Dry { fmt.Printf("%s\n", err) continue } pkg.Must(err, "Could not delete connection: %s", err) fmt.Printf("Connection %s deleted.\n", arg) } }
func getOrCreateTLSCertificate(cmd *cobra.Command) tls.Certificate { if cert := loadCertificateFromFile(cmd); cert != nil { return *cert } else if cert := loadCertificateFromEnv(cmd); cert != nil { return *cert } ctx := c.Context() keys, err := ctx.KeyManager.GetKey(TLSKeyName, "private") if errors.Is(err, pkg.ErrNotFound) { logrus.Warn("Key for TLS not found. Creating new one.") keys, err = new(jwk.ECDSA256Generator).Generate("") pkg.Must(err, "Could not generate key: %s", err) cert, err := createSelfSignedCertificate(jwk.First(keys.Key("private")).Key) pkg.Must(err, "Could not create X509 PEM Key Pair: %s", err) private := jwk.First(keys.Key("private")) private.Certificates = []*x509.Certificate{cert} keys = &jose.JsonWebKeySet{ Keys: []jose.JsonWebKey{ *private, *jwk.First(keys.Key("public")), }, } err = ctx.KeyManager.AddKeySet(TLSKeyName, keys) pkg.Must(err, "Could not persist key: %s", err) } else { pkg.Must(err, "Could not retrieve key: %s", err) } private := jwk.First(keys.Key("private")) block, err := jwk.PEMBlockForKey(private.Key) if err != nil { pkg.Must(err, "Could not encode key to PEM: %s", err) } if len(private.Certificates) == 0 { logrus.Fatal("TLS certificate chain can not be empty") } pemCert := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: private.Certificates[0].Raw}) pemKey := pem.EncodeToMemory(block) cert, err := tls.X509KeyPair(pemCert, pemKey) pkg.Must(err, "Could not decode certificate: %s", err) return cert }
func (h *ClientHandler) DeleteClient(cmd *cobra.Command, args []string) { h.M.Dry = *h.Config.Dry h.M.Endpoint = h.Config.Resolve("/clients") h.M.Client = h.Config.OAuth2Client(cmd) if len(args) == 0 { fmt.Print(cmd.UsageString()) return } for _, c := range args { err := h.M.DeleteClient(c) if h.M.Dry { fmt.Printf("%s\n", err) continue } pkg.Must(err, "Could not delete client: %s", err) } fmt.Println("Client(s) deleted.") }
func (c *Config) GetSystemSecret() []byte { c.Lock() defer c.Unlock() if len(c.SystemSecret) >= 16 { hash := sha256.Sum256(c.SystemSecret) c.SystemSecret = hash[:] return c.SystemSecret } logrus.Warnf("Expected system secret to be at least %d characters long but only got %d characters.", 32, len(c.SystemSecret)) logrus.Warnln("Generating a random system secret...") var err error c.SystemSecret, err = pkg.GenerateSecret(32) pkg.Must(err, "Could not generate global secret: %s", err) logrus.Warnf("Generated system secret: %s", c.SystemSecret) logrus.Warnln("Do not auto-generate system secrets in production.") hash := sha256.Sum256(c.SystemSecret) c.SystemSecret = hash[:] return c.SystemSecret }
func (h *ConnectionHandler) CreateConnection(cmd *cobra.Command, args []string) { h.M.Dry = *h.Config.Dry h.M.Client = h.Config.OAuth2Client(cmd) h.M.Endpoint = h.Config.Resolve("/connections") if len(args) != 3 { fmt.Print(cmd.UsageString()) return } err := h.M.Create(&connection.Connection{ ID: uuid.New(), Provider: args[0], LocalSubject: args[1], RemoteSubject: args[2], }) if h.M.Dry { fmt.Printf("%s\n", err) return } pkg.Must(err, "Could not create connection: %s", err) }
Short: "Generate an OAuth2 token the client grant type", Long: "This command uses the CLI's credentials to create an access token.", Run: func(cmd *cobra.Command, args []string) { ctx := context.Background() if ok, _ := cmd.Flags().GetBool("skip-tls-verify"); ok { fmt.Println("Warning: Skipping TLS Certificate Verification.") ctx = context.WithValue(context.Background(), oauth2.HTTPClient, &http.Client{Transport: &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, }}) } oauthConfig := clientcredentials.Config{ ClientID: c.ClientID, ClientSecret: c.ClientSecret, TokenURL: pkg.JoinURLStrings(c.ClusterURL, "/oauth2/token"), Scopes: []string{ "core", "hydra", }, } t, err := oauthConfig.Token(ctx) pkg.Must(err, "Could not authenticate, because: %s\n", err) fmt.Printf("%s", t.AccessToken) }, } func init() { tokenCmd.AddCommand(tokenSelfCmd) }
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, }}) } conf := oauth2.Config{ ClientID: c.ClientID, ClientSecret: c.ClientSecret, Endpoint: oauth2.Endpoint{ TokenURL: pkg.JoinURLStrings(c.ClusterURL, "/oauth2/token"), AuthURL: pkg.JoinURLStrings(c.ClusterURL, "/oauth2/auth"), }, Scopes: []string{"core", "hydra"}, } state, err := sequence.RuneSequence(24, []rune("abcdefghijklmnopqrstuvwxyz")) pkg.Must(err, "Could not generate random state: %s", err) nonce, err := sequence.RuneSequence(24, []rune("abcdefghijklmnopqrstuvwxyz")) pkg.Must(err, "Could not generate random state: %s", err) location := conf.AuthCodeURL(string(state)) + "&nonce=" + string(nonce) if ok, _ := cmd.Flags().GetBool("no-open"); !ok { webbrowser.Open(location) } fmt.Printf("If your browser does not open automatically, navigate to: %s\n", location) fmt.Println("Setting up callback listener on http://localhost:4445/callback") fmt.Println("Press ctrl + c on Linux / Windows or cmd + c on OSX to end the process.") srv := &graceful.Server{