1
0
forked from baron/baron-sso

애플리케이션(RP) 관리 기능 구현 및 Ory Keto 권한 연동

This commit is contained in:
2026-02-04 14:56:16 +09:00
parent bf469b1eb4
commit 066ea86f46
14 changed files with 232 additions and 48 deletions

View File

@@ -10,6 +10,7 @@ import (
"net/http"
"net/url"
"os"
"time"
)
type KetoService interface {
@@ -87,22 +88,34 @@ func (s *ketoService) CreateRelation(ctx context.Context, namespace, object, rel
}
body, _ := json.Marshal(payload)
req, _ := http.NewRequestWithContext(ctx, "PUT", u, bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
// Exponential Backoff Retry Logic
var lastErr error
maxRetries := 3
backoff := 100 * time.Millisecond
resp, err := s.client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
for i := 0; i < maxRetries; i++ {
req, _ := http.NewRequestWithContext(ctx, "PUT", u, bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
if resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusNoContent && resp.StatusCode != http.StatusOK {
resBody, _ := io.ReadAll(resp.Body)
return fmt.Errorf("keto returned status %d: %s", resp.StatusCode, string(resBody))
resp, err := s.client.Do(req)
if err == nil {
defer resp.Body.Close()
if resp.StatusCode == http.StatusCreated || resp.StatusCode == http.StatusNoContent || resp.StatusCode == http.StatusOK {
slog.Info("Keto relation created", "namespace", namespace, "object", object, "relation", relation, "subject", subject)
return nil
}
resBody, _ := io.ReadAll(resp.Body)
lastErr = fmt.Errorf("keto returned status %d: %s", resp.StatusCode, string(resBody))
} else {
lastErr = err
}
time.Sleep(backoff)
backoff *= 2
}
slog.Info("Keto relation created", "namespace", namespace, "object", object, "relation", relation, "subject", subject)
return nil
slog.Error("Keto create relation failed after retries", "error", lastErr)
return lastErr
}
func (s *ketoService) DeleteRelation(ctx context.Context, namespace, object, relation, subject string) error {