diff --git a/admin/api/password.go b/admin/api/password.go index a626ee22..311a53ce 100644 --- a/admin/api/password.go +++ b/admin/api/password.go @@ -17,8 +17,9 @@ import ( ) var ( - OidcIssuer = "live.fic.srs.epita.fr" - OidcSecret = "" + OidcIssuer = "live.fic.srs.epita.fr" + OidcClientId = "epita-challenge" + OidcSecret = "" ) func declarePasswordRoutes(router *gin.RouterGroup) { @@ -69,6 +70,26 @@ func declarePasswordRoutes(router *gin.RouterGroup) { return } + c.JSON(http.StatusOK, true) + }) + router.GET("/vouch-proxy.yaml", func(c *gin.Context) { + cfg, err := genVouchProxyConfig() + if err != nil { + c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": err.Error()}) + return + } + + c.String(http.StatusOK, string(cfg)) + }) + router.POST("/vouch-proxy.yaml", func(c *gin.Context) { + if dexcfg, err := genVouchProxyConfig(); err != nil { + c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": err.Error()}) + return + } else if err := ioutil.WriteFile(path.Join(pki.PKIDir, "shared", "vouch-config.yaml"), []byte(dexcfg), 0644); err != nil { + c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": err.Error()}) + return + } + c.JSON(http.StatusOK, true) }) } @@ -203,7 +224,7 @@ func genDexConfig() ([]byte, error) { Issuer: "https://" + OidcIssuer, Clients: []dexConfigClient{ dexConfigClient{ - Id: "epita-challenge", + Id: OidcClientId, Name: challengeInfo.Title, RedirectURIs: []string{"https://" + OidcIssuer + "/challenge_access/auth"}, Secret: OidcSecret, @@ -249,3 +270,54 @@ func genDexPasswordTpl() ([]byte, error) { } } } + +const vouchcfgtpl = `# CONFIGURATION FILE HANDLED BY fic-admin +# DO NOT MODIFY IT BY HAND + +vouch: + logLevel: debug + allowAllUsers: true + document_root: /challenge_access + + cookie: + domain: {{ .Issuer }} + + oauth: + provider: oidc + client_id: {{ .ClientId }} + client_secret: {{ .ClientSecret }} + callback_urls: + - https://{{ .Issuer }}/challenge_access/auth + auth_url: https://{{ .Issuer }}/auth + token_url: http://127.0.0.1:5556/token + user_info_url: http://127.0.0.1:5556/userinfo + scopes: + - openid + - email +` + +type vouchProxyConfig struct { + Issuer string + ClientId string + ClientSecret string +} + +func genVouchProxyConfig() ([]byte, error) { + if OidcSecret == "" { + return nil, fmt.Errorf("Unable to generate vouch proxy configuration: OIDC Secret not defined. Please define FICOIDC_SECRET in your environment.") + } + + b := bytes.NewBufferString("") + + if vouchTmpl, err := template.New("vouchcfg").Parse(vouchcfgtpl); err != nil { + return nil, fmt.Errorf("Cannot create template: %w", err) + } else if err = vouchTmpl.Execute(b, vouchProxyConfig{ + Issuer: "https://" + OidcIssuer, + ClientId: OidcClientId, + ClientSecret: OidcSecret, + }); err != nil { + return nil, fmt.Errorf("An error occurs during template execution: %w", err) + } else { + return b.Bytes(), nil + } +} diff --git a/admin/main.go b/admin/main.go index d6977913..47d31c72 100644 --- a/admin/main.go +++ b/admin/main.go @@ -38,6 +38,16 @@ func main() { // Read paremeters from environment if v, exists := os.LookupEnv("FICOIDC_ISSUER"); exists { api.OidcIssuer = v + } else if v, exists := os.LookupEnv("FICOIDC_ISSUER_FILE"); exists { + fd, err := os.Open(v) + if err != nil { + log.Fatal("Unable to open FICOIDC_ISSUER_FILE:", err) + } + + b, _ := ioutil.ReadAll(fd) + api.OidcIssuer = strings.TrimSpace(string(b)) + + fd.Close() } if v, exists := os.LookupEnv("FICOIDC_SECRET"); exists { api.OidcSecret = v diff --git a/admin/static/js/app.js b/admin/static/js/app.js index f8dfd31f..ae400578 100644 --- a/admin/static/js/app.js +++ b/admin/static/js/app.js @@ -2396,6 +2396,12 @@ angular.module("FICApp") }, function(response) { $scope.addToast('danger', 'An error occurs when generating dex config:', response.data.errmsg); }); + $http.post("api/vouch.yaml").then(function() { + $scope.addToast('success', 'VouchProxy config refreshed.', "Don't forget to reload/reboot frontend host."); + }, function(response) { + $scope.addToast('danger', 'An error occurs when generating VouchProxy config:', response.data.errmsg); + }); + }); } $scope.desactiveTeams = function() { $http.post("api/disableinactiveteams").then(function() { diff --git a/fickit-backend.yml b/fickit-backend.yml index 017377d4..c7a34444 100644 --- a/fickit-backend.yml +++ b/fickit-backend.yml @@ -214,10 +214,11 @@ services: - MYSQL_HOST=db - MYSQL_PASSWORD_FILE=/run/secrets/mysql_password - FICCA_PASS_FILE=/run/secrets/fic_ca_pass - - FICOIDC_ISSUER=live.fic.srs.epita.fr + - FICOIDC_ISSUER_FILE=/run/config/ip_config/domain - FICOIDC_SECRET_FILE=/run/secrets/fic_oidc_secret binds: - /etc/hosts:/etc/hosts:ro + - /run/config/ip_config/domain:/run/config/ip_config/domain:ro - /var/lib/fic/secrets/fic_ca_pass:/run/secrets/fic_ca_pass:ro - /var/lib/fic/secrets/fic_oidc_secret:/run/secrets/fic_oidc_secret:ro - /var/lib/fic/secrets/mysql_password:/run/secrets/mysql_password:ro diff --git a/fickit-frontend.yml b/fickit-frontend.yml index f484305e..0821f12f 100644 --- a/fickit-frontend.yml +++ b/fickit-frontend.yml @@ -276,19 +276,10 @@ services: - name: vouch-proxy image: quay.io/vouch/vouch-proxy:alpine-0.39 env: - - VOUCH_ALLOWALLUSERS=true - - VOUCH_COOKIE_DOMAIN=live.fic.srs.epita.fr - - VOUCH_DOCUMENT_ROOT=/challenge_access - - VOUCH_LOGLEVEL=debug - - OAUTH_PROVIDER=oidc - - OAUTH_CLIENT_ID=epita-challenge - - OAUTH_CLIENT_SECRET=N4n7AXzK9kpXt3TmSn8wAgtxqxhGORgcubLaE2g - - OAUTH_CALLBACK_URL=https://live.fic.srs.epita.fr/challenge_access/auth - - OAUTH_AUTH_URL=https://live.fic.srs.epita.fr/auth - - OAUTH_TOKEN_URL=http://127.0.0.1:5556/token - - OAUTH_USER_INFO_URL=http://127.0.0.1:5556/userinfo - - OAUTH_SCOPES=openid,email + - VOUCH_CONFIG=/etc/vouch/config.yml net: /run/netns/auth + binds: + - /var/lib/fic/pki/shared/vouch-config.yaml:/etc/vouch/config.yml:ro files: