package authentication import ( . "git.gorlug.de/code/golang/ersteller-lib" "net/http" "strings" "github.com/gorilla/sessions" "golang.org/x/net/context" ) const sessionName = "session" const EmailKey = "email" const UserIdKey = "userId" func SaveEmailAndUserIdToSessionStore(request *http.Request, writer http.ResponseWriter, store *sessions.CookieStore, email string, userId int) error { session, err := store.New(request, sessionName) if err != nil { LogError("Failed to create session: %v", err) return err } session.Values = map[interface{}]interface{}{ EmailKey: email, UserIdKey: userId, } err = session.Save(request, writer) if err != nil { LogError("Failed to save session: %v", err) return err } return nil } func SetUserIdAndEmailFromSessionStore(request *http.Request, store *sessions.CookieStore) (bool, *http.Request, error) { session, err := store.Get(request, sessionName) if err != nil { LogError("Failed to get session: %v", err) return false, nil, err } email, ok := session.Values[EmailKey].(string) if !ok { return false, nil, nil } userId, ok := session.Values[UserIdKey].(int) if !ok { return false, nil, nil } ctx := context.WithValue(request.Context(), AuthContextKey, AuthContext{ Email: email, UserId: userId, }) return true, request.WithContext(ctx), nil } func LogoutSession(writer http.ResponseWriter, request *http.Request, sessionStore *sessions.CookieStore, redirectUrl string) { // Clear the session session, err := sessionStore.Get(request, sessionName) // Using default session name if err != nil { LogError("Failed to get session: %v", err) http.Redirect(writer, request, redirectUrl, http.StatusTemporaryRedirect) return } session.Options.MaxAge = -1 err = session.Save(request, writer) if err != nil { LogError("Failed to save session: %v", err) http.Error(writer, "Failed to clear session", http.StatusInternalServerError) return } http.Redirect(writer, request, redirectUrl, http.StatusTemporaryRedirect) } func Middleware(store *sessions.CookieStore, excludedPrefixes []string, redirect LanguagePaths) MiddlewareFunc { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { Debug("Authenticating for page", r.URL.Path) if r.Method == http.MethodOptions { next.ServeHTTP(w, r) return } for _, prefix := range excludedPrefixes { if strings.HasPrefix(r.URL.Path, prefix) { next.ServeHTTP(w, r) return } } for _, path := range redirect { if strings.HasPrefix(r.URL.Path, path) { next.ServeHTTP(w, r) return } } ok, newR, err := SetUserIdAndEmailFromSessionStore(r, store) if err != nil { LogError("Failed to set user id and email from session: %v", err) http.Error(w, "Internal server error", http.StatusInternalServerError) return } if ok { next.ServeHTTP(w, newR) } else { redirectUrl := En.GetPath() + redirect[En] for lang, path := range redirect { if strings.HasPrefix(r.URL.Path, lang.GetPath()) { redirectUrl = lang.GetPath() + path break } } if redirectUrl == "" { redirectUrl = "/" } Debug("Redirecting to ", redirectUrl, "because there is no session") http.Redirect(w, r, redirectUrl, http.StatusTemporaryRedirect) } }) } }