aboutsummaryrefslogtreecommitdiff
path: root/app/controllers/api_credentials.go
diff options
context:
space:
mode:
Diffstat (limited to 'app/controllers/api_credentials.go')
-rw-r--r--app/controllers/api_credentials.go84
1 files changed, 75 insertions, 9 deletions
diff --git a/app/controllers/api_credentials.go b/app/controllers/api_credentials.go
index cd1a912..d53565e 100644
--- a/app/controllers/api_credentials.go
+++ b/app/controllers/api_credentials.go
@@ -1,7 +1,9 @@
1package controllers 1package controllers
2 2
3import ( 3import (
4 "bytes"
4 "net/http" 5 "net/http"
6 "text/template"
5 "time" 7 "time"
6 8
7 "code.crute.us/mcrute/cloud-identity-broker/cloud/aws" 9 "code.crute.us/mcrute/cloud-identity-broker/cloud/aws"
@@ -23,8 +25,33 @@ type jsonCredential struct {
23 SecretAccessKey *string `json:"secret_key"` 25 SecretAccessKey *string `json:"secret_key"`
24 SessionToken *string `json:"session_token"` 26 SessionToken *string `json:"session_token"`
25 Expiration *time.Time `json:"expiration"` 27 Expiration *time.Time `json:"expiration"`
28 ShortName string `json:"-"`
26} 29}
27 30
31var (
32 bashTemplate = template.Must(template.New("").Parse(
33 `export AWS_CREDS_EXPIRATION="{{ .Expiration }}"
34export AWS_ACCESS_KEY_ID="{{ .AccessKeyId }}"
35export AWS_SECRET_ACCESS_KEY="{{ .SecretAccessKey }}"
36export AWS_SESSION_TOKEN="{{ .SessionToken }}"
37`))
38
39 pslTemplate = template.Must(template.New("").Parse(
40 `Set-Item -path env:AWS_CREDS_EXPIRATION -value '{{ .Expiration }}'
41Set-Item -path env:AWS_ACCESS_KEY_ID -value '{{ .AccessKeyId }}'
42Set-Item -path env:AWS_SECRET_ACCESS_KEY -value '{{ .SecretAccessKey }}'
43Set-Item -path env:AWS_SESSION_TOKEN -value '{{ .SessionToken }}'
44`))
45
46 iniTemplate = template.Must(template.New("").Parse(
47 `[profile {{ .ShortName }}]
48aws_access_key_id={{ .AccessKeyId }}
49aws_secret_access_key={{ .SecretAccessKey }}
50aws_session_token={{ .SessionToken }}
51expiration={{ .Expiration }}
52`))
53)
54
28type APICredentialsHandler struct { 55type APICredentialsHandler struct {
29 *AWSAPI 56 *AWSAPI
30} 57}
@@ -32,29 +59,32 @@ type APICredentialsHandler struct {
32func NewAPICredentialsHandler(a *AWSAPI) echo.HandlerFunc { 59func NewAPICredentialsHandler(a *AWSAPI) echo.HandlerFunc {
33 al := &APICredentialsHandler{a} 60 al := &APICredentialsHandler{a}
34 h := &controller.ContentTypeNegotiatingHandler{ 61 h := &controller.ContentTypeNegotiatingHandler{
35 DefaultHandler: al.Handle, 62 DefaultHandler: al.HandleJSONV1,
36 Handlers: map[string]echo.HandlerFunc{ 63 Handlers: map[string]echo.HandlerFunc{
37 contentTypeV1: al.Handle, 64 contentTypeV1: al.HandleJSONV1,
38 contentTypeV2: al.Handle, 65 contentTypeV2: al.HandleJSONV1,
66 contentTypeV2AWSBash: al.HandleBashV2,
67 contentTypeV2AWSPowershell: al.HandlePSLV2,
68 contentTypeV2AWSConfig: al.HandleINIV2,
39 }, 69 },
40 } 70 }
41 return h.Handle 71 return h.Handle
42} 72}
43 73
44func (h *APICredentialsHandler) Handle(c echo.Context) error { 74func (h *APICredentialsHandler) getAWSCredential(c echo.Context) (*jsonCredential, error) {
45 rc, err := h.GetContext(c) // Does authorization checks 75 rc, err := h.GetContext(c) // Does authorization checks
46 if err != nil { 76 if err != nil {
47 return err 77 return nil, err
48 } 78 }
49 79
50 region := c.Param("region") 80 region := c.Param("region")
51 creds, err := rc.AWS.AssumeRole(rc.Principal.Username, &region) 81 creds, err := rc.AWS.AssumeRole(rc.Principal.Username, &region)
52 if err != nil { 82 if err != nil {
53 if aws.IsRegionNotExist(err) { 83 if aws.IsRegionNotExist(err) {
54 return echo.NotFoundHandler(c) 84 return nil, echo.NotFoundHandler(c)
55 } 85 }
56 c.Logger().Errorf("Error retrieving credentials: %w", err) 86 c.Logger().Errorf("Error retrieving credentials: %w", err)
57 return echo.ErrInternalServerError 87 return nil, echo.ErrInternalServerError
58 } 88 }
59 89
60 c.Logger().Infof( 90 c.Logger().Infof(
@@ -68,10 +98,46 @@ func (h *APICredentialsHandler) Handle(c echo.Context) error {
68 98
69 c.Response().Header().Set("Expires", creds.Expiration.Add(-5*time.Minute).Format(time.RFC1123)) 99 c.Response().Header().Set("Expires", creds.Expiration.Add(-5*time.Minute).Format(time.RFC1123))
70 100
71 return c.JSON(http.StatusOK, &jsonCredential{ 101 return &jsonCredential{
72 AccessKeyId: creds.AccessKeyId, 102 AccessKeyId: creds.AccessKeyId,
73 SecretAccessKey: creds.SecretAccessKey, 103 SecretAccessKey: creds.SecretAccessKey,
74 SessionToken: creds.SessionToken, 104 SessionToken: creds.SessionToken,
75 Expiration: creds.Expiration, 105 Expiration: creds.Expiration,
76 }) 106 ShortName: rc.Account.ShortName,
107 }, nil
108}
109
110func (h *APICredentialsHandler) renderTemplate(c echo.Context, t *template.Template, ct string) error {
111 creds, err := h.getAWSCredential(c)
112 if err != nil {
113 return err
114 }
115
116 buf := &bytes.Buffer{}
117 if err = t.Execute(buf, creds); err != nil {
118 return echo.ErrInternalServerError
119 }
120
121 return c.Blob(http.StatusOK, ct, buf.Bytes())
122}
123
124func (h *APICredentialsHandler) HandleJSONV1(c echo.Context) error {
125 creds, err := h.getAWSCredential(c)
126 if err != nil {
127 return err
128 }
129
130 return c.JSON(http.StatusOK, creds)
131}
132
133func (h *APICredentialsHandler) HandleBashV2(c echo.Context) error {
134 return h.renderTemplate(c, bashTemplate, contentTypeV2AWSBash)
135}
136
137func (h *APICredentialsHandler) HandlePSLV2(c echo.Context) error {
138 return h.renderTemplate(c, pslTemplate, contentTypeV2AWSPowershell)
139}
140
141func (h *APICredentialsHandler) HandleINIV2(c echo.Context) error {
142 return h.renderTemplate(c, iniTemplate, contentTypeV2AWSConfig)
77} 143}