aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Crute <mike@crute.us>2021-11-24 21:58:09 -0800
committerMike Crute <mike@crute.us>2021-11-24 22:11:12 -0800
commite5629fb163c7cf303438afc5be6075299cfc6071 (patch)
tree0f835aa20df3e93d93358810566ab9986db35eaa
parent09fa11a1dad5301e8e0aeb069fc1d11312b4a1c5 (diff)
downloadcloud-identity-broker-e5629fb163c7cf303438afc5be6075299cfc6071.tar.bz2
cloud-identity-broker-e5629fb163c7cf303438afc5be6075299cfc6071.tar.xz
cloud-identity-broker-e5629fb163c7cf303438afc5be6075299cfc6071.zip
Extract URL building logic
-rw-r--r--app/controllers/api.go8
-rw-r--r--app/controllers/api_account.go3
-rw-r--r--app/controllers/api_account_list.go14
-rw-r--r--app/controllers/api_region_list.go13
-rw-r--r--app/controllers/api_user.go3
-rw-r--r--app/controllers/api_user_list.go4
-rw-r--r--app/urls.go51
-rw-r--r--cmd/web/server.go8
8 files changed, 82 insertions, 22 deletions
diff --git a/app/controllers/api.go b/app/controllers/api.go
index 39fc227..0820584 100644
--- a/app/controllers/api.go
+++ b/app/controllers/api.go
@@ -3,9 +3,9 @@ package controllers
3import ( 3import (
4 "net/http" 4 "net/http"
5 5
6 "code.crute.us/mcrute/cloud-identity-broker/app"
6 "code.crute.us/mcrute/cloud-identity-broker/app/middleware" 7 "code.crute.us/mcrute/cloud-identity-broker/app/middleware"
7 8
8 glecho "code.crute.us/mcrute/golib/echo"
9 "github.com/labstack/echo/v4" 9 "github.com/labstack/echo/v4"
10) 10)
11 11
@@ -23,12 +23,14 @@ func APIIndexHandler(c echo.Context) error {
23 return echo.ErrUnauthorized 23 return echo.ErrUnauthorized
24 } 24 }
25 25
26 au := app.AppURL{}
27
26 out := map[string]string{ 28 out := map[string]string{
27 "accounts": glecho.URLFor(c, "/api/account").String(), 29 "accounts": au.Account(c, "", nil),
28 } 30 }
29 31
30 if p.IsAdmin { 32 if p.IsAdmin {
31 out["users"] = glecho.URLFor(c, "/api/user").String() 33 out["users"] = au.User(c, nil)
32 } 34 }
33 35
34 return c.JSON(http.StatusOK, out) 36 return c.JSON(http.StatusOK, out)
diff --git a/app/controllers/api_account.go b/app/controllers/api_account.go
index f22191d..815daf4 100644
--- a/app/controllers/api_account.go
+++ b/app/controllers/api_account.go
@@ -6,6 +6,7 @@ import (
6 "net/http" 6 "net/http"
7 "time" 7 "time"
8 8
9 "code.crute.us/mcrute/cloud-identity-broker/app"
9 "code.crute.us/mcrute/cloud-identity-broker/app/middleware" 10 "code.crute.us/mcrute/cloud-identity-broker/app/middleware"
10 "code.crute.us/mcrute/cloud-identity-broker/app/models" 11 "code.crute.us/mcrute/cloud-identity-broker/app/models"
11 "code.crute.us/mcrute/cloud-identity-broker/cloud/aws" 12 "code.crute.us/mcrute/cloud-identity-broker/cloud/aws"
@@ -191,7 +192,7 @@ func (h *APIAccountHandler) HandlePost(c echo.Context) error {
191 return echo.ErrInternalServerError 192 return echo.ErrInternalServerError
192 } 193 }
193 194
194 c.Response().Header().Add("Location", glecho.URLFor(c, "/api/account", in.ShortName).String()) 195 c.Response().Header().Add("Location", app.AppURL{}.Account(c, "aws", &in.ShortName))
195 196
196 return c.String(http.StatusCreated, "") 197 return c.String(http.StatusCreated, "")
197} 198}
diff --git a/app/controllers/api_account_list.go b/app/controllers/api_account_list.go
index 28b64c1..4835d0c 100644
--- a/app/controllers/api_account_list.go
+++ b/app/controllers/api_account_list.go
@@ -4,10 +4,10 @@ import (
4 "context" 4 "context"
5 "net/http" 5 "net/http"
6 6
7 "code.crute.us/mcrute/cloud-identity-broker/app"
7 "code.crute.us/mcrute/cloud-identity-broker/app/middleware" 8 "code.crute.us/mcrute/cloud-identity-broker/app/middleware"
8 "code.crute.us/mcrute/cloud-identity-broker/app/models" 9 "code.crute.us/mcrute/cloud-identity-broker/app/models"
9 10
10 glecho "code.crute.us/mcrute/golib/echo"
11 "code.crute.us/mcrute/golib/echo/controller" 11 "code.crute.us/mcrute/golib/echo/controller"
12 "github.com/labstack/echo/v4" 12 "github.com/labstack/echo/v4"
13) 13)
@@ -25,15 +25,17 @@ type jsonAccount struct {
25} 25}
26 26
27func jsonAccountFromAccount(c echo.Context, a *models.Account) *jsonAccount { 27func jsonAccountFromAccount(c echo.Context, a *models.Account) *jsonAccount {
28 u := app.AppURL{}
29
28 return &jsonAccount{ 30 return &jsonAccount{
29 AccountNumber: a.AccountNumber, 31 AccountNumber: a.AccountNumber,
30 ShortName: a.ShortName, 32 ShortName: a.ShortName,
31 Name: a.Name, 33 Name: a.Name,
32 SelfUrl: glecho.URLFor(c, "/api/account", a.ShortName).String(), 34 SelfUrl: u.Account(c, "aws", &a.ShortName),
33 ConsoleUrl: glecho.URLFor(c, "/api/account", a.ShortName, "console").String(), 35 ConsoleUrl: u.AccountConsole(c, "aws", a.ShortName, false),
34 ConsoleRedirectUrl: glecho.URLFor(c, "/api/account", a.ShortName, "console").Query("redirect", "1").String(), 36 ConsoleRedirectUrl: u.AccountConsole(c, "aws", a.ShortName, true),
35 CredentialsUrl: glecho.URLFor(c, "/api/account", a.ShortName, "credentials").String(), 37 CredentialsUrl: u.AccountCredentials(c, "aws", a.ShortName, ""),
36 GlobalCredentialsUrl: glecho.URLFor(c, "/api/account", a.ShortName, "credentials/global").String(), 38 GlobalCredentialsUrl: u.AccountCredentials(c, "aws", a.ShortName, "global"),
37 } 39 }
38} 40}
39 41
diff --git a/app/controllers/api_region_list.go b/app/controllers/api_region_list.go
index 44d591c..c34ac3a 100644
--- a/app/controllers/api_region_list.go
+++ b/app/controllers/api_region_list.go
@@ -3,7 +3,7 @@ package controllers
3import ( 3import (
4 "net/http" 4 "net/http"
5 5
6 glecho "code.crute.us/mcrute/golib/echo" 6 "code.crute.us/mcrute/cloud-identity-broker/app"
7 "code.crute.us/mcrute/golib/echo/controller" 7 "code.crute.us/mcrute/golib/echo/controller"
8 "github.com/labstack/echo/v4" 8 "github.com/labstack/echo/v4"
9) 9)
@@ -17,10 +17,14 @@ type jsonRegion struct {
17 17
18type APIRegionListHandler struct { 18type APIRegionListHandler struct {
19 *AWSAPI 19 *AWSAPI
20 urls app.AppURL
20} 21}
21 22
22func NewAPIRegionListHandler(a *AWSAPI) echo.HandlerFunc { 23func NewAPIRegionListHandler(a *AWSAPI) echo.HandlerFunc {
23 al := &APIRegionListHandler{a} 24 al := &APIRegionListHandler{
25 AWSAPI: a,
26 urls: app.AppURL{},
27 }
24 h := &controller.ContentTypeNegotiatingHandler{ 28 h := &controller.ContentTypeNegotiatingHandler{
25 DefaultHandler: al.Handle, 29 DefaultHandler: al.Handle,
26 Handlers: map[string]echo.HandlerFunc{ 30 Handlers: map[string]echo.HandlerFunc{
@@ -52,9 +56,8 @@ func (h *APIRegionListHandler) Handle(c echo.Context) error {
52 Default: rc.Account.DefaultRegion == r.Name, 56 Default: rc.Account.DefaultRegion == r.Name,
53 } 57 }
54 if r.Enabled { 58 if r.Enabled {
55 out[i].CredentialsURL = glecho.URLFor(c, 59 out[i].CredentialsURL = h.urls.AccountCredentials(
56 "/api/account", rc.Account.ShortName, "credentials", r.Name, 60 c, "aws", rc.Account.ShortName, r.Name)
57 ).String()
58 } 61 }
59 } 62 }
60 63
diff --git a/app/controllers/api_user.go b/app/controllers/api_user.go
index e55d88d..b024ffd 100644
--- a/app/controllers/api_user.go
+++ b/app/controllers/api_user.go
@@ -4,6 +4,7 @@ import (
4 "context" 4 "context"
5 "net/http" 5 "net/http"
6 6
7 "code.crute.us/mcrute/cloud-identity-broker/app"
7 "code.crute.us/mcrute/cloud-identity-broker/app/models" 8 "code.crute.us/mcrute/cloud-identity-broker/app/models"
8 9
9 glecho "code.crute.us/mcrute/golib/echo" 10 glecho "code.crute.us/mcrute/golib/echo"
@@ -152,7 +153,7 @@ func (h *APIUserHandler) HandlePost(c echo.Context) error {
152 return echo.ErrInternalServerError 153 return echo.ErrInternalServerError
153 } 154 }
154 155
155 c.Response().Header().Add("Location", glecho.URLFor(c, "/api/user", in.Username).String()) 156 c.Response().Header().Add("Location", app.AppURL{}.User(c, &in.Username))
156 157
157 return c.String(http.StatusCreated, "") 158 return c.String(http.StatusCreated, "")
158} 159}
diff --git a/app/controllers/api_user_list.go b/app/controllers/api_user_list.go
index c753093..415517d 100644
--- a/app/controllers/api_user_list.go
+++ b/app/controllers/api_user_list.go
@@ -5,9 +5,9 @@ import (
5 "net/http" 5 "net/http"
6 "time" 6 "time"
7 7
8 "code.crute.us/mcrute/cloud-identity-broker/app"
8 "code.crute.us/mcrute/cloud-identity-broker/app/models" 9 "code.crute.us/mcrute/cloud-identity-broker/app/models"
9 10
10 glecho "code.crute.us/mcrute/golib/echo"
11 "code.crute.us/mcrute/golib/echo/controller" 11 "code.crute.us/mcrute/golib/echo/controller"
12 "github.com/labstack/echo/v4" 12 "github.com/labstack/echo/v4"
13) 13)
@@ -47,7 +47,7 @@ func (h *APIUserListHandler) Handle(c echo.Context) error {
47 Username: v.Username, 47 Username: v.Username,
48 IsAdmin: v.IsAdmin, 48 IsAdmin: v.IsAdmin,
49 IsService: v.IsService, 49 IsService: v.IsService,
50 SelfLink: glecho.URLFor(c, "/api/user", v.Username).String(), 50 SelfLink: app.AppURL{}.User(c, &v.Username),
51 Deleted: v.Deleted, 51 Deleted: v.Deleted,
52 } 52 }
53 } 53 }
diff --git a/app/urls.go b/app/urls.go
new file mode 100644
index 0000000..8cceb37
--- /dev/null
+++ b/app/urls.go
@@ -0,0 +1,51 @@
1package app
2
3import (
4 glecho "code.crute.us/mcrute/golib/echo"
5 "github.com/labstack/echo/v4"
6)
7
8// AppURL is an interface to building URLs to the application. This exists
9// because the Echo reverse URL functionality requires keeping references to
10// handler functions for the ability to reverse URLs which doesn't work at all
11// for the structure of this application. This interface is effectively named
12// URLs. If Echo supports named URLs in the future this struct can be removed.
13type AppURL struct{}
14
15func (u AppURL) Account(c echo.Context, provider string, shortName *string) string {
16 parts := []string{"/api/account"}
17
18 if provider != "" {
19 parts = append(parts, provider)
20 }
21
22 if shortName != nil {
23 parts = append(parts, *shortName)
24 }
25
26 return glecho.URLFor(c, parts...).String()
27}
28
29func (u AppURL) User(c echo.Context, username *string) string {
30 if username != nil {
31 return glecho.URLFor(c, "/api/user", *username).String()
32 } else {
33 return glecho.URLFor(c, "/api/user").String()
34 }
35}
36
37func (u AppURL) AccountConsole(c echo.Context, provider, shortName string, redir bool) string {
38 au := glecho.URLFor(c, "/api/account", provider, shortName, "console")
39 if redir {
40 au = au.Query("redirect", "1")
41 }
42 return au.String()
43}
44
45func (u AppURL) AccountCredentials(c echo.Context, provider, shortName string, region string) string {
46 if region != "" {
47 return glecho.URLFor(c, "/api/account", provider, shortName, "credentials", region).String()
48 } else {
49 return glecho.URLFor(c, "/api/account", provider, shortName, "credentials").String()
50 }
51}
diff --git a/cmd/web/server.go b/cmd/web/server.go
index 9f750bc..610cc72 100644
--- a/cmd/web/server.go
+++ b/cmd/web/server.go
@@ -143,23 +143,23 @@ func webMain(cfg app.Config, embeddedTemplates fs.FS, version string) {
143 { 143 {
144 account.GET("", controllers.NewAPIAccountListHandler(as)) 144 account.GET("", controllers.NewAPIAccountListHandler(as))
145 account.GET( 145 account.GET(
146 "/:account/credentials", 146 "/:provider/:account/credentials",
147 controllers.NewAPIRegionListHandler(aws), 147 controllers.NewAPIRegionListHandler(aws),
148 ) 148 )
149 account.GET( 149 account.GET(
150 "/:account/console", 150 "/:provider/:account/console",
151 controllers.NewAPIConsoleRedirectHandler(aws, cfg.IssuerEndpoint), 151 controllers.NewAPIConsoleRedirectHandler(aws, cfg.IssuerEndpoint),
152 rateLimit, 152 rateLimit,
153 ) 153 )
154 account.GET( 154 account.GET(
155 "/:account/credentials/:region", 155 "/:provider/:account/credentials/:region",
156 controllers.NewAPICredentialsHandler(aws), 156 controllers.NewAPICredentialsHandler(aws),
157 rateLimit, 157 rateLimit,
158 ) 158 )
159 (&controllers.APIAccountHandler{ 159 (&controllers.APIAccountHandler{
160 Store: as, 160 Store: as,
161 AdminStore: adminAccountStore, 161 AdminStore: adminAccountStore,
162 }).Register("/:account", "", account) 162 }).Register("/:provider/:account", "", account)
163 } 163 }
164 164
165 user := api.Group("/user") 165 user := api.Group("/user")