From bc7722e59ddb9b15c85b4c2901865bb9f509ba52 Mon Sep 17 00:00:00 2001 From: Chris Erwin Date: Thu, 18 Oct 2018 19:27:02 -0400 Subject: [PATCH 1/3] initial refactoring into a package --- cmd/login.go | 13 ++++++------- cmd/refresh.go | 9 +++++---- cmd/sign.go | 9 +++++---- cmd/utility.go => pkg/dcosauth/dcosauth.go | 16 ++++++++-------- 4 files changed, 24 insertions(+), 23 deletions(-) rename cmd/utility.go => pkg/dcosauth/dcosauth.go (85%) diff --git a/cmd/login.go b/cmd/login.go index 461c2f5..a7042bf 100644 --- a/cmd/login.go +++ b/cmd/login.go @@ -17,12 +17,11 @@ package cmd import ( // "bytes" // "fmt" - "io/ioutil" - // "crypto/tls" + "io/ioutil" // "crypto/tls" // "encoding/json" - "log" - // "net/http" + "log" // "net/http" + "github.com/dcos-labs/dcos-auth/pkg/dcosauth" "github.com/spf13/cobra" ) @@ -47,14 +46,14 @@ var loginCmd = &cobra.Command{ } // Returns a []byte - loginObject, err := generateServiceLoginObject(privateKey, uid, validTime) + loginObject, err := dcosauth.GenerateServiceLoginObject(privateKey, uid, validTime) if err != nil { log.Fatal(err) } - authToken, err := login(master, loginObject) + authToken, err := dcosauth.Login(master, loginObject) - err = output([]byte(authToken)) + err = dcosauth.Output([]byte(authToken), outputFile) if err != nil { log.Fatal(err) } diff --git a/cmd/refresh.go b/cmd/refresh.go index cfdae0d..ce848eb 100644 --- a/cmd/refresh.go +++ b/cmd/refresh.go @@ -18,6 +18,7 @@ import ( "io/ioutil" "log" + "github.com/dcos-labs/dcos-auth/pkg/dcosauth" "github.com/spf13/cobra" ) @@ -39,7 +40,7 @@ var refreshCmd = &cobra.Command{ // File does not exist; let's write to it refresh = true } else { - refresh, err = checkExpired(string(tokenString)) + refresh, err = dcosauth.CheckExpired(string(tokenString), refreshThreshold) if err != nil { log.Fatal(err) } @@ -52,14 +53,14 @@ var refreshCmd = &cobra.Command{ } // Returns a []byte - loginObject, err := generateServiceLoginObject(privateKey, uid, validTime) + loginObject, err := dcosauth.GenerateServiceLoginObject(privateKey, uid, validTime) if err != nil { log.Fatal(err) } - authToken, err := login(master, loginObject) + authToken, err := dcosauth.Login(master, loginObject) - err = output([]byte(authToken)) + err = dcosauth.Output([]byte(authToken), outputFile) if err != nil { log.Fatal(err) } diff --git a/cmd/sign.go b/cmd/sign.go index 200fe7f..b388e87 100644 --- a/cmd/sign.go +++ b/cmd/sign.go @@ -19,6 +19,7 @@ import ( "io/ioutil" "log" + "github.com/dcos-labs/dcos-auth/pkg/dcosauth" "github.com/spf13/cobra" ) @@ -39,13 +40,13 @@ var genSLTCmd = &cobra.Command{ log.Fatal(err) } - loginToken, err := generateServiceLoginToken(privateKey, uid, validTime) + loginToken, err := dcosauth.GenerateServiceLoginToken(privateKey, uid, validTime) if err != nil { log.Fatal(err) } // fmt.Println(string(loginObject)) - err = output([]byte(loginToken)) + err = dcosauth.Output([]byte(loginToken), outputFile) if err != nil { log.Fatal(err) } @@ -68,12 +69,12 @@ var genSLOCmd = &cobra.Command{ log.Fatal(err) } - loginObject, err := generateServiceLoginObject(privateKey, uid, validTime) + loginObject, err := dcosauth.GenerateServiceLoginObject(privateKey, uid, validTime) if err != nil { log.Fatal(err) } - err = output(loginObject) + err = dcosauth.Output(loginObject, outputFile) if err != nil { log.Fatal(err) } diff --git a/cmd/utility.go b/pkg/dcosauth/dcosauth.go similarity index 85% rename from cmd/utility.go rename to pkg/dcosauth/dcosauth.go index 9101fb8..15a4294 100644 --- a/cmd/utility.go +++ b/pkg/dcosauth/dcosauth.go @@ -1,4 +1,4 @@ -package cmd +package dcosauth import ( "bytes" @@ -13,7 +13,7 @@ import ( "strings" "time" - "github.com/dgrijalva/jwt-go" + jwt "github.com/dgrijalva/jwt-go" ) type serviceLoginObject struct { @@ -49,7 +49,7 @@ func createClient() *http.Client { return client } -func checkExpired(tokenString string) (expired bool, err error) { +func CheckExpired(tokenString string, refreshThreshold int) (expired bool, err error) { b64claims := strings.Split(tokenString, ".")[1] claimsJson, err := base64.RawStdEncoding.DecodeString(b64claims) @@ -70,7 +70,7 @@ func checkExpired(tokenString string) (expired bool, err error) { return float64(claims.Exp) < minValidTime, nil } -func login(master string, loginObject []byte) (authToken string, err error) { +func Login(master string, loginObject []byte) (authToken string, err error) { // Build client client := createClient() @@ -113,7 +113,7 @@ func login(master string, loginObject []byte) (authToken string, err error) { } // TODO: Add optional additional claims -func generateServiceLoginToken(privateKey []byte, uid string, validTime int) (loginToken string, err error) { +func GenerateServiceLoginToken(privateKey []byte, uid string, validTime int) (loginToken string, err error) { // Parse the key key, err := jwt.ParseRSAPrivateKeyFromPEM(privateKey) if err != nil { @@ -130,8 +130,8 @@ func generateServiceLoginToken(privateKey []byte, uid string, validTime int) (lo return token.SignedString(key) } -func generateServiceLoginObject(privateKey []byte, uid string, validTime int) (loginObject []byte, err error) { - token, err := generateServiceLoginToken(privateKey, uid, validTime) +func GenerateServiceLoginObject(privateKey []byte, uid string, validTime int) (loginObject []byte, err error) { + token, err := GenerateServiceLoginToken(privateKey, uid, validTime) m := serviceLoginObject{ Uid: uid, @@ -141,7 +141,7 @@ func generateServiceLoginObject(privateKey []byte, uid string, validTime int) (l return json.Marshal(m) } -func output(content []byte) (err error) { +func Output(content []byte, outputFile string) (err error) { err = nil if outputFile != "" { err = ioutil.WriteFile(outputFile, []byte(content), 0600) From 5e74ddbc8d4887489864fa5b5a925f972ed1593b Mon Sep 17 00:00:00 2001 From: Chris Erwin Date: Thu, 18 Oct 2018 20:02:39 -0400 Subject: [PATCH 2/3] refactor command main and package up commands --- main.go => cmd/dcos-auth/main.go | 2 +- {cmd => pkg/cmd}/login.go | 13 ++----------- {cmd => pkg/cmd}/refresh.go | 0 {cmd => pkg/cmd}/root.go | 2 +- {cmd => pkg/cmd}/sign.go | 2 -- 5 files changed, 4 insertions(+), 15 deletions(-) rename main.go => cmd/dcos-auth/main.go (93%) rename {cmd => pkg/cmd}/login.go (84%) rename {cmd => pkg/cmd}/refresh.go (100%) rename {cmd => pkg/cmd}/root.go (97%) rename {cmd => pkg/cmd}/sign.go (95%) diff --git a/main.go b/cmd/dcos-auth/main.go similarity index 93% rename from main.go rename to cmd/dcos-auth/main.go index 26c367a..4cf066f 100644 --- a/main.go +++ b/cmd/dcos-auth/main.go @@ -14,7 +14,7 @@ package main -import "github.com/justinrlee/dcos-auth/cmd" +import "github.com/dcos-labs/dcos-auth/pkg/cmd" func main() { cmd.Execute() diff --git a/cmd/login.go b/pkg/cmd/login.go similarity index 84% rename from cmd/login.go rename to pkg/cmd/login.go index a7042bf..6fdaab1 100644 --- a/cmd/login.go +++ b/pkg/cmd/login.go @@ -15,20 +15,13 @@ package cmd import ( - // "bytes" - // "fmt" - "io/ioutil" // "crypto/tls" - // "encoding/json" - "log" // "net/http" + "io/ioutil" + "log" "github.com/dcos-labs/dcos-auth/pkg/dcosauth" "github.com/spf13/cobra" ) -// type loginResponse struct { -// Token string `json:"token"` -// } - var loginCmd = &cobra.Command{ Use: "login", Short: "Log in and generate Service Authentication Token", @@ -63,5 +56,3 @@ var loginCmd = &cobra.Command{ func init() { rootCmd.AddCommand(loginCmd) } - -// func generateServiceLoginToken(privateKey byte[], uid string, validTime int) (jwt string, err error) { diff --git a/cmd/refresh.go b/pkg/cmd/refresh.go similarity index 100% rename from cmd/refresh.go rename to pkg/cmd/refresh.go diff --git a/cmd/root.go b/pkg/cmd/root.go similarity index 97% rename from cmd/root.go rename to pkg/cmd/root.go index f23d7bb..801668d 100644 --- a/cmd/root.go +++ b/pkg/cmd/root.go @@ -38,6 +38,7 @@ var rootCmd = &cobra.Command{ Long: `Helper tool to authenticate against DC/OS Enterprise ACS`, } +// Execute executes the dcos-auth cli command with flags func Execute() { if err := rootCmd.Execute(); err != nil { fmt.Println(err) @@ -52,5 +53,4 @@ func init() { rootCmd.PersistentFlags().StringVarP(&outputFile, "output", "o", "", "Output File (will default to stdout)") rootCmd.PersistentFlags().IntVarP(&validTime, "time", "t", 10, "Token validity (in seconds)") rootCmd.PersistentFlags().IntVarP(&refreshThreshold, "refreshThreshold", "r", 900, "Refresh if auth token has less than this many seconds left") - } diff --git a/cmd/sign.go b/pkg/cmd/sign.go similarity index 95% rename from cmd/sign.go rename to pkg/cmd/sign.go index b388e87..bf85fa6 100644 --- a/cmd/sign.go +++ b/pkg/cmd/sign.go @@ -85,5 +85,3 @@ func init() { rootCmd.AddCommand(genSLTCmd) rootCmd.AddCommand(genSLOCmd) } - -// func generateServiceLoginToken(privateKey byte[], uid string, validTime int) (jwt string, err error) { From 75831ff0a553bc48a704a7b301b9881ce74a85fc Mon Sep 17 00:00:00 2001 From: Chris Erwin Date: Thu, 18 Oct 2018 20:44:24 -0400 Subject: [PATCH 3/3] comment exported functions and other lint fixes --- pkg/dcosauth/dcosauth.go | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/pkg/dcosauth/dcosauth.go b/pkg/dcosauth/dcosauth.go index 15a4294..dfc8b99 100644 --- a/pkg/dcosauth/dcosauth.go +++ b/pkg/dcosauth/dcosauth.go @@ -17,7 +17,7 @@ import ( ) type serviceLoginObject struct { - Uid string `json:"uid"` + UID string `json:"uid"` Token string `json:"token"` } @@ -26,16 +26,11 @@ type loginResponse struct { } type claimSet struct { - Uid string `json:"uid"` + UID string `json:"uid"` Exp int `json:"exp"` // *StandardClaims } -type Cluster struct { - cluster_url string - client *http.Client -} - func createClient() *http.Client { // // Create transport to skip verify TODO: add certificate verification tr := &http.Transport{ @@ -49,17 +44,18 @@ func createClient() *http.Client { return client } +// CheckExpired checks if a token will expire within the refreshThreshold func CheckExpired(tokenString string, refreshThreshold int) (expired bool, err error) { b64claims := strings.Split(tokenString, ".")[1] - claimsJson, err := base64.RawStdEncoding.DecodeString(b64claims) + claimsJSON, err := base64.RawStdEncoding.DecodeString(b64claims) if err != nil { log.Fatal(err) } var claims claimSet - err = json.Unmarshal(claimsJson, &claims) + err = json.Unmarshal(claimsJSON, &claims) if err != nil { log.Fatal(err) @@ -70,6 +66,7 @@ func CheckExpired(tokenString string, refreshThreshold int) (expired bool, err e return float64(claims.Exp) < minValidTime, nil } +// Login acquires and returns a new JWT token by authenticating to the DC/OS api with a uid and private key func Login(master string, loginObject []byte) (authToken string, err error) { // Build client @@ -112,7 +109,7 @@ func Login(master string, loginObject []byte) (authToken string, err error) { return dat.Token, nil } -// TODO: Add optional additional claims +// GenerateServiceLoginToken generates a JWT login token func GenerateServiceLoginToken(privateKey []byte, uid string, validTime int) (loginToken string, err error) { // Parse the key key, err := jwt.ParseRSAPrivateKeyFromPEM(privateKey) @@ -130,21 +127,23 @@ func GenerateServiceLoginToken(privateKey []byte, uid string, validTime int) (lo return token.SignedString(key) } +// GenerateServiceLoginObject returns a JSON object containing a uid and a token generated with GenerateServiceLoginToken func GenerateServiceLoginObject(privateKey []byte, uid string, validTime int) (loginObject []byte, err error) { token, err := GenerateServiceLoginToken(privateKey, uid, validTime) m := serviceLoginObject{ - Uid: uid, + UID: uid, Token: token, } return json.Marshal(m) } -func Output(content []byte, outputFile string) (err error) { +// Output writes given content to a given filepath +func Output(content []byte, outputFilePath string) (err error) { err = nil - if outputFile != "" { - err = ioutil.WriteFile(outputFile, []byte(content), 0600) + if outputFilePath != "" { + err = ioutil.WriteFile(outputFilePath, []byte(content), 0600) } else { fmt.Println(string(content)) }