github.com/pelicanplatform/pelican@v1.0.5/director/authentication.go (about) 1 /*************************************************************** 2 * 3 * Copyright (C) 2023, Pelican Project, Morgridge Institute for Research 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); you 6 * may not use this file except in compliance with the License. You may 7 * obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ***************************************************************/ 18 19 package director 20 21 import ( 22 "encoding/json" 23 24 "github.com/gin-gonic/gin" 25 "github.com/pelicanplatform/pelican/config" 26 "github.com/pelicanplatform/pelican/param" 27 log "github.com/sirupsen/logrus" 28 ) 29 30 type DiscoveryResponse struct { 31 Issuer string `json:"issuer"` 32 JwksUri string `json:"jwks_uri"` 33 } 34 35 const ( 36 directorDiscoveryPath string = "/.well-known/openid-configuration" 37 directorJWKSPath string = "/.well-known/issuer.jwks" 38 ) 39 40 // Returns links related to director's authentication, including the link 41 // to get the public key from the director 42 func discoveryHandler(ctx *gin.Context) { 43 directorUrl := param.Federation_DirectorUrl.GetString() 44 if len(directorUrl) == 0 { 45 ctx.JSON(500, gin.H{"error": "Bad server configuration: Director URL is not set"}) 46 return 47 } 48 rs := DiscoveryResponse{ 49 Issuer: directorUrl, 50 JwksUri: directorUrl + directorJWKSPath, 51 } 52 jsonData, err := json.MarshalIndent(rs, "", " ") 53 if err != nil { 54 ctx.JSON(500, gin.H{"error": "Failed to marshal director's discovery response"}) 55 return 56 } 57 // Append a new line to the JSON data 58 jsonData = append(jsonData, '\n') 59 ctx.Header("Content-Disposition", "attachment; filename=pelican-director-configuration.json") 60 ctx.Data(200, "application/json", jsonData) 61 } 62 63 // Returns director's public key 64 func jwksHandler(ctx *gin.Context) { 65 key, err := config.GetIssuerPublicJWKS() 66 if err != nil { 67 log.Errorf("Failed to load director's public key: %v", err) 68 ctx.JSON(500, gin.H{"error": "Failed to load director's public key"}) 69 } else { 70 jsonData, err := json.MarshalIndent(key, "", " ") 71 if err != nil { 72 ctx.JSON(500, gin.H{"error": "Failed to marshal director's public key"}) 73 return 74 } 75 // Append a new line to the JSON data 76 jsonData = append(jsonData, '\n') 77 ctx.Header("Content-Disposition", "attachment; filename=public-signing-key.jwks") 78 ctx.Data(200, "application/json", jsonData) 79 } 80 } 81 82 func RegisterDirectorAuth(router *gin.RouterGroup) { 83 router.GET(directorDiscoveryPath, discoveryHandler) 84 router.GET(directorJWKSPath, jwksHandler) 85 }