Skip to content

Commit

Permalink
Merge pull request #161 from Avanade/sprint-36
Browse files Browse the repository at this point in the history
Sprint 36
  • Loading branch information
iibuan authored Oct 31, 2024
2 parents 188f833 + 4968bc8 commit 9e5eed1
Show file tree
Hide file tree
Showing 53 changed files with 907 additions and 1,455 deletions.
4 changes: 3 additions & 1 deletion .bicep/webapp/parameters.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@
"LINK_FOOTERS": "",
"ORGANIZATION_NAME": "",
"COMMUNITY_PORTAL_APP_ID": "",
"CALLBACK_RETRY_FREQ": ""
"CALLBACK_RETRY_FREQ": "",
"SESSION_KEY": "",
"SCOPE":""
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/setup-appservice-resource.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ jobs:
parameters.appServiceSettings.value.APPROVALSYSTEMDB_CONNECTION_STRING : ${{ secrets.DATABASE_CONNECTION_STRING }}
parameters.appServiceSettings.value.COMMUNITY_PORTAL_APP_ID : ${{ vars.COMMUNITY_PORTAL_APP_ID }}
parameters.appServiceSettings.value.CALLBACK_RETRY_FREQ: ${{ vars.CALLBACK_RETRY_FREQ }}
parameters.appServiceSettings.value.SESSION_KEY: ${{ secrets.SESSION_KEY }}
parameters.appServiceSettings.value.SCOPE: ${{ secrets.SCOPE}}

- name: Deploy App Service Plan and Web App
uses: azure/arm-deploy@v1
Expand Down
4 changes: 3 additions & 1 deletion src/goapp/.env.template
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ EMAIL_ENABLED=<Email enabled. default: false>
EMAIL_USER_ID=<Email user id>
LINK_FOOTERS=""
ORGANIZATION_NAME=""
COMMUNITY_PORTAL_APP_ID=""
COMMUNITY_PORTAL_APP_ID=""
SESSION_KEY=""
SCOPE=""
2 changes: 1 addition & 1 deletion src/goapp/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1-buster
FROM golang:1.23.2-bookworm

