Skip to content

Commit

Permalink
WIP: Add registration API between origin and director
Browse files Browse the repository at this point in the history
This work-in-progress commit sketches out a new REST API for the
origin to register itself (and its available namespaces) with the
director.

The bones on the server side are there; the invocation from the
origin (and the generation of the data at the origin) are not.
  • Loading branch information
bbockelm committed Jul 28, 2023
1 parent 6abff85 commit b73113a
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 2 deletions.
4 changes: 2 additions & 2 deletions director/origin_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type (
OriginAdvertise struct {
Name string `json:"name"`
URL string `json:"url"`
Namespace string `json:"namespace"`
Namespaces []NamespaceAd `json:"namespaces"`
}

)
Expand Down Expand Up @@ -96,7 +96,7 @@ func VerifyAdvertiseToken(token, namespace string) (bool, error) {
return false, err
}

tok, err := jwt.Parse([]byte(token), jwt.WithKeySet(keyset))
tok, err := jwt.Parse([]byte(token), jwt.WithKeySet(keyset), jwt.WithValidate(true))
if err != nil {
return false, err
}
Expand Down
46 changes: 46 additions & 0 deletions director/redirect.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strings"

"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
)

func getRedirectURL(reqPath string, ad ServerAd, requiresAuth bool) (redirectURL url.URL) {
Expand Down Expand Up @@ -154,8 +155,53 @@ func ShortcutMiddleware() gin.HandlerFunc {
}
}

func RegisterOrigin (ctx *gin.Context) {
tokens, present := ctx.Request.Header["Authorization"]
if !present || len(tokens) == 0 {
ctx.JSON(401, gin.H{"error": "Bearer token not present in the 'Authorization' header"})
return
}
ad := OriginAdvertise{}
if ctx.ShouldBind(&ad) != nil {
ctx.JSON(400, gin.H{"error": "Invalid origin registration"})
return
}

for _, namespace := range(ad.Namespaces) {
ok, err := VerifyAdvertiseToken(tokens[0], namespace.Path)
if err != nil {
log.Warningln("Failed to verify token:", err)
ctx.JSON(400, gin.H{"error": "Authorization token verification failed"})
return
}
if !ok {
log.Warningf("Origin %v advertised to namespace %v without valid registration\n",
ad.Name, namespace.Path)
ctx.JSON(400, gin.H{"error": "Origin not authorized to advertise to this namespace"})
return
}
}

ad_url, err := url.Parse(ad.URL)
if err != nil {
log.Warningf("Failed to parse origin URL %v: %v\n", ad.URL, err)
ctx.JSON(400, gin.H{"error": "Invalid origin URL"})
return
}

originAd := ServerAd{
Name: ad.Name,
AuthURL: *ad_url,
URL: *ad_url,
Type: OriginType,
}
RecordAd(originAd, &ad.Namespaces)
ctx.JSON(200, gin.H{"msg": "Successful registration"})
}

func RegisterDirector(router *gin.RouterGroup) {
// Establish the routes used for cache/origin redirection
router.GET("/api/v1.0/director/object/*any", RedirectToCache)
router.GET("/api/v1.0/director/origin/*any", RedirectToOrigin)
router.POST("/api/v1.0/director/registerOrigin", RegisterOrigin)
}
25 changes: 25 additions & 0 deletions origin_ui/advertise.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package origin_ui

import (
"errors"

"github.com/pelicanplatform/pelican/director"
"github.com/spf13/viper"
)

func AdvertiseOrigin() error {
name := viper.GetString("Sitename")
if name == "" {
return errors.New("Origin name isn't set")
}
// TODO: waiting on a different branch to merge origin URL generation
url := "https://localhost:8444"

ad := director.OriginAdvertise{
Name: name,
URL: url,
Namespaces: make([]director.NamespaceAd, 0),
}
_ = ad
return nil
}

0 comments on commit b73113a

Please sign in to comment.