Github OAuth integration complete, add a requirelogin middleware who redirect to admin/login if no session
- commit
- 4d9166c6d286f87a9f1940cb384b531ac63d3098
- author
- bnema · · 2023-09-16 09:57 UTC
- parent
- ad67f6b
- signature
- unsigned
5 files · +101 -42
M internal/app/app.go +1 -1
| @@ -20,7 +20,7 @@ const ( | |||
| 20 | 20 | // If enabled replace all docker commands by podman | |
| 21 | 21 | PodmanEnable = false | |
| 22 | 22 | PodmanSock = "/run/user/1000/podman/podman.sock" | |
| 23 | - | OauthCallbackURL = "http://localhost:1323/oauth/callback" | |
| 23 | + | OauthCallbackURL = "http://localhost:1323/admin/login/oauth/callback" | |
| 24 | 24 | ) | |
| 25 | 25 | ||
| 26 | 26 | type App struct { | |
| @@ -20,7 +20,7 @@ const ( | |||||
| 20 | // If enabled replace all docker commands by podman | 20 | // If enabled replace all docker commands by podman | ||
| 21 | PodmanEnable = false | 21 | PodmanEnable = false | ||
| 22 | PodmanSock = "/run/user/1000/podman/podman.sock" | 22 | PodmanSock = "/run/user/1000/podman/podman.sock" | ||
| 23 | - | OauthCallbackURL = "http://localhost:1323/oauth/callback" | 23 | + | OauthCallbackURL = "http://localhost:1323/admin/login/oauth/callback" |
| 24 | ) | 24 | ) | ||
| 25 | 25 | ||||
| 26 | type App struct { | 26 | type App struct { | ||
M internal/gotemplate/models/html/login/index.gohtml +2 -2
| @@ -21,7 +21,7 @@ | |||
| 21 | 21 | <script src="/assets/js/custom.js"></script> | |
| 22 | 22 | </head> | |
| 23 | 23 | ||
| 24 | - | <body class="IBMPlexSans bg-zinc-200 md:p-8 flex flex-col items-center" hx-boost="true"> | |
| 24 | + | <body class="IBMPlexSans bg-zinc-200 md:p-8 flex flex-col items-center"> | |
| 25 | 25 | <!-- Logo and Title --> | |
| 26 | 26 | <div id="logo-mascot" class="flex flex-col justify-center items-center p-4 mb-4"> | |
| 27 | 27 | <div class="circle-shadow flex justify-center w-100"> | |
| @@ -41,7 +41,7 @@ | |||
| 41 | 41 | <h2 class="text-2xl font-semibold text-gray-800">Login</h2> | |
| 42 | 42 | <!-- GitHub OAuth --> | |
| 43 | 43 | <div class="mt-4 p-2 bg-gordonmascot-hblue text-white rounded-md flex justify-left"> | |
| 44 | - | <a href="{{ .AdminPath }}/login/github" class="flex items-center"> | |
| 44 | + | <a href="login/oauth/github" class="flex items-center"> | |
| 45 | 45 | <img src="/assets/imgs/github/github-mark-white.png" alt="logo github" class="h-8 xl:h-12" /> | |
| 46 | 46 | <span class="w-full p-2 text-white ">Login with GitHub</span> | |
| 47 | 47 | </a> | |
| @@ -21,7 +21,7 @@ | |||||
| 21 | <script src="/assets/js/custom.js"></script> | 21 | <script src="/assets/js/custom.js"></script> | ||
| 22 | </head> | 22 | </head> | ||
| 23 | 23 | ||||
| 24 | - | <body class="IBMPlexSans bg-zinc-200 md:p-8 flex flex-col items-center" hx-boost="true"> | 24 | + | <body class="IBMPlexSans bg-zinc-200 md:p-8 flex flex-col items-center"> |
| 25 | <!-- Logo and Title --> | 25 | <!-- Logo and Title --> | ||
| 26 | <div id="logo-mascot" class="flex flex-col justify-center items-center p-4 mb-4"> | 26 | <div id="logo-mascot" class="flex flex-col justify-center items-center p-4 mb-4"> | ||
| 27 | <div class="circle-shadow flex justify-center w-100"> | 27 | <div class="circle-shadow flex justify-center w-100"> | ||
| @@ -41,7 +41,7 @@ | |||||
| 41 | <h2 class="text-2xl font-semibold text-gray-800">Login</h2> | 41 | <h2 class="text-2xl font-semibold text-gray-800">Login</h2> | ||
| 42 | <!-- GitHub OAuth --> | 42 | <!-- GitHub OAuth --> | ||
| 43 | <div class="mt-4 p-2 bg-gordonmascot-hblue text-white rounded-md flex justify-left"> | 43 | <div class="mt-4 p-2 bg-gordonmascot-hblue text-white rounded-md flex justify-left"> | ||
| 44 | - | <a href="{{ .AdminPath }}/login/github" class="flex items-center"> | 44 | + | <a href="login/oauth/github" class="flex items-center"> |
| 45 | <img src="/assets/imgs/github/github-mark-white.png" alt="logo github" class="h-8 xl:h-12" /> | 45 | <img src="/assets/imgs/github/github-mark-white.png" alt="logo github" class="h-8 xl:h-12" /> | ||
| 46 | <span class="w-full p-2 text-white ">Login with GitHub</span> | 46 | <span class="w-full p-2 text-white ">Login with GitHub</span> | ||
| 47 | </a> | 47 | </a> | ||
M internal/httpserve/handler/oauth.go +69 -34
| @@ -1,7 +1,10 @@ | |||
| 1 | 1 | package handler | |
| 2 | 2 | ||
| 3 | 3 | import ( | |
| 4 | + | "fmt" | |
| 5 | + | "io" | |
| 4 | 6 | "net/http" | |
| 7 | + | "net/url" | |
| 5 | 8 | "os" | |
| 6 | 9 | ||
| 7 | 10 | "github.com/bnema/gordon/internal/app" | |
| @@ -11,23 +14,9 @@ import ( | |||
| 11 | 14 | _ "github.com/joho/godotenv/autoload" | |
| 12 | 15 | "github.com/labstack/echo-contrib/session" | |
| 13 | 16 | "github.com/labstack/echo/v4" | |
| 14 | - | "github.com/markbates/goth" | |
| 15 | 17 | "github.com/markbates/goth/gothic" | |
| 16 | - | "github.com/markbates/goth/providers/github" | |
| 17 | 18 | ) | |
| 18 | 19 | ||
| 19 | - | var providerNames []string | |
| 20 | - | ||
| 21 | - | func init() { | |
| 22 | - | goth.UseProviders( | |
| 23 | - | github.New(os.Getenv("GITHUB_KEY"), os.Getenv("GITHUB_SECRET"), app.OauthCallbackURL), | |
| 24 | - | ) | |
| 25 | - | for _, provider := range goth.GetProviders() { | |
| 26 | - | // Append the provider's name to the slice | |
| 27 | - | providerNames = append(providerNames, provider.Name()) | |
| 28 | - | } | |
| 29 | - | } | |
| 30 | - | ||
| 31 | 20 | // RenderLoginPage renders the login.html template | |
| 32 | 21 | func RenderLoginPage(c echo.Context, a *app.App) error { | |
| 33 | 22 | lang := c.Get(middleware.LangKey).(string) | |
| @@ -57,37 +46,83 @@ func RenderLoginPage(c echo.Context, a *app.App) error { | |||
| 57 | 46 | return c.HTML(200, renderedHTML) | |
| 58 | 47 | } | |
| 59 | 48 | ||
| 60 | - | // StartOAuth initiates OAuth process | |
| 61 | - | func StartOAuth(c echo.Context, a *app.App) error { | |
| 62 | - | provider := c.Param("provider") | |
| 63 | - | if provider == "" { | |
| 64 | - | return echo.NewHTTPError(http.StatusBadRequest, "Missing provider") | |
| 49 | + | func StartOAuthGithub(c echo.Context, a *app.App) error { | |
| 50 | + | clientID := os.Getenv("GITHUB_CLIENTID") | |
| 51 | + | redirectURI := a.OauthCallbackURL // Make sure this URL is registered in your GitHub OAuth App | |
| 52 | + | fmt.Print(a.OauthCallbackURL) | |
| 53 | + | // Define the scopes you need; for example, "repo" and "admin:repo_hook" for repository and webhook actions | |
| 54 | + | scopes := "repo,admin:repo_hook" | |
| 55 | + | ||
| 56 | + | // Redirect to GitHub's OAuth page | |
| 57 | + | oauthURL := fmt.Sprintf( | |
| 58 | + | "https://github.com/login/oauth/authorize?client_id=%s&redirect_uri=%s&scope=%s", | |
| 59 | + | clientID, | |
| 60 | + | redirectURI, | |
| 61 | + | scopes, | |
| 62 | + | ) | |
| 63 | + | return c.Redirect(http.StatusFound, oauthURL) | |
| 64 | + | } | |
| 65 | + | ||
| 66 | + | func OAuthCallback(c echo.Context, a *app.App) error { | |
| 67 | + | clientID := os.Getenv("GITHUB_CLIENTID") | |
| 68 | + | clientSecret := os.Getenv("GITHUB_TOKEN") | |
| 69 | + | code := c.QueryParam("code") | |
| 70 | + | ||
| 71 | + | if code == "" { | |
| 72 | + | return c.JSON(http.StatusBadRequest, "Missing code") | |
| 65 | 73 | } | |
| 66 | 74 | ||
| 67 | - | // Get the current session from echo-contrib/session | |
| 68 | - | sess, _ := session.Get("session", c) | |
| 75 | + | // Create POST request to exchange code for access token | |
| 76 | + | payload := url.Values{} | |
| 77 | + | payload.Set("client_id", clientID) | |
| 78 | + | payload.Set("client_secret", clientSecret) | |
| 79 | + | payload.Set("code", code) | |
| 69 | 80 | ||
| 70 | - | // Set the provider in the session | |
| 71 | - | sess.Values["provider"] = provider | |
| 72 | - | sess.Save(c.Request(), c.Response()) | |
| 81 | + | resp, err := http.PostForm("https://github.com/login/oauth/access_token", payload) | |
| 82 | + | if err != nil { | |
| 83 | + | return c.JSON(http.StatusInternalServerError, "Failed to get access token") | |
| 84 | + | } | |
| 85 | + | defer resp.Body.Close() | |
| 73 | 86 | ||
| 74 | - | gothic.BeginAuthHandler(c.Response(), c.Request()) | |
| 75 | - | return nil | |
| 76 | - | } | |
| 87 | + | if resp.StatusCode != 200 { | |
| 88 | + | return c.JSON(http.StatusInternalServerError, "Received non-200 status code") | |
| 89 | + | } | |
| 77 | 90 | ||
| 78 | - | // OAuthCallback handles OAuth callback from provider | |
| 79 | - | func OAuthCallback(c echo.Context, a *app.App) error { | |
| 80 | - | _, err := gothic.CompleteUserAuth(c.Response(), c.Request()) | |
| 91 | + | // Parse the response | |
| 92 | + | body, err := io.ReadAll(resp.Body) | |
| 93 | + | if err != nil { | |
| 94 | + | return c.JSON(http.StatusInternalServerError, "Failed to read access token") | |
| 95 | + | } | |
| 96 | + | ||
| 97 | + | // Parse the access token from the response body | |
| 98 | + | accessToken := string(body) | |
| 99 | + | ||
| 100 | + | parsedQuery, err := url.ParseQuery(accessToken) | |
| 81 | 101 | if err != nil { | |
| 82 | - | return c.JSON(http.StatusUnauthorized, "Authentication failed") | |
| 102 | + | return c.JSON(http.StatusInternalServerError, "Failed to parse access token") | |
| 83 | 103 | } | |
| 84 | - | // TODO: Add your logic here, like creating a session, etc. | |
| 85 | - | return c.Redirect(http.StatusMovedPermanently, "/success") | |
| 104 | + | ||
| 105 | + | actualToken := parsedQuery.Get("access_token") | |
| 106 | + | fmt.Println("Received access token:", actualToken) | |
| 107 | + | ||
| 108 | + | // Get the current session from echo-contrib/session | |
| 109 | + | sess, err := session.Get("session", c) | |
| 110 | + | if err != nil { | |
| 111 | + | return echo.NewHTTPError(http.StatusInternalServerError, "Could not get session") | |
| 112 | + | } | |
| 113 | + | ||
| 114 | + | // Set the user as authenticated | |
| 115 | + | sess.Values["authenticated"] = true | |
| 116 | + | if err = sess.Save(c.Request(), c.Response()); err != nil { | |
| 117 | + | return echo.NewHTTPError(http.StatusInternalServerError, "Could not save session") | |
| 118 | + | } | |
| 119 | + | ||
| 120 | + | return c.Redirect(http.StatusFound, "/admin") | |
| 121 | + | ||
| 86 | 122 | } | |
| 87 | 123 | ||
| 88 | 124 | // Logout handles user logout and clears session | |
| 89 | 125 | func Logout(c echo.Context, a *app.App) error { | |
| 90 | 126 | gothic.Logout(c.Response(), c.Request()) | |
| 91 | - | // TODO: Add your logout logic here, like clearing session, etc. | |
| 92 | 127 | return c.Redirect(http.StatusMovedPermanently, "/") | |
| 93 | 128 | } | |
| @@ -1,7 +1,10 @@ | |||||
| 1 | package handler | 1 | package handler | ||
| 2 | 2 | ||||
| 3 | import ( | 3 | import ( | ||
| 4 | + | "fmt" | |||
| 5 | + | "io" | |||
| 4 | "net/http" | 6 | "net/http" | ||
| 7 | + | "net/url" | |||
| 5 | "os" | 8 | "os" | ||
| 6 | 9 | ||||
| 7 | "github.com/bnema/gordon/internal/app" | 10 | "github.com/bnema/gordon/internal/app" | ||
| @@ -11,23 +14,9 @@ import ( | |||||
| 11 | _ "github.com/joho/godotenv/autoload" | 14 | _ "github.com/joho/godotenv/autoload" | ||
| 12 | "github.com/labstack/echo-contrib/session" | 15 | "github.com/labstack/echo-contrib/session" | ||
| 13 | "github.com/labstack/echo/v4" | 16 | "github.com/labstack/echo/v4" | ||
| 14 | - | "github.com/markbates/goth" | |||
| 15 | "github.com/markbates/goth/gothic" | 17 | "github.com/markbates/goth/gothic" | ||
| 16 | - | "github.com/markbates/goth/providers/github" | |||
| 17 | ) | 18 | ) | ||
| 18 | 19 | ||||
| 19 | - | var providerNames []string | |||
| 20 | - | ||||
| 21 | - | func init() { | |||
| 22 | - | goth.UseProviders( | |||
| 23 | - | github.New(os.Getenv("GITHUB_KEY"), os.Getenv("GITHUB_SECRET"), app.OauthCallbackURL), | |||
| 24 | - | ) | |||
| 25 | - | for _, provider := range goth.GetProviders() { | |||
| 26 | - | // Append the provider's name to the slice | |||
| 27 | - | providerNames = append(providerNames, provider.Name()) | |||
| 28 | - | } | |||
| 29 | - | } | |||
| 30 | - | ||||
| 31 | // RenderLoginPage renders the login.html template | 20 | // RenderLoginPage renders the login.html template | ||
| 32 | func RenderLoginPage(c echo.Context, a *app.App) error { | 21 | func RenderLoginPage(c echo.Context, a *app.App) error { | ||
| 33 | lang := c.Get(middleware.LangKey).(string) | 22 | lang := c.Get(middleware.LangKey).(string) | ||
| @@ -57,37 +46,83 @@ func RenderLoginPage(c echo.Context, a *app.App) error { | |||||
| 57 | return c.HTML(200, renderedHTML) | 46 | return c.HTML(200, renderedHTML) | ||
| 58 | } | 47 | } | ||
| 59 | 48 | ||||
| 60 | - | // StartOAuth initiates OAuth process | 49 | + | func StartOAuthGithub(c echo.Context, a *app.App) error { |
| 61 | - | func StartOAuth(c echo.Context, a *app.App) error { | 50 | + | clientID := os.Getenv("GITHUB_CLIENTID") |
| 62 | - | provider := c.Param("provider") | 51 | + | redirectURI := a.OauthCallbackURL // Make sure this URL is registered in your GitHub OAuth App |
| 63 | - | if provider == "" { | 52 | + | fmt.Print(a.OauthCallbackURL) |
| 64 | - | return echo.NewHTTPError(http.StatusBadRequest, "Missing provider") | 53 | + | // Define the scopes you need; for example, "repo" and "admin:repo_hook" for repository and webhook actions |
| 54 | + | scopes := "repo,admin:repo_hook" | |||
| 55 | + | ||||
| 56 | + | // Redirect to GitHub's OAuth page | |||
| 57 | + | oauthURL := fmt.Sprintf( | |||
| 58 | + | "https://github.com/login/oauth/authorize?client_id=%s&redirect_uri=%s&scope=%s", | |||
| 59 | + | clientID, | |||
| 60 | + | redirectURI, | |||
| 61 | + | scopes, | |||
| 62 | + | ) | |||
| 63 | + | return c.Redirect(http.StatusFound, oauthURL) | |||
| 64 | + | } | |||
| 65 | + | ||||
| 66 | + | func OAuthCallback(c echo.Context, a *app.App) error { | |||
| 67 | + | clientID := os.Getenv("GITHUB_CLIENTID") | |||
| 68 | + | clientSecret := os.Getenv("GITHUB_TOKEN") | |||
| 69 | + | code := c.QueryParam("code") | |||
| 70 | + | ||||
| 71 | + | if code == "" { | |||
| 72 | + | return c.JSON(http.StatusBadRequest, "Missing code") | |||
| 65 | } | 73 | } | ||
| 66 | 74 | ||||
| 67 | - | // Get the current session from echo-contrib/session | 75 | + | // Create POST request to exchange code for access token |
| 68 | - | sess, _ := session.Get("session", c) | 76 | + | payload := url.Values{} |
| 77 | + | payload.Set("client_id", clientID) | |||
| 78 | + | payload.Set("client_secret", clientSecret) | |||
| 79 | + | payload.Set("code", code) | |||
| 69 | 80 | ||||
| 70 | - | // Set the provider in the session | 81 | + | resp, err := http.PostForm("https://github.com/login/oauth/access_token", payload) |
| 71 | - | sess.Values["provider"] = provider | 82 | + | if err != nil { |
| 72 | - | sess.Save(c.Request(), c.Response()) | 83 | + | return c.JSON(http.StatusInternalServerError, "Failed to get access token") |
| 84 | + | } | |||
| 85 | + | defer resp.Body.Close() | |||
| 73 | 86 | ||||
| 74 | - | gothic.BeginAuthHandler(c.Response(), c.Request()) | 87 | + | if resp.StatusCode != 200 { |
| 75 | - | return nil | 88 | + | return c.JSON(http.StatusInternalServerError, "Received non-200 status code") |
| 76 | - | } | 89 | + | } |
| 77 | 90 | ||||
| 78 | - | // OAuthCallback handles OAuth callback from provider | 91 | + | // Parse the response |
| 79 | - | func OAuthCallback(c echo.Context, a *app.App) error { | 92 | + | body, err := io.ReadAll(resp.Body) |
| 80 | - | _, err := gothic.CompleteUserAuth(c.Response(), c.Request()) | 93 | + | if err != nil { |
| 94 | + | return c.JSON(http.StatusInternalServerError, "Failed to read access token") | |||
| 95 | + | } | |||
| 96 | + | ||||
| 97 | + | // Parse the access token from the response body | |||
| 98 | + | accessToken := string(body) | |||
| 99 | + | ||||
| 100 | + | parsedQuery, err := url.ParseQuery(accessToken) | |||
| 81 | if err != nil { | 101 | if err != nil { | ||
| 82 | - | return c.JSON(http.StatusUnauthorized, "Authentication failed") | 102 | + | return c.JSON(http.StatusInternalServerError, "Failed to parse access token") |
| 83 | } | 103 | } | ||
| 84 | - | // TODO: Add your logic here, like creating a session, etc. | 104 | + | |
| 85 | - | return c.Redirect(http.StatusMovedPermanently, "/success") | 105 | + | actualToken := parsedQuery.Get("access_token") |
| 106 | + | fmt.Println("Received access token:", actualToken) | |||
| 107 | + | ||||
| 108 | + | // Get the current session from echo-contrib/session | |||
| 109 | + | sess, err := session.Get("session", c) | |||
| 110 | + | if err != nil { | |||
| 111 | + | return echo.NewHTTPError(http.StatusInternalServerError, "Could not get session") | |||
| 112 | + | } | |||
| 113 | + | ||||
| 114 | + | // Set the user as authenticated | |||
| 115 | + | sess.Values["authenticated"] = true | |||
| 116 | + | if err = sess.Save(c.Request(), c.Response()); err != nil { | |||
| 117 | + | return echo.NewHTTPError(http.StatusInternalServerError, "Could not save session") | |||
| 118 | + | } | |||
| 119 | + | ||||
| 120 | + | return c.Redirect(http.StatusFound, "/admin") | |||
| 121 | + | ||||
| 86 | } | 122 | } | ||
| 87 | 123 | ||||
| 88 | // Logout handles user logout and clears session | 124 | // Logout handles user logout and clears session | ||
| 89 | func Logout(c echo.Context, a *app.App) error { | 125 | func Logout(c echo.Context, a *app.App) error { | ||
| 90 | gothic.Logout(c.Response(), c.Request()) | 126 | gothic.Logout(c.Response(), c.Request()) | ||
| 91 | - | // TODO: Add your logout logic here, like clearing session, etc. | |||
| 92 | return c.Redirect(http.StatusMovedPermanently, "/") | 127 | return c.Redirect(http.StatusMovedPermanently, "/") | ||
| 93 | } | 128 | } | ||
A internal/httpserve/middleware/requirelogin.go +24 -0
| @@ -0,0 +1,24 @@ | |||
| 1 | + | package middleware | |
| 2 | + | ||
| 3 | + | import ( | |
| 4 | + | "net/http" | |
| 5 | + | ||
| 6 | + | "github.com/labstack/echo-contrib/session" | |
| 7 | + | "github.com/labstack/echo/v4" | |
| 8 | + | ) | |
| 9 | + | ||
| 10 | + | func RequireLogin(next echo.HandlerFunc) echo.HandlerFunc { | |
| 11 | + | return func(c echo.Context) error { | |
| 12 | + | sess, err := session.Get("session", c) | |
| 13 | + | if err != nil { | |
| 14 | + | return echo.NewHTTPError(http.StatusInternalServerError, "Could not get session") | |
| 15 | + | } | |
| 16 | + | ||
| 17 | + | // Check if the user is authenticated | |
| 18 | + | if sess.Values["authenticated"] == nil || sess.Values["authenticated"] == false { | |
| 19 | + | return c.Redirect(http.StatusSeeOther, "/admin/login") | |
| 20 | + | } | |
| 21 | + | ||
| 22 | + | return next(c) | |
| 23 | + | } | |
| 24 | + | } | |
| @@ -0,0 +1,24 @@ | |||||
| 1 | + | package middleware | |||
| 2 | + | ||||
| 3 | + | import ( | |||
| 4 | + | "net/http" | |||
| 5 | + | ||||
| 6 | + | "github.com/labstack/echo-contrib/session" | |||
| 7 | + | "github.com/labstack/echo/v4" | |||
| 8 | + | ) | |||
| 9 | + | ||||
| 10 | + | func RequireLogin(next echo.HandlerFunc) echo.HandlerFunc { | |||
| 11 | + | return func(c echo.Context) error { | |||
| 12 | + | sess, err := session.Get("session", c) | |||
| 13 | + | if err != nil { | |||
| 14 | + | return echo.NewHTTPError(http.StatusInternalServerError, "Could not get session") | |||
| 15 | + | } | |||
| 16 | + | ||||
| 17 | + | // Check if the user is authenticated | |||
| 18 | + | if sess.Values["authenticated"] == nil || sess.Values["authenticated"] == false { | |||
| 19 | + | return c.Redirect(http.StatusSeeOther, "/admin/login") | |||
| 20 | + | } | |||
| 21 | + | ||||
| 22 | + | return next(c) | |||
| 23 | + | } | |||
| 24 | + | } | |||
M internal/httpserve/router.go +5 -5
| @@ -18,7 +18,7 @@ func RegisterRoutes(e *echo.Echo, a *app.App) *echo.Echo { | |||
| 18 | 18 | e.Use(middleware.SetCommonDataMiddleware(a)) | |
| 19 | 19 | e.Use(middleware.ErrorHandler) | |
| 20 | 20 | // Add session middleware | |
| 21 | - | e.Use(session.Middleware(sessions.NewCookieStore([]byte(os.Getenv("SECRET"))))) | |
| 21 | + | e.Use(session.Middleware(sessions.NewCookieStore([]byte(os.Getenv("SESSION_SECRET"))))) | |
| 22 | 22 | e.Use(middleware.ColorSchemeDetection) | |
| 23 | 23 | e.Use(middleware.LanguageDetection) | |
| 24 | 24 | ||
| @@ -44,17 +44,17 @@ func bindStaticRoute(e *echo.Echo, a *app.App, path string) { | |||
| 44 | 44 | func bindAdminRoute(e *echo.Echo, a *app.App, path string) { | |
| 45 | 45 | e.GET(path, func(c echo.Context) error { | |
| 46 | 46 | return handler.AdminRoute(c, a) | |
| 47 | - | }) | |
| 47 | + | }, middleware.RequireLogin) // Require login | |
| 48 | 48 | } | |
| 49 | 49 | ||
| 50 | 50 | func bindLoginRoute(e *echo.Echo, a *app.App, adminPath string) { | |
| 51 | 51 | e.GET(adminPath+"/login", func(c echo.Context) error { | |
| 52 | 52 | return handler.RenderLoginPage(c, a) | |
| 53 | 53 | }) | |
| 54 | - | e.GET(adminPath+"/login/:provider", func(c echo.Context) error { | |
| 55 | - | return handler.StartOAuth(c, a) | |
| 54 | + | e.GET(adminPath+"/login/oauth/github", func(c echo.Context) error { | |
| 55 | + | return handler.StartOAuthGithub(c, a) | |
| 56 | 56 | }) | |
| 57 | - | e.GET(a.OauthCallbackURL, func(c echo.Context) error { | |
| 57 | + | e.GET(adminPath+"/login/oauth/callback", func(c echo.Context) error { | |
| 58 | 58 | return handler.OAuthCallback(c, a) | |
| 59 | 59 | }) | |
| 60 | 60 | e.GET(adminPath+"/logout", func(c echo.Context) error { | |
| @@ -18,7 +18,7 @@ func RegisterRoutes(e *echo.Echo, a *app.App) *echo.Echo { | |||||
| 18 | e.Use(middleware.SetCommonDataMiddleware(a)) | 18 | e.Use(middleware.SetCommonDataMiddleware(a)) | ||
| 19 | e.Use(middleware.ErrorHandler) | 19 | e.Use(middleware.ErrorHandler) | ||
| 20 | // Add session middleware | 20 | // Add session middleware | ||
| 21 | - | e.Use(session.Middleware(sessions.NewCookieStore([]byte(os.Getenv("SECRET"))))) | 21 | + | e.Use(session.Middleware(sessions.NewCookieStore([]byte(os.Getenv("SESSION_SECRET"))))) |
| 22 | e.Use(middleware.ColorSchemeDetection) | 22 | e.Use(middleware.ColorSchemeDetection) | ||
| 23 | e.Use(middleware.LanguageDetection) | 23 | e.Use(middleware.LanguageDetection) | ||
| 24 | 24 | ||||
| @@ -44,17 +44,17 @@ func bindStaticRoute(e *echo.Echo, a *app.App, path string) { | |||||
| 44 | func bindAdminRoute(e *echo.Echo, a *app.App, path string) { | 44 | func bindAdminRoute(e *echo.Echo, a *app.App, path string) { | ||
| 45 | e.GET(path, func(c echo.Context) error { | 45 | e.GET(path, func(c echo.Context) error { | ||
| 46 | return handler.AdminRoute(c, a) | 46 | return handler.AdminRoute(c, a) | ||
| 47 | - | }) | 47 | + | }, middleware.RequireLogin) // Require login |
| 48 | } | 48 | } | ||
| 49 | 49 | ||||
| 50 | func bindLoginRoute(e *echo.Echo, a *app.App, adminPath string) { | 50 | func bindLoginRoute(e *echo.Echo, a *app.App, adminPath string) { | ||
| 51 | e.GET(adminPath+"/login", func(c echo.Context) error { | 51 | e.GET(adminPath+"/login", func(c echo.Context) error { | ||
| 52 | return handler.RenderLoginPage(c, a) | 52 | return handler.RenderLoginPage(c, a) | ||
| 53 | }) | 53 | }) | ||
| 54 | - | e.GET(adminPath+"/login/:provider", func(c echo.Context) error { | 54 | + | e.GET(adminPath+"/login/oauth/github", func(c echo.Context) error { |
| 55 | - | return handler.StartOAuth(c, a) | 55 | + | return handler.StartOAuthGithub(c, a) |
| 56 | }) | 56 | }) | ||
| 57 | - | e.GET(a.OauthCallbackURL, func(c echo.Context) error { | 57 | + | e.GET(adminPath+"/login/oauth/callback", func(c echo.Context) error { |
| 58 | return handler.OAuthCallback(c, a) | 58 | return handler.OAuthCallback(c, a) | ||
| 59 | }) | 59 | }) | ||
| 60 | e.GET(adminPath+"/logout", func(c echo.Context) error { | 60 | e.GET(adminPath+"/logout", func(c echo.Context) error { | ||