From 92aabc00864609d17e793e1b12ad60cbecbbf2cb Mon Sep 17 00:00:00 2001 From: Marco Piovanello <35533749+marcopeocchi@users.noreply.github.com> Date: Tue, 23 Jul 2024 19:04:05 +0200 Subject: [PATCH] OpenID authentification (#170) * openid authentification * openid middleware * openId login * tidied login page * removed useless email text field --- frontend/src/views/Login.tsx | 25 +++-- go.mod | 5 + go.sum | 14 +++ main.go | 3 + server/config/config.go | 6 ++ server/logging/handler.go | 4 + server/openid/handler.go | 172 +++++++++++++++++++++++++++++++++++ server/openid/middleware.go | 20 ++++ server/rest/container.go | 4 + server/rpc/container.go | 4 + server/server.go | 10 ++ 11 files changed, 259 insertions(+), 8 deletions(-) create mode 100644 server/openid/handler.go create mode 100644 server/openid/middleware.go diff --git a/frontend/src/views/Login.tsx b/frontend/src/views/Login.tsx index 9884a3c..208bc18 100644 --- a/frontend/src/views/Login.tsx +++ b/frontend/src/views/Login.tsx @@ -6,19 +6,20 @@ import styled from '@emotion/styled' import { Button, Container, + Divider, Paper, Stack, TextField, Typography } from '@mui/material' +import { matchW } from 'fp-ts/lib/TaskEither' +import { pipe } from 'fp-ts/lib/function' import { useState } from 'react' import { useNavigate } from 'react-router-dom' import { useRecoilValue } from 'recoil' import { serverURL } from '../atoms/settings' import { useToast } from '../hooks/toast' import { ffetch } from '../lib/httpClient' -import { matchW } from 'fp-ts/lib/TaskEither' -import { pipe } from 'fp-ts/lib/function' const LoginContainer = styled(Container)({ display: 'flex', @@ -81,6 +82,8 @@ export default function Login() { )() } + const loginWithOpenId = () => window.open(`${url}/auth/openid/login`) + return ( @@ -89,12 +92,8 @@ export default function Login() { yt-dlp WebUI - Authentication token will expire after 30 days. - - - In order to enable RPC authentication append the --auth, - <br /> - --user [username] and --pass [password] flags. + To configure authentication check the  + <a href='https://github.com/marcopeocchi/yt-dlp-web-ui/wiki/Authentication-methods'>wiki</a>. login()}> Submit + + + + or use your authentication provider + + + + diff --git a/go.mod b/go.mod index fd2d748..0af71a1 100644 --- a/go.mod +++ b/go.mod @@ -4,12 +4,14 @@ go 1.22 require ( github.com/asaskevich/EventBus v0.0.0-20200907212545-49d423059eef + github.com/coreos/go-oidc v2.2.1+incompatible github.com/go-chi/chi/v5 v5.0.12 github.com/go-chi/cors v1.2.1 github.com/golang-jwt/jwt/v5 v5.2.1 github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.1 github.com/reactivex/rxgo/v2 v2.5.0 + golang.org/x/oauth2 v0.21.0 golang.org/x/sync v0.6.0 golang.org/x/sys v0.18.0 gopkg.in/yaml.v3 v3.0.1 @@ -25,11 +27,14 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pquerna/cachecontrol v0.2.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/stretchr/testify v1.9.0 // indirect github.com/teivah/onecontext v1.3.0 // indirect + golang.org/x/crypto v0.21.0 // indirect golang.org/x/net v0.22.0 // indirect + gopkg.in/square/go-jose.v2 v2.6.0 // indirect modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b // indirect modernc.org/libc v1.47.0 // indirect modernc.org/mathutil v1.6.0 // indirect diff --git a/go.sum b/go.sum index ad38ecd..d35463d 100644 --- a/go.sum +++ b/go.sum @@ -3,6 +3,8 @@ github.com/asaskevich/EventBus v0.0.0-20200907212545-49d423059eef/go.mod h1:JS7h github.com/cenkalti/backoff/v4 v4.0.0/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk= +github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -17,6 +19,8 @@ github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4= github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -38,6 +42,8 @@ github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdh github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pquerna/cachecontrol v0.2.0 h1:vBXSNuE5MYP9IJ5kjsdo8uq+w41jSPgvba2DEnkRx9k= +github.com/pquerna/cachecontrol v0.2.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI= github.com/reactivex/rxgo/v2 v2.5.0 h1:FhPgHwX9vKdNQB2gq9EPt+EKk9QrrzoeztGbEEnZam4= github.com/reactivex/rxgo/v2 v2.5.0/go.mod h1:bs4fVZxcb5ZckLIOeIeVH942yunJLWDABWGbrHAW+qU= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= @@ -47,6 +53,7 @@ github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/teivah/onecontext v0.0.0-20200513185103-40f981bfd775/go.mod h1:XUZ4x3oGhWfiOnUvTslnKKs39AWUct3g3yJvXTQSJOQ= @@ -55,6 +62,8 @@ github.com/teivah/onecontext v1.3.0/go.mod h1:hoW1nmdPVK/0jrvGtcx8sCKYs2PiS4z0zz go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= @@ -63,6 +72,8 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= @@ -80,7 +91,10 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= +gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= modernc.org/cc/v4 v4.19.5 h1:QlsZyQ1zf78DGeqnQ9ILi9hXyMdoC5e1qoGNUyBjHQw= diff --git a/main.go b/main.go index dc5f19a..960a2fe 100644 --- a/main.go +++ b/main.go @@ -11,6 +11,7 @@ import ( "github.com/marcopeocchi/yt-dlp-web-ui/server" "github.com/marcopeocchi/yt-dlp-web-ui/server/cli" "github.com/marcopeocchi/yt-dlp-web-ui/server/config" + "github.com/marcopeocchi/yt-dlp-web-ui/server/openid" ) var ( @@ -91,6 +92,8 @@ func main() { log.Println(cli.BgRed, "config", cli.Reset, err) } + openid.Configure() + server.RunBlocking(&server.RunConfig{ Host: c.Host, Port: c.Port, diff --git a/server/config/config.go b/server/config/config.go index 5e889db..08d4604 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -22,6 +22,12 @@ type Config struct { QueueSize int `yaml:"queue_size"` SessionFilePath string `yaml:"session_file_path"` path string + + UseOpenId bool `yaml:"use_openid"` + OpenIdProviderURL string `yaml:"openid_provider_url"` + OpenIdClientId string `yaml:"openid_client_id"` + OpenIdClientSecret string `yaml:"openid_client_secret"` + OpenIdRedirectURL string `yaml:"openid_redirect_url"` } var ( diff --git a/server/logging/handler.go b/server/logging/handler.go index a4ff5c1..aaccd22 100644 --- a/server/logging/handler.go +++ b/server/logging/handler.go @@ -11,6 +11,7 @@ import ( "github.com/gorilla/websocket" "github.com/marcopeocchi/yt-dlp-web-ui/server/config" middlewares "github.com/marcopeocchi/yt-dlp-web-ui/server/middleware" + "github.com/marcopeocchi/yt-dlp-web-ui/server/openid" ) var upgrader = websocket.Upgrader{ @@ -77,6 +78,9 @@ func ApplyRouter() func(chi.Router) { if config.Instance().RequireAuth { r.Use(middlewares.Authenticated) } + if config.Instance().UseOpenId { + r.Use(openid.Middleware) + } r.Get("/ws", webSocket) r.Get("/sse", sse) } diff --git a/server/openid/handler.go b/server/openid/handler.go new file mode 100644 index 0000000..642644f --- /dev/null +++ b/server/openid/handler.go @@ -0,0 +1,172 @@ +package openid + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "net/http" + "time" + + "github.com/coreos/go-oidc" + "github.com/google/uuid" + "github.com/marcopeocchi/yt-dlp-web-ui/server/config" + "golang.org/x/oauth2" +) + +type OAuth2SuccessResponse struct { + OAuth2Token *oauth2.Token + OAuth2RawToken string + IDTokenClaims *json.RawMessage +} + +var ( + oauth2Config oauth2.Config + verifier *oidc.IDTokenVerifier +) + +func Configure() { + provider, err := oidc.NewProvider(context.Background(), config.Instance().OpenIdProviderURL) + if err != nil { + panic(err) + } + + oauth2Config = oauth2.Config{ + ClientID: config.Instance().OpenIdClientId, + ClientSecret: config.Instance().OpenIdClientSecret, + RedirectURL: config.Instance().OpenIdRedirectURL, + Endpoint: provider.Endpoint(), + Scopes: []string{oidc.ScopeOpenID, "profile", "email"}, + } + + verifier = provider.Verifier(&oidc.Config{ + ClientID: config.Instance().OpenIdClientId, + }) +} + +func Login(w http.ResponseWriter, r *http.Request) { + var ( + state = uuid.NewString() + nonce = uuid.NewString() // maybe something cryptographycally more seucre? + ) + + http.SetCookie(w, &http.Cookie{ + Name: "state", + Value: state, + HttpOnly: true, + Path: "/", + Secure: r.TLS != nil, + Expires: time.Now().Add(time.Hour * 24 * 30), + }) + + http.SetCookie(w, &http.Cookie{ + Name: "nonce", + Value: nonce, + HttpOnly: true, + Path: "/", + Secure: r.TLS != nil, + Expires: time.Now().Add(time.Hour * 24 * 30), + }) + + http.Redirect(w, r, oauth2Config.AuthCodeURL(state, oidc.Nonce(nonce)), http.StatusFound) +} + +func doAuthentification(r *http.Request) (*OAuth2SuccessResponse, error) { + state, err := r.Cookie("state") + if err != nil { + return nil, err + } + + if r.URL.Query().Get("state") != state.Value { + return nil, errors.New("auth state does not match") + } + + oauth2Token, err := oauth2Config.Exchange(r.Context(), r.URL.Query().Get("code")) + if err != nil { + return nil, err + } + + rawToken, ok := oauth2Token.Extra("id_token").(string) + if !ok { + return nil, errors.New("openid field \"id_token\" not found in oauth2 token") + } + + idToken, err := verifier.Verify(r.Context(), rawToken) + if err != nil { + return nil, err + } + + nonce, err := r.Cookie("nonce") + if err != nil { + return nil, err + } + + if idToken.Nonce != nonce.Value { + return nil, errors.New("auth nonce does not match") + } + + // redact + oauth2Token.AccessToken = "" + + res := OAuth2SuccessResponse{ + oauth2Token, + rawToken, + &json.RawMessage{}, + } + + if err := idToken.Claims(&res.IDTokenClaims); err != nil { + return nil, err + } + + return &res, nil +} + +func SingIn(w http.ResponseWriter, r *http.Request) { + res, err := doAuthentification(r) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + http.SetCookie(w, &http.Cookie{ + Name: "oid-token", + Value: res.OAuth2RawToken, + HttpOnly: true, + Path: "/", + Secure: r.TLS != nil, + Expires: time.Now().Add(time.Hour * 24 * 30), + }) + + // if err := json.NewEncoder(w).Encode(res); err != nil { + // http.Error(w, err.Error(), http.StatusInternalServerError) + // return + // } + + fmt.Fprintf(w, "Login succesfully, you may now close this window and refresh yt-dlp-webui.") +} + +func Logout(w http.ResponseWriter, r *http.Request) { + http.SetCookie(w, &http.Cookie{ + Name: "oid-token", + HttpOnly: true, + Path: "/", + Secure: r.TLS != nil, + Expires: time.Now(), + }) + + http.SetCookie(w, &http.Cookie{ + Name: "state", + HttpOnly: true, + Path: "/", + Secure: r.TLS != nil, + Expires: time.Now(), + }) + + http.SetCookie(w, &http.Cookie{ + Name: "nonce", + HttpOnly: true, + Path: "/", + Secure: r.TLS != nil, + Expires: time.Now(), + }) +} diff --git a/server/openid/middleware.go b/server/openid/middleware.go new file mode 100644 index 0000000..3ff6cb2 --- /dev/null +++ b/server/openid/middleware.go @@ -0,0 +1,20 @@ +package openid + +import "net/http" + +func Middleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + token, err := r.Cookie("oid-token") + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + if _, err := verifier.Verify(r.Context(), token.Value); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + next.ServeHTTP(w, r) + }) +} diff --git a/server/rest/container.go b/server/rest/container.go index 047d611..07bf32c 100644 --- a/server/rest/container.go +++ b/server/rest/container.go @@ -4,6 +4,7 @@ import ( "github.com/go-chi/chi/v5" "github.com/marcopeocchi/yt-dlp-web-ui/server/config" middlewares "github.com/marcopeocchi/yt-dlp-web-ui/server/middleware" + "github.com/marcopeocchi/yt-dlp-web-ui/server/openid" ) func Container(args *ContainerArgs) *Handler { @@ -21,6 +22,9 @@ func ApplyRouter(args *ContainerArgs) func(chi.Router) { if config.Instance().RequireAuth { r.Use(middlewares.Authenticated) } + if config.Instance().UseOpenId { + r.Use(openid.Middleware) + } r.Post("/exec", h.Exec()) r.Get("/running", h.Running()) r.Get("/version", h.GetVersion()) diff --git a/server/rpc/container.go b/server/rpc/container.go index 7328fc3..b1ab11c 100644 --- a/server/rpc/container.go +++ b/server/rpc/container.go @@ -7,6 +7,7 @@ import ( "github.com/marcopeocchi/yt-dlp-web-ui/server/config" "github.com/marcopeocchi/yt-dlp-web-ui/server/internal" middlewares "github.com/marcopeocchi/yt-dlp-web-ui/server/middleware" + "github.com/marcopeocchi/yt-dlp-web-ui/server/openid" ) // Dependency injection container. @@ -28,6 +29,9 @@ func ApplyRouter() func(chi.Router) { if config.Instance().RequireAuth { r.Use(middlewares.Authenticated) } + if config.Instance().UseOpenId { + r.Use(openid.Middleware) + } r.Get("/ws", WebSocket) r.Post("/http", Post) } diff --git a/server/server.go b/server/server.go index 450b9c5..65e7e06 100644 --- a/server/server.go +++ b/server/server.go @@ -24,6 +24,7 @@ import ( "github.com/marcopeocchi/yt-dlp-web-ui/server/internal" "github.com/marcopeocchi/yt-dlp-web-ui/server/logging" middlewares "github.com/marcopeocchi/yt-dlp-web-ui/server/middleware" + "github.com/marcopeocchi/yt-dlp-web-ui/server/openid" "github.com/marcopeocchi/yt-dlp-web-ui/server/rest" ytdlpRPC "github.com/marcopeocchi/yt-dlp-web-ui/server/rpc" @@ -168,6 +169,9 @@ func newServer(c serverConfig) *http.Server { if config.Instance().RequireAuth { r.Use(middlewares.Authenticated) } + if config.Instance().UseOpenId { + r.Use(openid.Middleware) + } r.Post("/downloaded", handlers.ListDownloaded) r.Post("/delete", handlers.DeleteFile) r.Get("/d/{id}", handlers.DownloadFile) @@ -179,6 +183,12 @@ func newServer(c serverConfig) *http.Server { r.Route("/auth", func(r chi.Router) { r.Post("/login", handlers.Login) r.Get("/logout", handlers.Logout) + + r.Route("/openid", func(r chi.Router) { + r.Get("/login", openid.Login) + r.Get("/signin", openid.SingIn) + r.Get("/logout", openid.Logout) + }) }) // RPC handlers