Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add simple verification to namespace registration #94

Merged
merged 1 commit into from
Sep 6, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 62 additions & 16 deletions namespace-registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,30 @@ func keySignChallengeCommit(ctx *gin.Context, data *registrationData, action str
if clientVerified && serverVerified {
if action == "register" {
log.Debug("Registering namespace ", data.Prefix)

// Check if prefix exists before doing anything else
exists, err := namespaceExists(data.Prefix)
if err != nil {
log.Errorf("Failed to check if namespace already exists: %v", err)
return errors.Wrap(err, "Server encountered an error checking if namespace already exists")
}
if exists {
return errors.New("The prefix already is registered")
}
reqPrefix, err := validateNSPath(data.Prefix)
if err != nil {
err = errors.Wrapf(err, "Requested namespace %s failed validation", reqPrefix)
log.Errorln(err)
return err
}
data.Prefix = reqPrefix

// Verify the requested path is a valid prefix
if err != nil {
ctx.JSON(http.StatusForbidden, gin.H{"error": "Namespace prefix cannot be registered as it is invalid"})
return errors.Wrapf(err, "Namespace prefix %s cannot be registered as it is invalid", data.Prefix)
}

err = dbAddNamespace(ctx, data)
if err != nil {
ctx.JSON(500, gin.H{"error": "The server encountered an error while attempting to add the prefix to its database"})
Expand All @@ -329,6 +353,42 @@ func keySignChallengeCommit(ctx *gin.Context, data *registrationData, action str
return nil
}

func validateNSPath(nspath string) (string, error) {
if len(nspath) == 0 {
return "", errors.New("Path prefix may not be empty")
}
if nspath[0] != '/' {
return "", errors.New("Path prefix must be absolute - relative paths are not allowed")
}
components := strings.Split(nspath, "/")[1:]
if len(components) == 0 {
return "", errors.New("Cannot register the prefix '/' for an origin")
} else if components[0] == "api" {
return "", errors.New("Cannot register a prefix starting with '/api'")
} else if components[0] == "view" {
return "", errors.New("Cannot register a prefix starting with '/view'")
} else if components[0] == "pelican" {
return "", errors.New("Cannot register a prefix starting with '/pelican'")
}
result := ""
for _, component := range components {
if len(component) == 0 {
continue
} else if component == "." {
return "", errors.New("Path component cannot be '.'")
} else if component == ".." {
return "", errors.New("Path component cannot be '..'")
} else if component[0] == '.' {
return "", errors.New("Path component cannot begin with a '.'")
}
result += "/" + component
}
if result == "/" || len(result) == 0 {
return "", errors.New("Cannot register the prefix '/' for an origin")
}
return result, nil
}

/*
Handler functions called upon by the gin router
*/
Expand All @@ -340,19 +400,6 @@ func cliRegisterNamespace(ctx *gin.Context) {
return
}

// Check if prefix exists before doing anything else
exists, err := namespaceExists(reqData.Prefix)
if err != nil {
log.Errorf("failed to check if namespace already exists: %v", err)
ctx.JSON(http.StatusInternalServerError, gin.H{"error": "server encountered an error checking if namespace already exists"})
return
}
if exists {
ctx.JSON(http.StatusInternalServerError, gin.H{"error": "The prefix already exists so it cannot be created. Did you mean to update it?"})
log.Errorf("namespace prefix %s already exists so it cannot be created", reqData.Prefix)
return
}

if reqData.AccessToken != "" {
payload := url.Values{}
payload.Set("access_token", reqData.AccessToken)
Expand Down Expand Up @@ -404,7 +451,7 @@ func cliRegisterNamespace(ctx *gin.Context) {
return
}

err = loadOIDC()
err := loadOIDC()
if err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{"error": "server has malformed OIDC configuration"})
log.Errorf("Failed to load OIDC information for registration with identity: %v", err)
Expand Down Expand Up @@ -554,9 +601,8 @@ func dbDeleteNamespace(ctx *gin.Context) {
return
}
if !exists {
ctx.JSON(http.StatusInternalServerError, gin.H{"error": "the prefix does not exist so it cannot be deleted"})
ctx.JSON(http.StatusBadRequest, gin.H{"error": "the prefix does not exist so it cannot be deleted"})
log.Errorln("prefix could not be deleted because it does not exist")
return
}

/*
Expand Down
Loading