init
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
@@ -45,8 +46,8 @@ type apiUser struct {
|
||||
|
||||
func NewClient(baseURL string, auth Auth) *Client {
|
||||
return &Client{
|
||||
baseURL: strings.TrimRight(baseURL, "/"),
|
||||
auth: auth,
|
||||
baseURL: strings.TrimRight(baseURL, "/"),
|
||||
auth: auth,
|
||||
httpClient: &http.Client{Timeout: 20 * time.Second},
|
||||
}
|
||||
}
|
||||
@@ -80,7 +81,7 @@ func (c *Client) ListOrgSkills(ctx context.Context, org string) ([]domain.Remote
|
||||
Name: repo.Name,
|
||||
FullName: repo.FullName,
|
||||
Description: repo.Description,
|
||||
CloneURL: repo.CloneURL,
|
||||
CloneURL: normalizeCloneURL(repo.CloneURL, c.baseURL),
|
||||
SSHURL: repo.SSHURL,
|
||||
DefaultBranch: repo.DefaultBranch,
|
||||
UpdatedAt: repo.UpdatedAt,
|
||||
@@ -175,3 +176,34 @@ func (c *Client) newRequest(ctx context.Context, method, endpoint string) (*http
|
||||
req.Header.Set("Accept", "application/json")
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func normalizeCloneURL(cloneURL, baseURL string) string {
|
||||
clone, err := url.Parse(cloneURL)
|
||||
if err != nil || clone.Scheme == "" || clone.Host == "" {
|
||||
return cloneURL
|
||||
}
|
||||
if clone.Scheme != "http" && clone.Scheme != "https" {
|
||||
return cloneURL
|
||||
}
|
||||
if !isLoopbackHost(clone.Hostname()) {
|
||||
return cloneURL
|
||||
}
|
||||
base, err := url.Parse(baseURL)
|
||||
if err != nil || base.Scheme == "" || base.Host == "" {
|
||||
return cloneURL
|
||||
}
|
||||
if clone.Scheme == base.Scheme && strings.EqualFold(clone.Host, base.Host) {
|
||||
return cloneURL
|
||||
}
|
||||
clone.Scheme = base.Scheme
|
||||
clone.Host = base.Host
|
||||
return clone.String()
|
||||
}
|
||||
|
||||
func isLoopbackHost(host string) bool {
|
||||
if strings.EqualFold(host, "localhost") {
|
||||
return true
|
||||
}
|
||||
ip := net.ParseIP(host)
|
||||
return ip != nil && ip.IsLoopback()
|
||||
}
|
||||
|
||||
@@ -44,6 +44,31 @@ func TestListOrgSkillsFiltersReposWithoutSkillMD(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestListOrgSkillsNormalizesLoopbackCloneURLToConfiguredBaseURL(t *testing.T) {
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/api/v1/orgs/skills/repos", func(w http.ResponseWriter, r *http.Request) {
|
||||
_ = json.NewEncoder(w).Encode([]apiRepo{
|
||||
{Name: "good", FullName: "skills/good", CloneURL: "http://localhost:3000/skills/good.git", DefaultBranch: "main"},
|
||||
})
|
||||
})
|
||||
mux.HandleFunc("/api/v1/repos/skills/good/contents/SKILL.md", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
server := httptest.NewServer(mux)
|
||||
defer server.Close()
|
||||
|
||||
client := NewClient(server.URL, Auth{Type: AuthPassword, Username: "alice", Secret: "secret"})
|
||||
repos, err := client.ListOrgSkills(context.Background(), "skills")
|
||||
if err != nil {
|
||||
t.Fatalf("ListOrgSkills returned error: %v", err)
|
||||
}
|
||||
|
||||
want := server.URL + "/skills/good.git"
|
||||
if repos[0].CloneURL != want {
|
||||
t.Fatalf("CloneURL = %q, want %q", repos[0].CloneURL, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestListOrgSkillsUsesTokenAuth(t *testing.T) {
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/api/v1/orgs/skills/repos", func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
Reference in New Issue
Block a user