Skip to content
This repository was archived by the owner on May 18, 2021. It is now read-only.

Commit b832769

Browse files
authored
Merge pull request #12 from segmentio/ej/login
Add login subcommand.
2 parents 3b768f5 + 5974d81 commit b832769

File tree

2 files changed

+133
-0
lines changed

2 files changed

+133
-0
lines changed

cmd/login.go

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package cmd
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"io/ioutil"
7+
"net/http"
8+
"net/url"
9+
10+
"github.com/99designs/aws-vault/keyring"
11+
"github.com/segmentio/aws-okta/lib"
12+
"github.com/skratchdot/open-golang/open"
13+
"github.com/spf13/cobra"
14+
)
15+
16+
// loginCmd represents the login command
17+
var loginCmd = &cobra.Command{
18+
Use: "login <profile>",
19+
Short: "login will authenticate you through okta and allow you to access your AWS environment through a browser",
20+
RunE: loginRun,
21+
}
22+
23+
func init() {
24+
RootCmd.AddCommand(loginCmd)
25+
}
26+
27+
func loginRun(cmd *cobra.Command, args []string) error {
28+
profile := args[0]
29+
config, err := lib.NewConfigFromEnv()
30+
if err != nil {
31+
return err
32+
}
33+
34+
profiles, err := config.Parse()
35+
if err != nil {
36+
return err
37+
}
38+
39+
if _, ok := profiles[profile]; !ok {
40+
return fmt.Errorf("Profile '%s' not found in your aws config", profile)
41+
}
42+
43+
opts := lib.ProviderOptions{
44+
Profiles: profiles,
45+
SessionDuration: sessionTTL,
46+
AssumeRoleDuration: assumeRoleTTL,
47+
}
48+
49+
kr, err := keyring.Open("aws-okta", backend)
50+
if err != nil {
51+
return err
52+
}
53+
54+
p, err := lib.NewProvider(kr, profile, opts)
55+
if err != nil {
56+
return err
57+
}
58+
59+
creds, err := p.Retrieve()
60+
if err != nil {
61+
return err
62+
}
63+
64+
jsonBytes, err := json.Marshal(map[string]string{
65+
"sessionId": creds.AccessKeyID,
66+
"sessionKey": creds.SecretAccessKey,
67+
"sessionToken": creds.SessionToken,
68+
})
69+
if err != nil {
70+
return err
71+
}
72+
73+
req, err := http.NewRequest("GET", "https://signin.aws.amazon.com/federation", nil)
74+
if err != nil {
75+
return err
76+
}
77+
q := req.URL.Query()
78+
q.Add("Action", "getSigninToken")
79+
q.Add("Session", string(jsonBytes))
80+
81+
req.URL.RawQuery = q.Encode()
82+
83+
resp, err := http.DefaultClient.Do(req)
84+
if err != nil {
85+
return err
86+
}
87+
88+
defer resp.Body.Close()
89+
body, err := ioutil.ReadAll(resp.Body)
90+
if err != nil {
91+
return err
92+
}
93+
94+
if resp.StatusCode != http.StatusOK {
95+
return fmt.Errorf("Call to getSigninToken failed with %v", resp.Status)
96+
}
97+
98+
var respParsed map[string]string
99+
if err = json.Unmarshal([]byte(body), &respParsed); err != nil {
100+
return err
101+
}
102+
103+
signinToken, ok := respParsed["SigninToken"]
104+
if !ok {
105+
return err
106+
}
107+
108+
destination := "https://console.aws.amazon.com/"
109+
prof := profiles[profile]
110+
if region, ok := prof["region"]; ok {
111+
destination = fmt.Sprintf(
112+
"https://%s.console.aws.amazon.com/console/home?region=%s",
113+
region, region,
114+
)
115+
}
116+
117+
loginURL := fmt.Sprintf(
118+
"https://signin.aws.amazon.com/federation?Action=login&Issuer=aws-vault&Destination=%s&SigninToken=%s",
119+
url.QueryEscape(destination),
120+
url.QueryEscape(signinToken),
121+
)
122+
123+
if err = open.Run(loginURL); err != nil {
124+
return err
125+
}
126+
return nil
127+
}

vendor/vendor.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,12 @@
249249
"revision": "b8bc1bf767474819792c23f32d8286a45736f1c6",
250250
"revisionTime": "2016-12-03T19:45:07Z"
251251
},
252+
{
253+
"checksumSHA1": "h/HMhokbQHTdLUbruoBBTee+NYw=",
254+
"path": "github.com/skratchdot/open-golang/open",
255+
"revision": "75fb7ed4208cf72d323d7d02fd1a5964a7a9073c",
256+
"revisionTime": "2016-03-02T14:40:31Z"
257+
},
252258
{
253259
"checksumSHA1": "q4eQ3EqPmvAISYOp3DD/GrccXtY=",
254260
"path": "github.com/spf13/cobra",

0 commit comments

Comments
 (0)