1
0
forked from baron/baron-sso

chore: consolidate local integration changes

This commit is contained in:
2026-06-09 21:03:05 +09:00
parent aa2848c3b6
commit 1341f07ef9
158 changed files with 10995 additions and 1490 deletions

View File

@@ -9,6 +9,7 @@ import (
"io"
"net"
"net/http"
"net/url"
"os"
"strings"
"time"
@@ -68,27 +69,76 @@ func NewKratosAdminService() KratosAdminService {
func (s *kratosAdminService) ListIdentities(ctx context.Context) ([]KratosIdentity, error) {
endpoint := strings.TrimRight(s.AdminURL, "/") + "/admin/identities"
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
if err != nil {
return nil, err
}
resp, err := s.httpClient().Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode >= 300 {
body, _ := io.ReadAll(io.LimitReader(resp.Body, 2048))
return nil, fmt.Errorf("kratos admin list identities failed status=%d body=%s", resp.StatusCode, string(body))
}
var identities []KratosIdentity
if err := json.NewDecoder(resp.Body).Decode(&identities); err != nil {
return nil, err
pageToken := ""
seenTokens := make(map[string]bool)
for {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
if err != nil {
return nil, err
}
query := req.URL.Query()
query.Set("page_size", "250")
if pageToken != "" {
query.Set("page_token", pageToken)
}
req.URL.RawQuery = query.Encode()
resp, err := s.httpClient().Do(req)
if err != nil {
return nil, err
}
if resp.StatusCode >= 300 {
body, _ := io.ReadAll(io.LimitReader(resp.Body, 2048))
_ = resp.Body.Close()
return nil, fmt.Errorf("kratos admin list identities failed status=%d body=%s", resp.StatusCode, string(body))
}
var page []KratosIdentity
if err := json.NewDecoder(resp.Body).Decode(&page); err != nil {
_ = resp.Body.Close()
return nil, err
}
_ = resp.Body.Close()
identities = append(identities, page...)
nextToken := kratosNextPageToken(resp.Header.Values("Link"))
if nextToken == "" {
return identities, nil
}
if seenTokens[nextToken] {
return nil, fmt.Errorf("kratos admin list identities pagination loop detected page_token=%s", nextToken)
}
seenTokens[nextToken] = true
pageToken = nextToken
}
return identities, nil
}
func kratosNextPageToken(linkHeaders []string) string {
for _, header := range linkHeaders {
for _, part := range strings.Split(header, ",") {
part = strings.TrimSpace(part)
if !strings.Contains(part, `rel="next"`) && !strings.Contains(part, `rel=next`) {
continue
}
start := strings.Index(part, "<")
end := strings.Index(part, ">")
if start < 0 || end <= start+1 {
continue
}
rawURL := part[start+1 : end]
parsed, err := url.Parse(rawURL)
if err != nil {
continue
}
if token := strings.TrimSpace(parsed.Query().Get("page_token")); token != "" {
return token
}
}
}
return ""
}
func (s *kratosAdminService) FindIdentityIDByIdentifier(ctx context.Context, identifier string) (string, error) {