mirror of
https://gh-proxy.org/https://github.com/klinsmaya/CLIProxyAPI.git
synced 2026-11-08 01:16:47 +08:00
Merge pull request #4038 from router-for-me/plugins
feat(auth): refactor authentication handling for plugins and add tests
This commit is contained in:
@@ -7,7 +7,6 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -637,36 +636,7 @@ func sanitizePluginStorePlatforms(platforms []pluginstore.Platform) []pluginStor
|
||||
}
|
||||
|
||||
func pluginAuthConfigured(source pluginstore.Source, plugin pluginstore.Plugin, storeAuth []pluginstore.AuthConfig) bool {
|
||||
if pluginstore.AuthConfigured(storeAuth, source.URL, pluginstore.RequestKindRegistry) {
|
||||
return true
|
||||
}
|
||||
switch pluginstore.PluginInstallType(plugin) {
|
||||
case pluginstore.InstallTypeDirect:
|
||||
for _, artifact := range pluginstore.PluginArtifacts(plugin) {
|
||||
if pluginstore.AuthConfigured(storeAuth, artifact.URL, pluginstore.RequestKindArtifact) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
case pluginstore.InstallTypeGitHubRelease:
|
||||
return pluginGitHubReleaseAuthConfigured(plugin, storeAuth)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func pluginGitHubReleaseAuthConfigured(plugin pluginstore.Plugin, storeAuth []pluginstore.AuthConfig) bool {
|
||||
owner, repo, errRepository := pluginstore.GitHubRepositoryParts(plugin.Repository)
|
||||
if errRepository != nil {
|
||||
return false
|
||||
}
|
||||
releasesURL := fmt.Sprintf(
|
||||
"https://api.github.com/repos/%s/%s/releases/",
|
||||
url.PathEscape(owner),
|
||||
url.PathEscape(repo),
|
||||
)
|
||||
latestURL := releasesURL + "latest"
|
||||
tagsURL := releasesURL + "tags/"
|
||||
return pluginstore.AuthConfigured(storeAuth, latestURL, pluginstore.RequestKindMetadata) ||
|
||||
pluginstore.AuthConfigured(storeAuth, tagsURL, pluginstore.RequestKindMetadata)
|
||||
return pluginstore.PluginAuthConfigured(source, plugin, storeAuth)
|
||||
}
|
||||
|
||||
// latestPluginVersions resolves the latest release version of each registry
|
||||
|
||||
@@ -96,6 +96,37 @@ func AuthConfigured(auth []AuthConfig, requestURL string, kind string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func PluginAuthConfigured(source Source, plugin Plugin, auth []AuthConfig) bool {
|
||||
if AuthConfigured(auth, source.URL, RequestKindRegistry) {
|
||||
return true
|
||||
}
|
||||
switch PluginInstallType(plugin) {
|
||||
case InstallTypeDirect:
|
||||
for _, artifact := range PluginArtifacts(plugin) {
|
||||
if AuthConfigured(auth, artifact.URL, RequestKindArtifact) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
case InstallTypeGitHubRelease:
|
||||
return pluginGitHubReleaseAuthConfigured(plugin, auth)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func pluginGitHubReleaseAuthConfigured(plugin Plugin, auth []AuthConfig) bool {
|
||||
owner, repo, errRepository := GitHubRepositoryParts(plugin.Repository)
|
||||
if errRepository != nil {
|
||||
return false
|
||||
}
|
||||
releasesURL := fmt.Sprintf(
|
||||
"https://api.github.com/repos/%s/%s/releases/",
|
||||
url.PathEscape(owner),
|
||||
url.PathEscape(repo),
|
||||
)
|
||||
return AuthConfigured(auth, releasesURL+"latest", RequestKindMetadata) ||
|
||||
AuthConfigured(auth, releasesURL+"tags/", RequestKindMetadata)
|
||||
}
|
||||
|
||||
func applyPluginStoreAuth(headers http.Header, auth []AuthConfig, requestURL string, kind string) error {
|
||||
item, ok := matchingAuthConfig(auth, requestURL, kind)
|
||||
if !ok {
|
||||
|
||||
@@ -44,6 +44,73 @@ func TestPluginStoreAuthMatchesURLHostAndPathBoundaries(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPluginAuthConfiguredCoversInstallRequestKinds(t *testing.T) {
|
||||
t.Setenv("PLUGIN_STORE_TOKEN", "secret-token")
|
||||
|
||||
source := Source{URL: "https://registry.example/registry.json"}
|
||||
directPlugin := Plugin{
|
||||
ID: "sample-provider",
|
||||
Version: "1.0.0",
|
||||
Install: InstallPlan{
|
||||
Type: InstallTypeDirect,
|
||||
Artifacts: []Artifact{{
|
||||
GOOS: "linux",
|
||||
GOARCH: "amd64",
|
||||
URL: "https://downloads.example/private/sample-provider.zip",
|
||||
SHA256: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
|
||||
}},
|
||||
},
|
||||
}
|
||||
gitHubPlugin := Plugin{
|
||||
ID: "sample-provider",
|
||||
Repository: "https://github.com/author-name/sample-provider",
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
plugin Plugin
|
||||
auth []AuthConfig
|
||||
}{
|
||||
{
|
||||
name: "registry",
|
||||
plugin: gitHubPlugin,
|
||||
auth: []AuthConfig{{
|
||||
Match: "https://registry.example/",
|
||||
ApplyTo: []string{RequestKindRegistry},
|
||||
Type: AuthTypeBearer,
|
||||
TokenEnv: "PLUGIN_STORE_TOKEN",
|
||||
}},
|
||||
},
|
||||
{
|
||||
name: "direct artifact",
|
||||
plugin: directPlugin,
|
||||
auth: []AuthConfig{{
|
||||
Match: "https://downloads.example/private/",
|
||||
ApplyTo: []string{RequestKindArtifact},
|
||||
Type: AuthTypeBearer,
|
||||
TokenEnv: "PLUGIN_STORE_TOKEN",
|
||||
}},
|
||||
},
|
||||
{
|
||||
name: "github metadata",
|
||||
plugin: gitHubPlugin,
|
||||
auth: []AuthConfig{{
|
||||
Match: "https://api.github.com/repos/author-name/sample-provider/releases/",
|
||||
ApplyTo: []string{RequestKindMetadata},
|
||||
Type: AuthTypeBearer,
|
||||
TokenEnv: "PLUGIN_STORE_TOKEN",
|
||||
}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if !PluginAuthConfigured(source, tt.plugin, tt.auth) {
|
||||
t.Fatal("PluginAuthConfigured() = false, want true")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPluginStoreAuthHeaderIsReevaluatedAcrossRedirect(t *testing.T) {
|
||||
t.Setenv("PLUGIN_STORE_HEADER", "secret-token")
|
||||
|
||||
|
||||
@@ -106,6 +106,10 @@ func AuthConfigured(auth []AuthConfig, requestURL string, kind string) bool {
|
||||
return internalpluginstore.AuthConfigured(auth, requestURL, kind)
|
||||
}
|
||||
|
||||
func PluginAuthConfigured(source Source, plugin Plugin, auth []AuthConfig) bool {
|
||||
return internalpluginstore.PluginAuthConfigured(source, plugin, auth)
|
||||
}
|
||||
|
||||
func UpdateAvailable(installed, latest string) bool {
|
||||
return internalpluginstore.UpdateAvailable(installed, latest)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user