Neo OcLib
This commit is contained in:
@@ -21,6 +21,7 @@ import (
|
||||
)
|
||||
|
||||
type HydraConnector struct {
|
||||
Mu sync.RWMutex
|
||||
Caller *tools.HTTPCaller
|
||||
cookieJars sync.Map // map[loginChallenge] *cookiejar.Jar
|
||||
}
|
||||
@@ -33,6 +34,8 @@ func (h *HydraConnector) Status() tools.State {
|
||||
host = "localhost"
|
||||
}
|
||||
port := fmt.Sprintf("%v", conf.GetConfig().AuthConnectorPort)
|
||||
h.Mu.Lock()
|
||||
defer h.Mu.Unlock()
|
||||
resp, err := caller.CallGet("http://"+host+":"+port, "/health/ready")
|
||||
if err != nil {
|
||||
return tools.DEAD
|
||||
@@ -120,6 +123,8 @@ func (h *HydraConnector) InitiateLogin(clientID string, redirectURI string) (str
|
||||
// GetLoginChallenge retrieves login challenge details from Hydra admin API
|
||||
func (h *HydraConnector) GetLoginChallenge(challenge string) (*LoginChallenge, error) {
|
||||
logger := oclib.GetLogger()
|
||||
h.Mu.Lock()
|
||||
defer h.Mu.Unlock()
|
||||
resp, err := h.Caller.CallGet(h.getPath(true, true), "/auth/requests/login?login_challenge="+url.QueryEscape(challenge))
|
||||
if err != nil {
|
||||
logger.Error().Msg("Failed to get login challenge: " + err.Error())
|
||||
@@ -141,6 +146,8 @@ func (h *HydraConnector) AcceptLogin(challenge string, subject string) (*Redirec
|
||||
"remember": true,
|
||||
"remember_for": 3600,
|
||||
}
|
||||
h.Mu.Lock()
|
||||
defer h.Mu.Unlock()
|
||||
resp, err := h.Caller.CallRaw(http.MethodPut,
|
||||
h.getPath(true, true), "/auth/requests/login/accept?login_challenge="+url.QueryEscape(challenge),
|
||||
body, "application/json", true)
|
||||
@@ -170,6 +177,8 @@ func (h *HydraConnector) RejectLogin(challenge string, reason string) (*Redirect
|
||||
"error": "access_denied",
|
||||
"error_description": reason,
|
||||
}
|
||||
h.Mu.Lock()
|
||||
defer h.Mu.Unlock()
|
||||
resp, err := h.Caller.CallRaw(http.MethodPut,
|
||||
h.getPath(true, true), "/auth/requests/login/reject?login_challenge="+url.QueryEscape(challenge),
|
||||
body, "application/json", true)
|
||||
@@ -192,6 +201,8 @@ func (h *HydraConnector) RejectLogin(challenge string, reason string) (*Redirect
|
||||
// GetLogoutChallenge retrieves logout challenge details from Hydra admin API
|
||||
func (h *HydraConnector) GetLogoutChallenge(challenge string) (*LogoutChallenge, error) {
|
||||
logger := oclib.GetLogger()
|
||||
h.Mu.Lock()
|
||||
defer h.Mu.Unlock()
|
||||
resp, err := h.Caller.CallGet(h.getPath(true, true), "/auth/requests/logout?logout_challenge="+url.QueryEscape(challenge))
|
||||
if err != nil {
|
||||
logger.Error().Msg("Failed to get logout challenge: " + err.Error())
|
||||
@@ -208,6 +219,8 @@ func (h *HydraConnector) GetLogoutChallenge(challenge string) (*LogoutChallenge,
|
||||
// AcceptLogout accepts a logout challenge — invalidates the Hydra session
|
||||
func (h *HydraConnector) AcceptLogout(challenge string) (*Redirect, error) {
|
||||
logger := oclib.GetLogger()
|
||||
h.Mu.Lock()
|
||||
defer h.Mu.Unlock()
|
||||
resp, err := h.Caller.CallRaw(http.MethodPut,
|
||||
h.getPath(true, true), "/auth/requests/logout/accept?logout_challenge="+url.QueryEscape(challenge),
|
||||
nil, "application/json", true)
|
||||
@@ -233,6 +246,8 @@ func (h *HydraConnector) AcceptLogout(challenge string) (*Redirect, error) {
|
||||
// GetConsentChallenge retrieves consent challenge details from Hydra admin API
|
||||
func (h *HydraConnector) GetConsentChallenge(challenge string) (*ConsentChallenge, error) {
|
||||
logger := oclib.GetLogger()
|
||||
h.Mu.Lock()
|
||||
defer h.Mu.Unlock()
|
||||
resp, err := h.Caller.CallGet(h.getPath(true, true), "/auth/requests/consent?consent_challenge="+url.QueryEscape(challenge))
|
||||
if err != nil {
|
||||
logger.Error().Msg("Failed to get consent challenge: " + err.Error())
|
||||
@@ -259,6 +274,8 @@ func (h *HydraConnector) AcceptConsent(challenge string, grantScope []string, se
|
||||
"id_token": session.Session.IDToken,
|
||||
},
|
||||
}
|
||||
h.Mu.Lock()
|
||||
defer h.Mu.Unlock()
|
||||
resp, err := h.Caller.CallRaw(http.MethodPut,
|
||||
h.getPath(true, true), "/auth/requests/consent/accept?consent_challenge="+url.QueryEscape(challenge),
|
||||
body, "application/json", true)
|
||||
@@ -286,6 +303,8 @@ func (h *HydraConnector) Introspect(token string) (*IntrospectResult, error) {
|
||||
logger := oclib.GetLogger()
|
||||
urls := url.Values{}
|
||||
urls.Add("token", token)
|
||||
h.Mu.Lock()
|
||||
defer h.Mu.Unlock()
|
||||
resp, err := h.Caller.CallForm(http.MethodPost, h.getPath(true, true), "/introspect", urls,
|
||||
"application/x-www-form-urlencoded", true)
|
||||
if err != nil {
|
||||
@@ -314,6 +333,8 @@ func (h *HydraConnector) RevokeToken(token string, clientID string) error {
|
||||
urls.Add("token", token)
|
||||
urls.Add("client_id", clientID)
|
||||
urls.Add("client_secret", conf.GetConfig().ClientSecret)
|
||||
h.Mu.Lock()
|
||||
defer h.Mu.Unlock()
|
||||
resp, err := h.Caller.CallForm(http.MethodPost, h.getPath(false, true), "/revoke", urls,
|
||||
"application/x-www-form-urlencoded", true)
|
||||
if err != nil {
|
||||
@@ -336,6 +357,8 @@ func (h *HydraConnector) RefreshToken(refreshToken string, clientID string) (*To
|
||||
urls.Add("refresh_token", refreshToken)
|
||||
urls.Add("client_id", clientID)
|
||||
urls.Add("client_secret", conf.GetConfig().ClientSecret)
|
||||
h.Mu.Lock()
|
||||
defer h.Mu.Unlock()
|
||||
resp, err := h.Caller.CallForm(http.MethodPost, h.getPath(false, true), "/token", urls,
|
||||
"application/x-www-form-urlencoded", true)
|
||||
if err != nil {
|
||||
@@ -393,7 +416,7 @@ func (h *HydraConnector) CheckAuthForward(reqToken string, publicKey string, hos
|
||||
}
|
||||
|
||||
// For SELF peer requests skip the signature check (internal traffic).
|
||||
pp := oclib.NewRequest(oclib.LibDataEnum(oclib.PEER), "", "", []string{}, nil).Search(nil, fmt.Sprintf("%v", peer.SELF.EnumIndex()), false)
|
||||
pp := oclib.NewRequest(oclib.LibDataEnum(oclib.PEER), "", "", []string{}, nil).Search(nil, fmt.Sprintf("%v", peer.SELF.EnumIndex()), false, 0, 1)
|
||||
if len(pp.Data) > 0 {
|
||||
p := pp.Data[0].(*peer.Peer)
|
||||
if p.PublicKey == publicKey {
|
||||
@@ -501,6 +524,8 @@ func (h *HydraConnector) ExchangeCodeForToken(redirectTo string, clientID string
|
||||
vals.Add("client_id", clientID)
|
||||
vals.Add("client_secret", cfg.ClientSecret)
|
||||
vals.Add("redirect_uri", redirectURI)
|
||||
h.Mu.Lock()
|
||||
defer h.Mu.Unlock()
|
||||
resp2, err := h.Caller.CallForm(http.MethodPost, h.getPath(false, true), "/token", vals,
|
||||
"application/x-www-form-urlencoded", true)
|
||||
if err != nil {
|
||||
|
||||
@@ -99,9 +99,20 @@ func New(privateKey []byte, publicKeys map[string][]byte) (client *Client, err e
|
||||
if privateKey != nil {
|
||||
validPrivateKey, errPrivate := x509.ParsePKCS1PrivateKey(privateKey)
|
||||
if errPrivate != nil {
|
||||
err = errPrivate
|
||||
log.Println(err)
|
||||
return
|
||||
// Fallback to PKCS8 (generated with openssl genpkey or similar)
|
||||
key, errPKCS8 := x509.ParsePKCS8PrivateKey(privateKey)
|
||||
if errPKCS8 != nil {
|
||||
err = errPKCS8
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
rsaKey, ok := key.(*rsa.PrivateKey)
|
||||
if !ok {
|
||||
err = errors.New("PKCS8 private key is not RSA")
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
validPrivateKey = rsaKey
|
||||
}
|
||||
client.PrivateKey = validPrivateKey
|
||||
}
|
||||
@@ -111,9 +122,20 @@ func New(privateKey []byte, publicKeys map[string][]byte) (client *Client, err e
|
||||
for k, v := range publicKeys {
|
||||
validPublicKey, errPublic := x509.ParsePKCS1PublicKey(v)
|
||||
if errPublic != nil {
|
||||
err = errPublic
|
||||
log.Println(err)
|
||||
return
|
||||
// Fallback to PKIX (SubjectPublicKeyInfo, generated alongside PKCS8 private key)
|
||||
key, errPKIX := x509.ParsePKIXPublicKey(v)
|
||||
if errPKIX != nil {
|
||||
err = errPKIX
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
rsaKey, ok := key.(*rsa.PublicKey)
|
||||
if !ok {
|
||||
err = errors.New("PKIX public key is not RSA")
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
validPublicKey = rsaKey
|
||||
}
|
||||
if validPublicKey == nil {
|
||||
err = errors.New("Invalid Public Key Type")
|
||||
|
||||
@@ -2,12 +2,10 @@ package claims
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"oc-auth/conf"
|
||||
"fmt"
|
||||
"oc-auth/infrastructure/perms_connectors"
|
||||
"oc-auth/infrastructure/utils"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
oclib "cloud.o-forge.io/core/oc-lib"
|
||||
@@ -44,7 +42,7 @@ func (h HydraClaims) decodeKey(key string, external bool) (tools.METHOD, string,
|
||||
}
|
||||
|
||||
func (h HydraClaims) DecodeSignature(host string, signature string, publicKey string) (bool, error) {
|
||||
hashed := sha256.Sum256([]byte(host))
|
||||
/*hashed := sha256.Sum256([]byte(host))
|
||||
spkiBlock, _ := pem.Decode([]byte(publicKey))
|
||||
if spkiBlock == nil {
|
||||
return false, errors.New("failed to decode public key PEM")
|
||||
@@ -52,22 +50,22 @@ func (h HydraClaims) DecodeSignature(host string, signature string, publicKey st
|
||||
err := VerifyDefault(hashed[:], spkiBlock.Bytes, signature)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
}*/
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (h HydraClaims) encodeSignature(host string) (string, error) {
|
||||
hashed := sha256.Sum256([]byte(host))
|
||||
content, err := os.ReadFile(conf.GetConfig().PrivateKeyPath)
|
||||
return "", nil
|
||||
priv, err := tools.LoadKeyFromFilePrivate()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
privateKey := string(content)
|
||||
spkiBlock, _ := pem.Decode([]byte(privateKey))
|
||||
if spkiBlock == nil {
|
||||
return "", errors.New("failed to decode private key PEM")
|
||||
privb, err := priv.Raw()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return SignDefault(hashed[:], spkiBlock.Bytes)
|
||||
hashed := sha256.Sum256([]byte(host))
|
||||
return SignDefault(hashed[:], privb)
|
||||
}
|
||||
|
||||
func (h HydraClaims) clearBlank(path []string) []string {
|
||||
@@ -88,12 +86,14 @@ func (h HydraClaims) DecodeClaimsInToken(host string, method string, forward str
|
||||
// Signature verification: skip if signature is empty (internal requests)
|
||||
if sig, ok := idTokenClaims["signature"].(string); ok && sig != "" {
|
||||
if ok, err := h.DecodeSignature(host, sig, publicKey); !ok {
|
||||
fmt.Println("FAILED SIGNATURE")
|
||||
return false, "", err
|
||||
}
|
||||
}
|
||||
|
||||
claims := sessionClaims.Session.AccessToken
|
||||
if claims == nil {
|
||||
fmt.Println("no access_token claims found")
|
||||
return false, "", errors.New("no access_token claims found")
|
||||
}
|
||||
path := strings.ReplaceAll(forward, "http://"+host, "")
|
||||
@@ -138,7 +138,7 @@ func (h HydraClaims) DecodeClaimsInToken(host string, method string, forward str
|
||||
func (h HydraClaims) BuildConsentSession(clientID string, userId string, p *peer.Peer) Claims {
|
||||
logger := oclib.GetLogger()
|
||||
c := Claims{}
|
||||
perms, err := perms_connectors.KetoConnector{}.GetPermissionByUser(userId, true)
|
||||
perms, err := (&perms_connectors.KetoConnector{}).GetPermissionByUser(userId, true)
|
||||
if err != nil {
|
||||
logger.Error().Msg("Failed to get permissions for user " + userId + ": " + err.Error())
|
||||
return c
|
||||
@@ -160,7 +160,7 @@ func (h HydraClaims) BuildConsentSession(clientID string, userId string, p *peer
|
||||
logger.Error().Msg("Failed to encode signature: " + err.Error())
|
||||
return c
|
||||
}
|
||||
|
||||
fmt.Println("PEER ID", p.UUID)
|
||||
c.Session.AccessToken["peer_id"] = p.UUID
|
||||
c.Session.AccessToken["user_id"] = userId
|
||||
|
||||
@@ -168,7 +168,7 @@ func (h HydraClaims) BuildConsentSession(clientID string, userId string, p *peer
|
||||
c.Session.IDToken["peer_id"] = p.UUID
|
||||
c.Session.IDToken["client_id"] = clientID
|
||||
|
||||
groups, err := perms_connectors.KetoConnector{}.GetGroupByUser(userId)
|
||||
groups, err := (&perms_connectors.KetoConnector{}).GetGroupByUser(userId)
|
||||
if err != nil {
|
||||
logger.Error().Msg("Failed to get groups for user " + userId + ": " + err.Error())
|
||||
return c
|
||||
@@ -176,7 +176,7 @@ func (h HydraClaims) BuildConsentSession(clientID string, userId string, p *peer
|
||||
c.Session.AccessToken["groups"] = groups
|
||||
c.Session.IDToken["groups"] = groups
|
||||
|
||||
roles, err := perms_connectors.KetoConnector{}.GetRoleByUser(userId)
|
||||
roles, err := (&perms_connectors.KetoConnector{}).GetRoleByUser(userId)
|
||||
if err != nil {
|
||||
logger.Error().Msg("Failed to get roles for user " + userId + ": " + err.Error())
|
||||
return c
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"oc-auth/conf"
|
||||
"oc-auth/infrastructure/utils"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
oclib "cloud.o-forge.io/core/oc-lib"
|
||||
"cloud.o-forge.io/core/oc-lib/tools"
|
||||
@@ -14,21 +15,22 @@ import (
|
||||
|
||||
type KetoConnector struct {
|
||||
Client string
|
||||
Mu sync.RWMutex
|
||||
}
|
||||
|
||||
func (k KetoConnector) SetClient(client string) {
|
||||
func (k *KetoConnector) SetClient(client string) {
|
||||
k.Client = client
|
||||
}
|
||||
|
||||
func (k KetoConnector) namespace() string {
|
||||
func (k *KetoConnector) namespace() string {
|
||||
return "open-cloud"
|
||||
}
|
||||
|
||||
func (k KetoConnector) scope() string {
|
||||
func (k *KetoConnector) scope() string {
|
||||
return "oc-auth-realm"
|
||||
}
|
||||
|
||||
func (f KetoConnector) permToQuery(perm Permission, permDependancies *Permission) string {
|
||||
func (f *KetoConnector) permToQuery(perm Permission, permDependancies *Permission) string {
|
||||
n := "?namespace=" + f.namespace()
|
||||
if perm.Object != "" {
|
||||
n += "&object=" + perm.Object
|
||||
@@ -54,7 +56,7 @@ func (f KetoConnector) permToQuery(perm Permission, permDependancies *Permission
|
||||
return n
|
||||
}
|
||||
|
||||
func (k KetoConnector) Status() tools.State {
|
||||
func (k *KetoConnector) Status() tools.State {
|
||||
caller := tools.NewHTTPCaller(map[tools.DataType]map[tools.METHOD]string{})
|
||||
var responseBody map[string]interface{}
|
||||
host := conf.GetConfig().PermissionConnectorReadHost
|
||||
@@ -62,6 +64,8 @@ func (k KetoConnector) Status() tools.State {
|
||||
host = "localhost"
|
||||
}
|
||||
port := fmt.Sprintf("%v", conf.GetConfig().PermissionConnectorPort)
|
||||
k.Mu.Lock()
|
||||
defer k.Mu.Unlock()
|
||||
resp, err := caller.CallGet("http://"+host+":"+port, "/health/ready")
|
||||
if err != nil {
|
||||
return tools.DEAD
|
||||
@@ -73,7 +77,7 @@ func (k KetoConnector) Status() tools.State {
|
||||
return tools.ALIVE
|
||||
}
|
||||
|
||||
func (k KetoConnector) CheckPermission(perm Permission, permDependancies *Permission, internal bool) bool {
|
||||
func (k *KetoConnector) CheckPermission(perm Permission, permDependancies *Permission, internal bool) bool {
|
||||
if (perm.Object == k.scope() || perm.Subject == k.scope()) && !internal {
|
||||
log := oclib.GetLogger()
|
||||
log.Error().Msg("Permission denied : Ask illegal permission")
|
||||
@@ -88,7 +92,7 @@ func (k KetoConnector) CheckPermission(perm Permission, permDependancies *Permis
|
||||
return len(perms) > 0
|
||||
}
|
||||
|
||||
func (k KetoConnector) deletes(object string, relation string, subject string, relation2 string) (string, int, error) {
|
||||
func (k *KetoConnector) deletes(object string, relation string, subject string, relation2 string) (string, int, error) {
|
||||
k.deleteRelationShip(object, relation, subject, nil)
|
||||
_, code, err := k.deleteRelationShip(subject, relation2, k.scope(), nil)
|
||||
if err != nil {
|
||||
@@ -97,15 +101,15 @@ func (k KetoConnector) deletes(object string, relation string, subject string, r
|
||||
return subject, 200, nil
|
||||
}
|
||||
|
||||
func (k KetoConnector) DeleteRole(roleID string) (string, int, error) {
|
||||
func (k *KetoConnector) DeleteRole(roleID string) (string, int, error) {
|
||||
return k.deletes("", "member", roleID, "is")
|
||||
}
|
||||
|
||||
func (k KetoConnector) DeleteGroup(groupID string) (string, int, error) {
|
||||
func (k *KetoConnector) DeleteGroup(groupID string) (string, int, error) {
|
||||
return k.deletes("", "groups", groupID, "groupin")
|
||||
}
|
||||
|
||||
func (k KetoConnector) DeletePermission(permID string, relation string, internal bool) (string, int, error) {
|
||||
func (k *KetoConnector) DeletePermission(permID string, relation string, internal bool) (string, int, error) {
|
||||
meth, err := utils.ExtractMethod(relation, internal)
|
||||
if err != nil {
|
||||
for _, method := range []tools.METHOD{tools.GET, tools.PUT, tools.POST, tools.DELETE} {
|
||||
@@ -116,15 +120,15 @@ func (k KetoConnector) DeletePermission(permID string, relation string, internal
|
||||
return k.deletes("", "groups", permID, "permits"+meth.String())
|
||||
}
|
||||
|
||||
func (k KetoConnector) CreateRole(roleID string) (string, int, error) {
|
||||
func (k *KetoConnector) CreateRole(roleID string) (string, int, error) {
|
||||
return k.creates(roleID, "is", k.scope())
|
||||
}
|
||||
|
||||
func (k KetoConnector) CreateGroup(groupID string) (string, int, error) {
|
||||
func (k *KetoConnector) CreateGroup(groupID string) (string, int, error) {
|
||||
return k.creates(groupID, "groupin", k.scope())
|
||||
}
|
||||
|
||||
func (k KetoConnector) CreatePermission(permID string, relation string, internal bool) (string, int, error) {
|
||||
func (k *KetoConnector) CreatePermission(permID string, relation string, internal bool) (string, int, error) {
|
||||
meth, err := utils.ExtractMethod(relation, internal)
|
||||
if err != nil {
|
||||
return "", 422, err
|
||||
@@ -137,7 +141,7 @@ func (k KetoConnector) CreatePermission(permID string, relation string, internal
|
||||
return id, code, nil
|
||||
}
|
||||
|
||||
func (k KetoConnector) creates(object string, relation string, subject string) (string, int, error) {
|
||||
func (k *KetoConnector) creates(object string, relation string, subject string) (string, int, error) {
|
||||
p, code, err := k.createRelationShip(object, relation, subject, nil)
|
||||
if err != nil {
|
||||
return "", code, err
|
||||
@@ -145,23 +149,23 @@ func (k KetoConnector) creates(object string, relation string, subject string) (
|
||||
return p.Object, 200, nil
|
||||
}
|
||||
|
||||
func (k KetoConnector) GetRole(roleID string) ([]string, error) {
|
||||
func (k *KetoConnector) GetRole(roleID string) ([]string, error) {
|
||||
return k.gets(roleID, "is", k.scope())
|
||||
}
|
||||
|
||||
func (k KetoConnector) GetGroup(groupID string) ([]string, error) {
|
||||
func (k *KetoConnector) GetGroup(groupID string) ([]string, error) {
|
||||
return k.gets(groupID, "groupin", k.scope())
|
||||
}
|
||||
|
||||
func (k KetoConnector) GetRoleByUser(userID string) ([]string, error) {
|
||||
func (k *KetoConnector) GetRoleByUser(userID string) ([]string, error) {
|
||||
return k.gets("", "member", userID)
|
||||
}
|
||||
|
||||
func (k KetoConnector) GetGroupByUser(userID string) ([]string, error) {
|
||||
func (k *KetoConnector) GetGroupByUser(userID string) ([]string, error) {
|
||||
return k.gets("", "groups", userID)
|
||||
}
|
||||
|
||||
func (k KetoConnector) gets(object string, relation string, subject string) ([]string, error) {
|
||||
func (k *KetoConnector) gets(object string, relation string, subject string) ([]string, error) {
|
||||
arr := []string{}
|
||||
objs, err := k.get(object, relation, subject)
|
||||
if err != nil {
|
||||
@@ -173,7 +177,7 @@ func (k KetoConnector) gets(object string, relation string, subject string) ([]s
|
||||
return arr, nil
|
||||
}
|
||||
|
||||
func (k KetoConnector) GetPermission(permID string, relation string) ([]Permission, error) {
|
||||
func (k *KetoConnector) GetPermission(permID string, relation string) ([]Permission, error) {
|
||||
meth, err := utils.ExtractMethod(relation, true)
|
||||
if err != nil {
|
||||
p := []Permission{}
|
||||
@@ -189,7 +193,7 @@ func (k KetoConnector) GetPermission(permID string, relation string) ([]Permissi
|
||||
return k.get(permID, "permits"+meth.String(), k.scope())
|
||||
}
|
||||
|
||||
func (k KetoConnector) GetPermissionByRole(roleID string) ([]Permission, error) {
|
||||
func (k *KetoConnector) GetPermissionByRole(roleID string) ([]Permission, error) {
|
||||
p := []Permission{}
|
||||
for _, method := range []tools.METHOD{tools.GET, tools.PUT, tools.POST, tools.DELETE,
|
||||
tools.STRICT_INTERNAL_DELETE, tools.STRICT_INTERNAL_GET, tools.STRICT_INTERNAL_POST, tools.STRICT_INTERNAL_PUT} {
|
||||
@@ -200,7 +204,7 @@ func (k KetoConnector) GetPermissionByRole(roleID string) ([]Permission, error)
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
func (k KetoConnector) GetPermissionByUser(userID string, internal bool) ([]Permission, error) {
|
||||
func (k *KetoConnector) GetPermissionByUser(userID string, internal bool) ([]Permission, error) {
|
||||
roles, err := k.get("", "member", userID)
|
||||
log := oclib.GetLogger()
|
||||
log.Debug().Msgf("GetPermissionByUser roles for %s: %d roles, err=%v", userID, len(roles), err)
|
||||
@@ -223,7 +227,7 @@ func (k KetoConnector) GetPermissionByUser(userID string, internal bool) ([]Perm
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (k KetoConnector) get(object string, relation string, subject string) ([]Permission, error) {
|
||||
func (k *KetoConnector) get(object string, relation string, subject string) ([]Permission, error) {
|
||||
t := []Permission{}
|
||||
caller := tools.NewHTTPCaller(map[tools.DataType]map[tools.METHOD]string{})
|
||||
host := conf.GetConfig().PermissionConnectorReadHost
|
||||
@@ -231,6 +235,8 @@ func (k KetoConnector) get(object string, relation string, subject string) ([]Pe
|
||||
host = "localhost"
|
||||
}
|
||||
port := fmt.Sprintf("%v", conf.GetConfig().PermissionConnectorPort)
|
||||
k.Mu.Lock()
|
||||
defer k.Mu.Unlock()
|
||||
resp, err := caller.CallGet("http://"+host+":"+port, "/relation-tuples"+k.permToQuery(
|
||||
Permission{Object: object, Relation: relation, Subject: subject}, nil))
|
||||
if err != nil {
|
||||
@@ -253,7 +259,7 @@ func (k KetoConnector) get(object string, relation string, subject string) ([]Pe
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func (k KetoConnector) binds(object string, relation string, subject string) (string, int, error) {
|
||||
func (k *KetoConnector) binds(object string, relation string, subject string) (string, int, error) {
|
||||
_, code, err := k.createRelationShip(object, relation, subject, nil)
|
||||
if err != nil {
|
||||
return object, code, err
|
||||
@@ -261,17 +267,17 @@ func (k KetoConnector) binds(object string, relation string, subject string) (st
|
||||
return object, 200, nil
|
||||
}
|
||||
|
||||
func (k KetoConnector) BindRole(userID string, roleID string) (string, int, error) {
|
||||
func (k *KetoConnector) BindRole(userID string, roleID string) (string, int, error) {
|
||||
log := oclib.GetLogger()
|
||||
log.Debug().Msgf("BindRole: user=%s role=%s", userID, roleID)
|
||||
return k.binds(userID, "member", roleID)
|
||||
}
|
||||
|
||||
func (k KetoConnector) BindGroup(userID string, groupID string) (string, int, error) {
|
||||
func (k *KetoConnector) BindGroup(userID string, groupID string) (string, int, error) {
|
||||
return k.binds(userID, "groups", groupID)
|
||||
}
|
||||
|
||||
func (k KetoConnector) BindPermission(roleID string, permID string, relation string) (*Permission, int, error) {
|
||||
func (k *KetoConnector) BindPermission(roleID string, permID string, relation string) (*Permission, int, error) {
|
||||
perms, err := k.GetPermission(permID, relation)
|
||||
if err != nil || len(perms) != 1 {
|
||||
count := 0
|
||||
@@ -297,7 +303,7 @@ func (k KetoConnector) BindPermission(roleID string, permID string, relation str
|
||||
}, 200, nil
|
||||
}
|
||||
|
||||
func (k KetoConnector) unbinds(subject string, relation string, object string) (string, int, error) {
|
||||
func (k *KetoConnector) unbinds(subject string, relation string, object string) (string, int, error) {
|
||||
_, code, err := k.deleteRelationShip(object, relation, subject, nil)
|
||||
if err != nil {
|
||||
return object, code, err
|
||||
@@ -305,15 +311,15 @@ func (k KetoConnector) unbinds(subject string, relation string, object string) (
|
||||
return object, 200, nil
|
||||
}
|
||||
|
||||
func (k KetoConnector) UnBindRole(userID string, roleID string) (string, int, error) {
|
||||
func (k *KetoConnector) UnBindRole(userID string, roleID string) (string, int, error) {
|
||||
return k.unbinds(userID, "member", roleID)
|
||||
}
|
||||
|
||||
func (k KetoConnector) UnBindGroup(userID string, groupID string) (string, int, error) {
|
||||
func (k *KetoConnector) UnBindGroup(userID string, groupID string) (string, int, error) {
|
||||
return k.unbinds(userID, "groups", groupID)
|
||||
}
|
||||
|
||||
func (k KetoConnector) UnBindPermission(roleID string, permID string, relation string) (*Permission, int, error) {
|
||||
func (k *KetoConnector) UnBindPermission(roleID string, permID string, relation string) (*Permission, int, error) {
|
||||
meth, err := utils.ExtractMethod(relation, false)
|
||||
if err != nil {
|
||||
return nil, 422, err
|
||||
@@ -342,7 +348,7 @@ func (k KetoConnector) UnBindPermission(roleID string, permID string, relation s
|
||||
Subject: permID,
|
||||
}, 200, nil
|
||||
}
|
||||
func (k KetoConnector) createRelationShip(object string, relation string, subject string, subPerm *Permission) (*Permission, int, error) {
|
||||
func (k *KetoConnector) createRelationShip(object string, relation string, subject string, subPerm *Permission) (*Permission, int, error) {
|
||||
exist, err := k.get(object, relation, subject)
|
||||
if err == nil && len(exist) > 0 {
|
||||
return nil, 409, errors.New("Relation already exist")
|
||||
@@ -362,6 +368,8 @@ func (k KetoConnector) createRelationShip(object string, relation string, subjec
|
||||
host = "localhost"
|
||||
}
|
||||
port := fmt.Sprintf("%v", conf.GetConfig().PermissionConnectorAdminPort)
|
||||
k.Mu.Lock()
|
||||
defer k.Mu.Unlock()
|
||||
b, err := caller.CallPut("http://"+host+":"+port, "/relation-tuples", body)
|
||||
if err != nil {
|
||||
log := oclib.GetLogger()
|
||||
@@ -378,23 +386,23 @@ func (k KetoConnector) createRelationShip(object string, relation string, subjec
|
||||
perm := &Permission{}
|
||||
if data != nil {
|
||||
perm = &Permission{
|
||||
Object: data["object"].(string),
|
||||
Relation: data["relation"].(string),
|
||||
Subject: data["subject_id"].(string),
|
||||
Object: fmt.Sprintf("%v", data["object"]),
|
||||
Relation: fmt.Sprintf("%v", data["relation"]),
|
||||
Subject: fmt.Sprintf("%v", data["subject_id"]),
|
||||
}
|
||||
if data["subject_set"] != nil {
|
||||
sub := data["subject_set"].(map[string]interface{})
|
||||
perm.SubPermission = &Permission{
|
||||
Object: sub["object"].(string),
|
||||
Relation: sub["relation"].(string),
|
||||
Subject: sub["subject_id"].(string),
|
||||
Object: fmt.Sprintf("%v", sub["object"]),
|
||||
Relation: fmt.Sprintf("%v", sub["relation"]),
|
||||
Subject: fmt.Sprintf("%v", sub["subject_id"]),
|
||||
}
|
||||
}
|
||||
}
|
||||
return perm, 200, nil
|
||||
}
|
||||
|
||||
func (k KetoConnector) deleteRelationShip(object string, relation string, subject string, subPerm *Permission) (*Permission, int, error) {
|
||||
func (k *KetoConnector) deleteRelationShip(object string, relation string, subject string, subPerm *Permission) (*Permission, int, error) {
|
||||
exist, err := k.get(object, relation, subject)
|
||||
if err == nil && len(exist) == 0 {
|
||||
return nil, 409, errors.New("Relation does not exist")
|
||||
@@ -406,6 +414,8 @@ func (k KetoConnector) deleteRelationShip(object string, relation string, subjec
|
||||
host = "localhost"
|
||||
}
|
||||
port := fmt.Sprintf("%v", conf.GetConfig().PermissionConnectorAdminPort)
|
||||
k.Mu.Lock()
|
||||
defer k.Mu.Unlock()
|
||||
b, err := caller.CallDelete("http://"+host+":"+port, "/relation-tuples"+n)
|
||||
if err != nil {
|
||||
log := oclib.GetLogger()
|
||||
@@ -414,8 +424,8 @@ func (k KetoConnector) deleteRelationShip(object string, relation string, subjec
|
||||
}
|
||||
var data map[string]interface{}
|
||||
err = json.Unmarshal(b, &data)
|
||||
if err == nil && data["code"].(int) > 300 {
|
||||
return nil, data["code"].(int), errors.New("Error while deleting relation")
|
||||
if data["code"] == nil || err != nil || data["code"].(int) > 300 {
|
||||
return nil, 400, errors.New("Error while deleting relation")
|
||||
}
|
||||
return &Permission{
|
||||
Object: object,
|
||||
|
||||
@@ -52,7 +52,7 @@ type PermConnector interface {
|
||||
}
|
||||
|
||||
var c = map[string]PermConnector{
|
||||
"keto": KetoConnector{},
|
||||
"keto": &KetoConnector{},
|
||||
}
|
||||
|
||||
func GetPermissionConnector(scope string) PermConnector {
|
||||
|
||||
Reference in New Issue
Block a user