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 75% rename from cmd/login.go rename to pkg/cmd/login.go index 461c2f5..6fdaab1 100644 --- a/cmd/login.go +++ b/pkg/cmd/login.go @@ -15,21 +15,13 @@ package cmd import ( - // "bytes" - // "fmt" "io/ioutil" - // "crypto/tls" - // "encoding/json" "log" - // "net/http" + "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", @@ -47,14 +39,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) } @@ -64,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 82% rename from cmd/refresh.go rename to pkg/cmd/refresh.go index cfdae0d..ce848eb 100644 --- a/cmd/refresh.go +++ b/pkg/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/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 85% rename from cmd/sign.go rename to pkg/cmd/sign.go index 200fe7f..bf85fa6 100644 --- a/cmd/sign.go +++ b/pkg/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) } @@ -84,5 +85,3 @@ func init() { rootCmd.AddCommand(genSLTCmd) rootCmd.AddCommand(genSLOCmd) } - -// func generateServiceLoginToken(privateKey byte[], uid string, validTime int) (jwt string, err error) { diff --git a/cmd/utility.go b/pkg/dcosauth/dcosauth.go similarity index 67% rename from cmd/utility.go rename to pkg/dcosauth/dcosauth.go index 9101fb8..dfc8b99 100644 --- a/cmd/utility.go +++ b/pkg/dcosauth/dcosauth.go @@ -1,4 +1,4 @@ -package cmd +package dcosauth import ( "bytes" @@ -13,11 +13,11 @@ import ( "strings" "time" - "github.com/dgrijalva/jwt-go" + jwt "github.com/dgrijalva/jwt-go" ) 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 } -func checkExpired(tokenString string) (expired bool, err error) { +// 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,7 +66,8 @@ func checkExpired(tokenString string) (expired bool, err error) { return float64(claims.Exp) < minValidTime, nil } -func login(master string, loginObject []byte) (authToken string, err error) { +// 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 client := createClient() @@ -112,8 +109,8 @@ func login(master string, loginObject []byte) (authToken string, err error) { return dat.Token, nil } -// TODO: Add optional additional claims -func generateServiceLoginToken(privateKey []byte, uid string, validTime int) (loginToken string, err error) { +// 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) if err != nil { @@ -130,21 +127,23 @@ 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) +// 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) (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)) }