Skip to content

Commit 9e5eed1

Browse files
authored
Merge pull request #161 from Avanade/sprint-36
Sprint 36
2 parents 188f833 + 4968bc8 commit 9e5eed1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+907
-1455
lines changed

.bicep/webapp/parameters.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@
4343
"LINK_FOOTERS": "",
4444
"ORGANIZATION_NAME": "",
4545
"COMMUNITY_PORTAL_APP_ID": "",
46-
"CALLBACK_RETRY_FREQ": ""
46+
"CALLBACK_RETRY_FREQ": "",
47+
"SESSION_KEY": "",
48+
"SCOPE":""
4749
}
4850
}
4951
}

.github/workflows/setup-appservice-resource.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ jobs:
4747
parameters.appServiceSettings.value.APPROVALSYSTEMDB_CONNECTION_STRING : ${{ secrets.DATABASE_CONNECTION_STRING }}
4848
parameters.appServiceSettings.value.COMMUNITY_PORTAL_APP_ID : ${{ vars.COMMUNITY_PORTAL_APP_ID }}
4949
parameters.appServiceSettings.value.CALLBACK_RETRY_FREQ: ${{ vars.CALLBACK_RETRY_FREQ }}
50+
parameters.appServiceSettings.value.SESSION_KEY: ${{ secrets.SESSION_KEY }}
51+
parameters.appServiceSettings.value.SCOPE: ${{ secrets.SCOPE}}
5052

5153
- name: Deploy App Service Plan and Web App
5254
uses: azure/arm-deploy@v1

src/goapp/.env.template

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,6 @@ EMAIL_ENABLED=<Email enabled. default: false>
1717
EMAIL_USER_ID=<Email user id>
1818
LINK_FOOTERS=""
1919
ORGANIZATION_NAME=""
20-
COMMUNITY_PORTAL_APP_ID=""
20+
COMMUNITY_PORTAL_APP_ID=""
21+
SESSION_KEY=""
22+
SCOPE=""

src/goapp/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM golang:1-buster
1+
FROM golang:1.23.2-bookworm
22

33
# Set the Current Working Directory inside the container
44
WORKDIR /goapp

