aboutsummaryrefslogtreecommitdiff
path: root/app/controllers/api_account_list.go
diff options
context:
space:
mode:
Diffstat (limited to 'app/controllers/api_account_list.go')
-rw-r--r--app/controllers/api_account_list.go109
1 files changed, 109 insertions, 0 deletions
diff --git a/app/controllers/api_account_list.go b/app/controllers/api_account_list.go
new file mode 100644
index 0000000..f69db6a
--- /dev/null
+++ b/app/controllers/api_account_list.go
@@ -0,0 +1,109 @@
1package controllers
2
3import (
4 "context"
5 "net/http"
6
7 "code.crute.us/mcrute/cloud-identity-broker/app/middleware"
8 "code.crute.us/mcrute/cloud-identity-broker/app/models"
9
10 glecho "code.crute.us/mcrute/golib/echo"
11 "code.crute.us/mcrute/golib/echo/controller"
12 "github.com/labstack/echo/v4"
13)
14
15type jsonAccount struct {
16 Vendor string `json:"vendor,omitempty"`
17 AccountNumber int `json:"account_number"`
18 ShortName string `json:"short_name"`
19 Name string `json:"name"`
20 ConsoleUrl string `json:"get_console_url,omitempty"`
21 ConsoleRedirectUrl string `json:"console_redirect_url,omitempty"`
22 CredentialsUrl string `json:"credentials_url"`
23 GlobalCredentialsUrl string `json:"global_credential_url,omitempty"`
24}
25
26func jsonAccountFromAccount(c echo.Context, a *models.Account) *jsonAccount {
27 return &jsonAccount{
28 AccountNumber: a.AccountNumber,
29 ShortName: a.ShortName,
30 Name: a.Name,
31 ConsoleUrl: glecho.URLFor(c, "/api/account", a.ShortName, "console").String(),
32 ConsoleRedirectUrl: glecho.URLFor(c, "/api/account", a.ShortName, "console").Query("redirect", "1").String(),
33 CredentialsUrl: glecho.URLFor(c, "/api/account", a.ShortName, "credentials").String(),
34 GlobalCredentialsUrl: glecho.URLFor(c, "/api/account", a.ShortName, "credentials/global").String(),
35 }
36}
37
38type APIAccountListHandler struct {
39 store models.AccountStore
40}
41
42func NewAPIAccountListHandler(s models.AccountStore) echo.HandlerFunc {
43 al := &APIAccountListHandler{store: s}
44 h := &controller.ContentTypeNegotiatingHandler{
45 DefaultHandler: al.HandleV1,
46 Handlers: map[string]echo.HandlerFunc{
47 contentTypeV1: al.HandleV1,
48 contentTypeV2: al.HandleV2,
49 },
50 }
51 return h.Handle
52}
53
54// getAccountList returns the account list. This does the same work that
55// GetContext would do for most AWSAPI handlers but is a little different
56// because it deals with lists of accounts.
57//
58// Authorization of the account is handled within the store. The store will not
59// return accounts for which the user does not have access.
60func (h *APIAccountListHandler) getAccountList(c echo.Context) ([]*models.Account, error) {
61 principal, err := middleware.GetAuthorizedPrincipal(c)
62 if err != nil {
63 return nil, echo.ErrUnauthorized
64 }
65
66 accounts, err := h.store.ListForUser(context.Background(), principal)
67 if err != nil {
68 c.Logger().Errorf("Unable to load account list: %w", err)
69 return nil, echo.ErrInternalServerError
70 }
71
72 return accounts, nil
73}
74
75// HandleV1 returns a list of JSON account objects
76func (h *APIAccountListHandler) HandleV1(c echo.Context) error {
77 accounts, err := h.getAccountList(c)
78 if err != nil {
79 return err
80 }
81
82 out := []*jsonAccount{}
83 for _, a := range accounts {
84 ja := jsonAccountFromAccount(c, a)
85 ja.Vendor = "aws"
86 out = append(out, ja)
87 }
88
89 return c.JSON(http.StatusOK, out)
90}
91
92// HandleV2 returns a map of lists of account objects. the key to the map is
93// the short name of the cloud provider.
94func (h *APIAccountListHandler) HandleV2(c echo.Context) error {
95 accounts, err := h.getAccountList(c)
96 if err != nil {
97 return err
98 }
99
100 out := map[string][]*jsonAccount{
101 "aws": []*jsonAccount{},
102 }
103 for _, a := range accounts {
104 ja := jsonAccountFromAccount(c, a)
105 out["aws"] = append(out["aws"], ja)
106 }
107
108 return c.JSON(http.StatusOK, out)
109}