# Set the Current Working Directory inside the container
WORKDIR /goapp
Expand Down
4 changes: 4 additions & 0 deletions src/goapp/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type ConfigManager interface {
GetEmailClientID() string
GetEmailClientSecret() string
GetEmailUserID() string
GetHomeURL() string
GetIsEmailEnabled() bool
GetTenantID() string
GetClientID() string
Expand All @@ -21,4 +22,7 @@ type ConfigManager interface {
GetOrganizationName() string
GetCommunityPortalAppId() string
GetCallbackRetryFreq() string
GetPort() string
GetSessionKey() string
GetScope() string
}
16 changes: 16 additions & 0 deletions src/goapp/config/env-config.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ func (ecm *envConfigManager) GetEmailUserID() string {
return os.Getenv("EMAIL_USER_ID")
}

func (ecm *envConfigManager) GetHomeURL() string {
return os.Getenv("HOME_URL")
}

func (ecm *envConfigManager) GetIsEmailEnabled() bool {
return os.Getenv("EMAIL_ENABLED") == "true"
}
Expand Down Expand Up @@ -82,3 +86,15 @@ func (ecm *envConfigManager) GetCommunityPortalAppId() string {
func (ecm *envConfigManager) GetCallbackRetryFreq() string {
return os.Getenv("CALLBACK_RETRY_FREQ")
}

func (ecm *envConfigManager) GetPort() string {
return os.Getenv("PORT")
}

func (ecm *envConfigManager) GetSessionKey() string {
return os.Getenv("SESSION_KEY")
}

func (ecm *envConfigManager) GetScope() string {
return os.Getenv("SCOPE")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package authentication

import (
"net/http"
)

type AuthenticationPageController interface {
CallbackHandler(w http.ResponseWriter, r *http.Request)
LoginHandler(w http.ResponseWriter, r *http.Request)
LoginRedirectHandler(w http.ResponseWriter, r *http.Request)
LogoutHandler(w http.ResponseWriter, r *http.Request)
}
116 changes: 116 additions & 0 deletions src/goapp/controller/authentication/authentication-page-controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package authentication

import (
"crypto/rand"
"encoding/base64"
"html/template"
"main/service"
"net/http"
)

type authenticationPageController struct {
*service.Service
}

func NewAuthenticationController(s *service.Service) AuthenticationPageController {
return &authenticationPageController{
Service: s,
}
}

func (a *authenticationPageController) CallbackHandler(w http.ResponseWriter, r *http.Request) {
state, err := a.Authenticator.GetStringValue(r, "auth-session", "state")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

if r.URL.Query().Get("state") != state {
http.Error(w, "Invalid state parameter", http.StatusBadRequest)
return
}

//Retrieve token and save data on session store
u, err := a.Authenticator.ProcessToken(r.URL.Query().Get("code"))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

data := map[string]interface{}{
"id_token": u.IdToken,
"access": u.AccessToken,
"profile": u.Profile,
"refresh_token": u.RefreshToken,
"expiry": u.Expiry,
}

err = a.Authenticator.SaveOnSession(&w, r, "auth-session", data)

if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

// Redirect to index
http.Redirect(w, r, "/", http.StatusSeeOther)
}

func (a *authenticationPageController) LoginHandler(w http.ResponseWriter, r *http.Request) {
// Generate random state
b := make([]byte, 32)
_, err := rand.Read(b)

if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
state := base64.StdEncoding.EncodeToString(b)

data := map[string]interface{}{
"state": state,
}

err = a.Authenticator.SaveOnSession(&w, r, "auth-session", data)

if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

http.Redirect(w, r, a.Authenticator.GetAuthCodeURL(state), http.StatusTemporaryRedirect)
}

func (a *authenticationPageController) LoginRedirectHandler(w http.ResponseWriter, r *http.Request) {
q := r.URL.Query()
redirect := "/"
if len(q["redirect"]) > 0 {
redirect = q["redirect"][0]
}
data := map[string]interface{}{
"redirect": redirect,
}

c := http.Cookie{
Name: "auth-session",
MaxAge: -1}
http.SetCookie(w, &c)

tmpl := template.Must(template.ParseFiles("templates/loginredirect.html"))
tmpl.Execute(w, data)
}

func (a *authenticationPageController) LogoutHandler(w http.ResponseWriter, r *http.Request) {
err := a.Authenticator.ClearFromSession(&w, r, "auth-session")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}

url, err := a.Authenticator.GetLogoutURL()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

http.Redirect(w, r, url, http.StatusTemporaryRedirect)
}
24 changes: 20 additions & 4 deletions src/goapp/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@ package controller
import (
"main/config"
cApplicationModule "main/controller/app-module"
cAuthentication "main/controller/authentication"
cFallback "main/controller/fallback"
cItem "main/controller/item"
cUser "main/controller/user"
"main/service"
)

type Controller struct {
Item cItem.ItemController
ItemPage cItem.ItemPageController
ApplicationModule cApplicationModule.ApplicationModuleController
User cUser.UserController
AuthenticationPage cAuthentication.AuthenticationPageController
Item cItem.ItemController
ItemPage cItem.ItemPageController
ApplicationModule cApplicationModule.ApplicationModuleController
User cUser.UserController
Fallback cFallback.FallbackController
}

type ControllerOptionFunc func(*Controller)
Expand All @@ -27,6 +31,12 @@ func NewController(opts ...ControllerOptionFunc) *Controller {
return controller
}

func NewAuthenticationController(svc *service.Service) ControllerOptionFunc {
return func(c *Controller) {
c.AuthenticationPage = cAuthentication.NewAuthenticationController(svc)
}
}

func NewItemController(svc *service.Service) ControllerOptionFunc {
return func(c *Controller) {
c.Item = cItem.NewItemController(svc)
Expand All @@ -52,3 +62,9 @@ func NewItemPageController(svc *service.Service, conf config.ConfigManager) Cont
c.ItemPage = cItem.NewItemPageController(svc, conf)
}
}

func NewFallbackController(svc *service.Service) ControllerOptionFunc {
return func(c *Controller) {
c.Fallback = cFallback.NewFallbackController(svc)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package fallback

import "net/http"

type FallbackController interface {
NotFound(w http.ResponseWriter, r *http.Request)
}
30 changes: 30 additions & 0 deletions src/goapp/controller/fallback/fallback-page-controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package fallback

import (
"main/service"
"net/http"
)

type fallbackController struct {
*service.Service
}

func NewFallbackController(s *service.Service) FallbackController {
return &fallbackController{
Service: s,
}
}

func (c *fallbackController) NotFound(w http.ResponseWriter, r *http.Request) {
user, err := c.Authenticator.GetAuthenticatedUser(r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

t, d := c.Service.Template.UseTemplate("NotFound", r.URL.Path, *user, nil)
err = t.Execute(w, d)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
Loading

0 comments on commit 9e5eed1

Please sign in to comment.