From bb2540a5c468d159157348f09e58114b6bc99c16 Mon Sep 17 00:00:00 2001 From: Bagas Aulia Rezki Date: Thu, 2 May 2024 21:02:50 +0700 Subject: [PATCH] Optimize session retrieval and fix Docker timezone issue --- Dockerfile | 5 +++- handler/user/user.go | 2 +- middleware/middleware.go | 7 ++++-- session/session.go | 53 +++++++++++++++++++++++----------------- 4 files changed, 41 insertions(+), 26 deletions(-) diff --git a/Dockerfile b/Dockerfile index 03f6a35..70cd683 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,7 +19,7 @@ COPY --from=node_builder /src/public /src/public COPY --from=node_builder /src/public/upload_obfuscated.js /src/public/upload.js COPY --from=node_builder /src/public/validatePassword_obfuscated.js /src/public/validatePassword.js -RUN apk update && apk upgrade && apk add --no-cache ca-certificates +RUN apk update && apk upgrade && apk add --no-cache ca-certificates tzdata RUN update-ca-certificates RUN go install github.com/a-h/templ/cmd/templ@$(go list -m -f '{{ .Version }}' github.com/a-h/templ) RUN templ generate @@ -30,9 +30,12 @@ FROM scratch WORKDIR /src +COPY --from=go_builder /usr/share/zoneinfo /usr/share/zoneinfo COPY --from=go_builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ COPY --from=go_builder /src/schema.sql /src COPY --from=go_builder /src/public /src/public COPY --from=go_builder /src/tmp/main /src +ENV TZ Asia/Jakarta + ENTRYPOINT ["./main"] diff --git a/handler/user/user.go b/handler/user/user.go index abe001d..755ae78 100644 --- a/handler/user/user.go +++ b/handler/user/user.go @@ -17,7 +17,7 @@ func init() { func GET(w http.ResponseWriter, r *http.Request) { userSession := r.Context().Value("user").(types.User) - component := userView.Main("User Page", userSession.Email, userSession.Username, session.UserSessionInfoList[userSession.Email]) + component := userView.Main("User Page", userSession.Email, userSession.Username, session.GetSessions(userSession.Email)) err := component.Render(r.Context(), w) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) diff --git a/middleware/middleware.go b/middleware/middleware.go index e58582b..90a2f4a 100644 --- a/middleware/middleware.go +++ b/middleware/middleware.go @@ -59,10 +59,13 @@ func Handler(next http.Handler) http.Handler { } func Auth(next http.HandlerFunc, w http.ResponseWriter, r *http.Request) { - status, user := session.GetSession(r) + status, user, sessionID := session.GetSession(r) switch status { case session.Authorized: + userSession := session.GetSessionInfo(user.Email, sessionID) + userSession.UpdateAccessTime() + ctx := context.WithValue(r.Context(), "user", user) req := r.WithContext(ctx) r.Context().Value("user") @@ -94,7 +97,7 @@ func Auth(next http.HandlerFunc, w http.ResponseWriter, r *http.Request) { } func Guest(next http.HandlerFunc, w http.ResponseWriter, r *http.Request) { - status, _ := session.GetSession(r) + status, _, _ := session.GetSession(r) switch status { case session.Authorized: diff --git a/session/session.go b/session/session.go index abc1574..a4a07f4 100644 --- a/session/session.go +++ b/session/session.go @@ -40,10 +40,8 @@ const ( InvalidSession UserStatus = "invalid_session" ) -type SessionInfoList map[string][]*SessionInfo - var GlobalSessionStore = SessionStore{Sessions: make(map[string]*Session)} -var UserSessionInfoList = make(SessionInfoList) +var UserSessionInfoList = make(map[string]map[string]*SessionInfo) type SessionNotFoundError struct{} @@ -95,22 +93,22 @@ func (s *Session) Destroy(w http.ResponseWriter) { } func AddSessionInfo(email string, sessionInfo *SessionInfo) { - UserSessionInfoList[email] = append(UserSessionInfoList[email], sessionInfo) + if _, ok := UserSessionInfoList[email]; !ok { + UserSessionInfoList[email] = make(map[string]*SessionInfo) + } + + UserSessionInfoList[email][sessionInfo.SessionID] = sessionInfo } func RemoveSessionInfo(email string, id string) { - sessionInfos := UserSessionInfoList[email] - var updatedSessionInfos []*SessionInfo - for _, sessionInfo := range sessionInfos { - if sessionInfo.SessionID != id { - updatedSessionInfos = append(updatedSessionInfos, sessionInfo) + if userSessions, ok := UserSessionInfoList[email]; ok { + if _, ok := userSessions[id]; ok { + delete(userSessions, id) + if len(userSessions) == 0 { + delete(UserSessionInfoList, email) + } } } - if len(updatedSessionInfos) > 0 { - UserSessionInfoList[email] = updatedSessionInfos - return - } - delete(UserSessionInfoList, email) } func RemoveAllSessions(email string) { @@ -122,8 +120,8 @@ func RemoveAllSessions(email string) { } func GetSessionInfo(email string, id string) *SessionInfo { - for _, sessionInfo := range UserSessionInfoList[email] { - if sessionInfo.SessionID == id { + if userSession, ok := UserSessionInfoList[email]; ok { + if sessionInfo, ok := userSession[id]; ok { return sessionInfo } } @@ -136,26 +134,37 @@ func (sessionInfo *SessionInfo) UpdateAccessTime() { sessionInfo.AccessAt = formattedTime } -func GetSession(r *http.Request) (UserStatus, types.User) { +func GetSession(r *http.Request) (UserStatus, types.User, string) { cookie, err := r.Cookie("Session") if err != nil { - return Unauthorized, types.User{} + return Unauthorized, types.User{}, "" } storeSession, err := GlobalSessionStore.Get(cookie.Value) if err != nil { if errors.Is(err, &SessionNotFoundError{}) { - return InvalidSession, types.User{} + return InvalidSession, types.User{}, "" } - return Unauthorized, types.User{} + return Unauthorized, types.User{}, "" } val := storeSession.Values["user"] var userSession = types.User{} userSession, ok := val.(types.User) if !ok { - return Unauthorized, types.User{} + return Unauthorized, types.User{}, "" } - return Authorized, userSession + return Authorized, userSession, cookie.Value +} + +func GetSessions(email string) []*SessionInfo { + if sessions, ok := UserSessionInfoList[email]; ok { + result := make([]*SessionInfo, 0, len(sessions)) + for _, sessionInfo := range sessions { + result = append(result, sessionInfo) + } + return result + } + return nil }