src/goapp/config/config.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ type ConfigManager interface {
1313
GetEmailClientID() string
1414
GetEmailClientSecret() string
1515
GetEmailUserID() string
16+
GetHomeURL() string
1617
GetIsEmailEnabled() bool
1718
GetTenantID() string
1819
GetClientID() string
@@ -21,4 +22,7 @@ type ConfigManager interface {
2122
GetOrganizationName() string
2223
GetCommunityPortalAppId() string
2324
GetCallbackRetryFreq() string
25+
GetPort() string
26+
GetSessionKey() string
27+
GetScope() string
2428
}

src/goapp/config/env-config.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ func (ecm *envConfigManager) GetEmailUserID() string {
5151
return os.Getenv("EMAIL_USER_ID")
5252
}
5353

54+
func (ecm *envConfigManager) GetHomeURL() string {
55+
return os.Getenv("HOME_URL")
56+
}
57+
5458
func (ecm *envConfigManager) GetIsEmailEnabled() bool {
5559
return os.Getenv("EMAIL_ENABLED") == "true"
5660
}
@@ -82,3 +86,15 @@ func (ecm *envConfigManager) GetCommunityPortalAppId() string {
8286
func (ecm *envConfigManager) GetCallbackRetryFreq() string {
8387
return os.Getenv("CALLBACK_RETRY_FREQ")
8488
}
89+
90+
func (ecm *envConfigManager) GetPort() string {
91+
return os.Getenv("PORT")
92+
}
93+
94+
func (ecm *envConfigManager) GetSessionKey() string {
95+
return os.Getenv("SESSION_KEY")
96+
}
97+
98+
func (ecm *envConfigManager) GetScope() string {
99+
return os.Getenv("SCOPE")
100+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package authentication
2+
3+
import (
4+
"net/http"
5+
)
6+
7+
type AuthenticationPageController interface {
8+
CallbackHandler(w http.ResponseWriter, r *http.Request)
9+
LoginHandler(w http.ResponseWriter, r *http.Request)
10+
LoginRedirectHandler(w http.ResponseWriter, r *http.Request)
11+
LogoutHandler(w http.ResponseWriter, r *http.Request)
12+
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package authentication
2+
3+
import (
4+
"crypto/rand"
5+
"encoding/base64"
6+
"html/template"
7+
"main/service"
8+
"net/http"
9+
)
10+
11+
type authenticationPageController struct {
12+
*service.Service
13+
}
14+
15+
func NewAuthenticationController(s *service.Service) AuthenticationPageController {
16+
return &authenticationPageController{
17+
Service: s,
18+
}
19+
}
20+
21+
func (a *authenticationPageController) CallbackHandler(w http.ResponseWriter, r *http.Request) {
22+
state, err := a.Authenticator.GetStringValue(r, "auth-session", "state")
23+
if err != nil {
24+
http.Error(w, err.Error(), http.StatusInternalServerError)
25+
return
26+
}
27+
28+
if r.URL.Query().Get("state") != state {
29+
http.Error(w, "Invalid state parameter", http.StatusBadRequest)
30+
return
31+
}
32+
33+
//Retrieve token and save data on session store
34+
u, err := a.Authenticator.ProcessToken(r.URL.Query().Get("code"))
35+
if err != nil {
36+
http.Error(w, err.Error(), http.StatusInternalServerError)
37+
return
38+
}
39+
40+
data := map[string]interface{}{
41+
"id_token": u.IdToken,
42+
"access": u.AccessToken,
43+
"profile": u.Profile,
44+
"refresh_token": u.RefreshToken,
45+
"expiry": u.Expiry,
46+
}
47+
48+
err = a.Authenticator.SaveOnSession(&w, r, "auth-session", data)
49+
50+
if err != nil {
51+
http.Error(w, err.Error(), http.StatusInternalServerError)
52+
return
53+
}
54+
55+
// Redirect to index
56+
http.Redirect(w, r, "/", http.StatusSeeOther)
57+
}
58+
59+
func (a *authenticationPageController) LoginHandler(w http.ResponseWriter, r *http.Request) {
60+
// Generate random state
61+
b := make([]byte, 32)
62+
_, err := rand.Read(b)
63+
64+
if err != nil {
65+
http.Error(w, err.Error(), http.StatusInternalServerError)
66+
return
67+
}
68+
state := base64.StdEncoding.EncodeToString(b)
69+
70+
data := map[string]interface{}{
71+
"state": state,
72+
}
73+
74+
err = a.Authenticator.SaveOnSession(&w, r, "auth-session", data)
75+
76+
if err != nil {
77+
http.Error(w, err.Error(), http.StatusInternalServerError)
78+
return
79+
}
80+
81+
http.Redirect(w, r, a.Authenticator.GetAuthCodeURL(state), http.StatusTemporaryRedirect)
82+
}
83+
84+
func (a *authenticationPageController) LoginRedirectHandler(w http.ResponseWriter, r *http.Request) {
85+
q := r.URL.Query()
86+
redirect := "/"
87+
if len(q["redirect"]) > 0 {
88+
redirect = q["redirect"][0]
89+
}
90+
data := map[string]interface{}{
91+
"redirect": redirect,
92+
}
93+
94+
c := http.Cookie{
95+
Name: "auth-session",
96+
MaxAge: -1}
97+
http.SetCookie(w, &c)
98+
99+
tmpl := template.Must(template.ParseFiles("templates/loginredirect.html"))
100+
tmpl.Execute(w, data)
101+
}
102+
103+
func (a *authenticationPageController) LogoutHandler(w http.ResponseWriter, r *http.Request) {
104+
err := a.Authenticator.ClearFromSession(&w, r, "auth-session")
105+
if err != nil {
106+
http.Error(w, err.Error(), http.StatusInternalServerError)
107+
}
108+
109+
url, err := a.Authenticator.GetLogoutURL()
110+
if err != nil {
111+
http.Error(w, err.Error(), http.StatusInternalServerError)
112+
return
113+
}
114+
115+
http.Redirect(w, r, url, http.StatusTemporaryRedirect)
116+
}

src/goapp/controller/controller.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,20 @@ package controller
33
import (
44
"main/config"
55
cApplicationModule "main/controller/app-module"
6+
cAuthentication "main/controller/authentication"
7+
cFallback "main/controller/fallback"
68
cItem "main/controller/item"
79
cUser "main/controller/user"
810
"main/service"
911
)
1012

1113
type Controller struct {
12-
Item cItem.ItemController
13-
ItemPage cItem.ItemPageController
14-
ApplicationModule cApplicationModule.ApplicationModuleController
15-
User cUser.UserController
14+
AuthenticationPage cAuthentication.AuthenticationPageController
15+
Item cItem.ItemController
16+
ItemPage cItem.ItemPageController
17+
ApplicationModule cApplicationModule.ApplicationModuleController
18+
User cUser.UserController
19+
Fallback cFallback.FallbackController
1620
}
1721

1822
type ControllerOptionFunc func(*Controller)
@@ -27,6 +31,12 @@ func NewController(opts ...ControllerOptionFunc) *Controller {
2731
return controller
2832
}
2933

34+
func NewAuthenticationController(svc *service.Service) ControllerOptionFunc {
35+
return func(c *Controller) {
36+
c.AuthenticationPage = cAuthentication.NewAuthenticationController(svc)
37+
}
38+
}
39+
3040
func NewItemController(svc *service.Service) ControllerOptionFunc {
3141
return func(c *Controller) {
3242
c.Item = cItem.NewItemController(svc)
@@ -52,3 +62,9 @@ func NewItemPageController(svc *service.Service, conf config.ConfigManager) Cont
5262
c.ItemPage = cItem.NewItemPageController(svc, conf)
5363
}
5464
}
65+
66+
func NewFallbackController(svc *service.Service) ControllerOptionFunc {
67+
return func(c *Controller) {
68+
c.Fallback = cFallback.NewFallbackController(svc)
69+
}
70+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package fallback
2+
3+
import "net/http"
4+
5+
type FallbackController interface {
6+
NotFound(w http.ResponseWriter, r *http.Request)
7+
}

0 commit comments

Comments
 (0)