OC-AUTH with admin persona

This commit is contained in:
mr 2024-10-30 16:18:21 +01:00
parent d87883b57f
commit d33d2eb343
15 changed files with 52 additions and 52 deletions

View File

@ -3,6 +3,7 @@ package conf
import "sync" import "sync"
type Config struct { type Config struct {
Demo bool
PublicKeyPath string PublicKeyPath string
PrivateKeyPath string PrivateKeyPath string

View File

@ -66,7 +66,7 @@ func (o *PermissionController) GetByRole() {
// @router /user/:id [get] // @router /user/:id [get]
func (o *PermissionController) GetByUser() { func (o *PermissionController) GetByUser() {
id := o.Ctx.Input.Param(":id") id := o.Ctx.Input.Param(":id")
role, err := infrastructure.GetPermissionConnector().GetPermissionByUser(id) role, err := infrastructure.GetPermissionConnector().GetPermissionByUser(id, true)
if err != nil { if err != nil {
o.Data["json"] = map[string]interface{}{ o.Data["json"] = map[string]interface{}{
"data": nil, "data": nil,
@ -88,7 +88,7 @@ func (o *PermissionController) GetByUser() {
// @Description find auth by permission // @Description find auth by permission
// @Param id path string true "the permission you want to get" // @Param id path string true "the permission you want to get"
// @Success 200 {auth} models.auth // @Success 200 {auth} models.auth
// @router /:id/:relation[get] // @router /:id/:relation [get]
func (o *PermissionController) Get() { func (o *PermissionController) Get() {
id := o.Ctx.Input.Param(":id") id := o.Ctx.Input.Param(":id")
rel := o.Ctx.Input.Param(":relation") rel := o.Ctx.Input.Param(":relation")

View File

@ -5,5 +5,6 @@
"PORT" : 8080, "PORT" : 8080,
"AUTH_CONNECTOR_HOST": "hydra", "AUTH_CONNECTOR_HOST": "hydra",
"PRIVATE_KEY_PATH": "/etc/oc/pem/private.pem", "PRIVATE_KEY_PATH": "/etc/oc/pem/private.pem",
"PUBLIC_KEY_PATH": "/etc/oc/pem/public.pem" "PUBLIC_KEY_PATH": "/etc/oc/pem/public.pem",
"DEMO": true
} }

View File

@ -146,7 +146,6 @@ func (a HydraConnector) Login(username string, cookies ...*http.Cookie) (t *Toke
// problem with consent THERE we need to accept the consent challenge && get the token // problem with consent THERE we need to accept the consent challenge && get the token
_, err = a.Caller.CallRaw(http.MethodGet, a.urlFormat(redirect.RedirectTo, a.getPath(false, true)), "", map[string]interface{}{}, _, err = a.Caller.CallRaw(http.MethodGet, a.urlFormat(redirect.RedirectTo, a.getPath(false, true)), "", map[string]interface{}{},
"application/json", true, cookies...) "application/json", true, cookies...)
fmt.Println(err)
if err != nil { if err != nil {
s := strings.Split(err.Error(), "\"") s := strings.Split(err.Error(), "\"")
if len(s) > 1 && strings.Contains(s[1], "access_token") { if len(s) > 1 && strings.Contains(s[1], "access_token") {
@ -242,15 +241,12 @@ func (a HydraConnector) getPath(isAdmin bool, isOauth bool) string {
if isOauth { if isOauth {
oauth = "/oauth2" oauth = "/oauth2"
} }
fmt.Println("http://" + host + ":" + port + oauth)
return "http://" + host + ":" + port + oauth return "http://" + host + ":" + port + oauth
} }
func (a HydraConnector) CheckAuthForward(reqToken string, publicKey string, host string, method string, forward string) bool { func (a HydraConnector) CheckAuthForward(reqToken string, publicKey string, host string, method string, forward string) bool {
fmt.Println("CheckAuthForward", reqToken, publicKey, host, method, forward)
if forward == "" || method == "" { if forward == "" || method == "" {
fmt.Println("Forwarded headers are missing")
return false return false
} }
var c claims.Claims var c claims.Claims

View File

@ -254,7 +254,6 @@ func (cli *Client) connect(ctx context.Context) <-chan conn {
) )
wg.Add(len(cli.Endpoints)) wg.Add(len(cli.Endpoints))
for _, addr := range cli.Endpoints { for _, addr := range cli.Endpoints {
fmt.Println("addr", addr)
go func(addr string) { go func(addr string) {
defer wg.Done() defer wg.Done()

View File

@ -4,7 +4,6 @@ import (
"crypto/sha256" "crypto/sha256"
"encoding/pem" "encoding/pem"
"errors" "errors"
"fmt"
"oc-auth/conf" "oc-auth/conf"
"oc-auth/infrastructure/perms_connectors" "oc-auth/infrastructure/perms_connectors"
"oc-auth/infrastructure/utils" "oc-auth/infrastructure/utils"
@ -40,7 +39,6 @@ func (h HydraClaims) decodeKey(key string) (tools.METHOD, string, error) {
} }
func (h HydraClaims) DecodeSignature(host string, signature string, publicKey string) (bool, error) { func (h HydraClaims) DecodeSignature(host string, signature string, publicKey string) (bool, error) {
fmt.Println("DecodeSignature", host)
hashed := sha256.Sum256([]byte(host)) hashed := sha256.Sum256([]byte(host))
spkiBlock, _ := pem.Decode([]byte(publicKey)) // get public key into a variable spkiBlock, _ := pem.Decode([]byte(publicKey)) // get public key into a variable
err := VerifyDefault(hashed[:], spkiBlock.Bytes, signature) err := VerifyDefault(hashed[:], spkiBlock.Bytes, signature)
@ -51,7 +49,6 @@ func (h HydraClaims) DecodeSignature(host string, signature string, publicKey st
} }
func (h HydraClaims) encodeSignature(host string) (string, error) { func (h HydraClaims) encodeSignature(host string) (string, error) {
fmt.Println("encodeSignature", host)
hashed := sha256.Sum256([]byte(host)) hashed := sha256.Sum256([]byte(host))
// READ FILE TO GET PRIVATE KEY FROM PVK PEM PATH // READ FILE TO GET PRIVATE KEY FROM PVK PEM PATH
content, err := os.ReadFile(conf.GetConfig().PrivateKeyPath) content, err := os.ReadFile(conf.GetConfig().PrivateKeyPath)
@ -102,7 +99,7 @@ func (h HydraClaims) DecodeClaimsInToken(host string, method string, forward str
// add claims to token method of HydraTokenizer // add claims to token method of HydraTokenizer
func (h HydraClaims) AddClaimsToToken(userId string, host string) Claims { func (h HydraClaims) AddClaimsToToken(userId string, host string) Claims {
claims := Claims{} claims := Claims{}
perms, err := perms_connectors.KetoConnector{}.GetPermissionByUser(userId) perms, err := perms_connectors.KetoConnector{}.GetPermissionByUser(userId, false)
if err != nil { if err != nil {
return claims return claims
} }

View File

@ -124,6 +124,8 @@ func (k KetoConnector) CreatePermission(permID string, relation string, internal
if err != nil { if err != nil {
return "", 422, err return "", 422, err
} }
k.BindPermission("admin", permID, "permits"+meth.String())
p, code, err := k.createRelationShip(permID, "permits"+meth.String(), k.scope(), nil) p, code, err := k.createRelationShip(permID, "permits"+meth.String(), k.scope(), nil)
if err != nil { if err != nil {
return "", code, err return "", code, err
@ -145,7 +147,7 @@ func (k KetoConnector) GetRole(roleID string) ([]string, error) {
func (k KetoConnector) GetRoleByUser(userID string) ([]string, error) { func (k KetoConnector) GetRoleByUser(userID string) ([]string, error) {
arr := []string{} arr := []string{}
roles, err := k.get("", "is", userID) roles, err := k.get("", "member", userID)
if err != nil { if err != nil {
return arr, err return arr, err
} }
@ -159,10 +161,9 @@ func (k KetoConnector) GetPermission(permID string, relation string) ([]Permissi
meth, err := utils.ExtractMethod(relation, true) meth, err := utils.ExtractMethod(relation, true)
if err != nil { if err != nil {
p := []Permission{} p := []Permission{}
for _, method := range []tools.METHOD{tools.GET, tools.PUT, tools.POST, tools.DELETE} { for _, method := range []tools.METHOD{tools.GET, tools.PUT, tools.POST, tools.DELETE,
fmt.Println("blblbl", permID, "permits"+method.String(), k.scope()) tools.STRICT_INTERNAL_DELETE, tools.STRICT_INTERNAL_GET, tools.STRICT_INTERNAL_POST, tools.STRICT_INTERNAL_PUT} {
perms, err := k.get(permID, "permits"+method.String(), k.scope()) perms, err := k.get(permID, "permits"+method.String(), k.scope())
fmt.Println("blblbl2", perms, err)
if err == nil && len(perms) > 0 { if err == nil && len(perms) > 0 {
p = append(p, perms...) p = append(p, perms...)
} }
@ -173,24 +174,35 @@ func (k KetoConnector) GetPermission(permID string, relation string) ([]Permissi
} }
func (k KetoConnector) GetPermissionByRole(roleID string) ([]Permission, error) { func (k KetoConnector) GetPermissionByRole(roleID string) ([]Permission, error) {
return k.get("", "", roleID) 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} {
perms, err := k.get(roleID, "permits"+method.String(), "")
if err == nil && len(perms) > 0 {
p = append(p, perms...)
}
}
return p, nil
} }
func (k KetoConnector) GetPermissionByUser(userID string) ([]Permission, error) { func (k KetoConnector) GetPermissionByUser(userID string, internal bool) ([]Permission, error) {
roles, err := k.get("", "is", userID) roles, err := k.get("", "member", userID)
perms := []Permission{}
if err != nil { if err != nil {
return perms, err return nil, err
}
p := []Permission{}
meths := []tools.METHOD{tools.GET, tools.PUT, tools.POST, tools.DELETE}
if internal {
meths = append(meths, []tools.METHOD{tools.STRICT_INTERNAL_DELETE, tools.STRICT_INTERNAL_GET, tools.STRICT_INTERNAL_POST, tools.STRICT_INTERNAL_PUT}...)
} }
for _, role := range roles { for _, role := range roles {
p, err := k.get(role.Object, "", k.scope()) for _, method := range meths {
if err != nil { perms, err := k.get(role.Object, "permits"+method.String(), "")
log := oclib.GetLogger() if err == nil && len(perms) > 0 {
log.Error().Msg(err.Error()) p = append(p, perms...)
continue
} }
perms = append(perms, p...)
} }
return perms, nil }
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) {
@ -229,11 +241,7 @@ func (k KetoConnector) BindRole(userID string, roleID string) (string, int, erro
} }
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) {
meth, err := utils.ExtractMethod(relation, false) perms, err := k.GetPermission(permID, relation)
if err != nil {
return nil, 422, err
}
perms, err := k.GetPermission(permID, meth.String())
if err != nil || len(perms) != 1 { if err != nil || len(perms) != 1 {
if len(perms) == 0 { if len(perms) == 0 {
return nil, 404, errors.New("Permission not found") return nil, 404, errors.New("Permission not found")
@ -338,9 +346,7 @@ func (k KetoConnector) deleteRelationShip(object string, relation string, subjec
n := k.permToQuery(Permission{Object: object, Relation: relation, Subject: subject}, subPerm) n := k.permToQuery(Permission{Object: object, Relation: relation, Subject: subject}, subPerm)
host := conf.GetConfig().PermissionConnectorHost host := conf.GetConfig().PermissionConnectorHost
port := fmt.Sprintf("%v", conf.GetConfig().PermissionConnectorAdminPort) port := fmt.Sprintf("%v", conf.GetConfig().PermissionConnectorAdminPort)
fmt.Println(host, port, n)
b, err := caller.CallDelete("http://"+host+":"+port, "/relation-tuples"+n) b, err := caller.CallDelete("http://"+host+":"+port, "/relation-tuples"+n)
fmt.Println(b, err)
if err != nil { if err != nil {
log := oclib.GetLogger() log := oclib.GetLogger()
log.Error().Msg(err.Error()) log.Error().Msg(err.Error())

View File

@ -37,7 +37,7 @@ type PermConnector interface {
GetRoleByUser(userID string) ([]string, error) GetRoleByUser(userID string) ([]string, error)
GetPermissionByRole(roleID string) ([]Permission, error) GetPermissionByRole(roleID string) ([]Permission, error)
GetPermissionByUser(userID string) ([]Permission, error) GetPermissionByUser(userID string, internal bool) ([]Permission, error)
GetRole(roleID string) ([]string, error) GetRole(roleID string) ([]string, error)
GetPermission(permID string, relation string) ([]Permission, error) GetPermission(permID string, relation string) ([]Permission, error)

View File

@ -1,10 +1,10 @@
dn: uid=momo,ou=Users,dc=example,dc=com dn: uid=admin,ou=Users,dc=example,dc=com
objectClass: inetOrgPerson objectClass: inetOrgPerson
cn: Kolya Gerasyimov cn: Admin
sn: Gerasyimov sn: Istrator
uid: momo uid: admin
userPassword: 123 userPassword: admin
mail: momo@example.com mail: admin@example.com
ou: Users ou: Users
dn: ou=AppRoles,dc=example,dc=com dn: ou=AppRoles,dc=example,dc=com
@ -21,4 +21,4 @@ dn: cn=traveler,ou=App1,ou=AppRoles,dc=example,dc=com
objectClass: groupofnames objectClass: groupofnames
cn: traveler cn: traveler
description: traveler description: traveler
member: uid=momo,ou=Users,dc=example,dc=com member: uid=admin,ou=Users,dc=example,dc=com

View File

@ -73,13 +73,11 @@ func generateSelfPeer() error {
return err return err
} }
// compare the public key from file with the one in the database // compare the public key from file with the one in the database
fmt.Println(string(f), p.Data[0].(*peer.Peer).PublicKey)
if !strings.Contains(string(f), p.Data[0].(*peer.Peer).PublicKey) { if !strings.Contains(string(f), p.Data[0].(*peer.Peer).PublicKey) {
return errors.New("public key is different from the one in the database") return errors.New("public key is different from the one in the database")
} }
return nil return nil
} }
fmt.Println("Creating new peer", strconv.Itoa(peer.SELF.EnumIndex()))
// create a new peer // create a new peer
o := oclib.GetConfLoader() o := oclib.GetConfLoader()
peer := &peer.Peer{ peer := &peer.Peer{
@ -100,8 +98,10 @@ func generateSelfPeer() error {
func discovery() { func discovery() {
fmt.Println("Discovered") fmt.Println("Discovered")
api := tools.API{} api := tools.API{}
addPermissions := func(m map[string]interface{}) {
conn := infrastructure.GetPermissionConnector() conn := infrastructure.GetPermissionConnector()
conn.CreateRole("admin")
conn.BindRole("admin", "admin")
addPermissions := func(m map[string]interface{}) {
for k, v := range m { for k, v := range m {
for _, p := range v.([]interface{}) { for _, p := range v.([]interface{}) {
conn.CreatePermission(k, p.(string), true) conn.CreatePermission(k, p.(string), true)

BIN
oc-auth

Binary file not shown.

View File

@ -64,7 +64,7 @@ func init() {
beego.GlobalControllerRouter["oc-auth/controllers:PermissionController"] = append(beego.GlobalControllerRouter["oc-auth/controllers:PermissionController"], beego.GlobalControllerRouter["oc-auth/controllers:PermissionController"] = append(beego.GlobalControllerRouter["oc-auth/controllers:PermissionController"],
beego.ControllerComments{ beego.ControllerComments{
Method: "Get", Method: "Get",
Router: `/:id/:relation[get]`, Router: `/:id/:relation`,
AllowHTTPMethods: []string{"get"}, AllowHTTPMethods: []string{"get"},
MethodParams: param.Make(), MethodParams: param.Make(),
Filters: nil, Filters: nil,

View File

@ -14,7 +14,7 @@ import (
) )
func init() { func init() {
ns := beego.NewNamespace("/oc", ns := beego.NewNamespace("/oc/",
beego.NSInclude( beego.NSInclude(
&controllers.OAuthController{}, &controllers.OAuthController{},
), ),

View File

@ -13,7 +13,7 @@
"url": "https://www.gnu.org/licenses/agpl-3.0.html" "url": "https://www.gnu.org/licenses/agpl-3.0.html"
} }
}, },
"basePath": "/oc", "basePath": "/oc/",
"paths": { "paths": {
"/forward": { "/forward": {
"get": { "get": {
@ -180,7 +180,7 @@
} }
} }
}, },
"/permission/{id}/{relation[get]}": { "/permission/{id}/{relation}": {
"get": { "get": {
"tags": [ "tags": [
"permission" "permission"

View File

@ -10,7 +10,7 @@ info:
license: license:
name: AGPL name: AGPL
url: https://www.gnu.org/licenses/agpl-3.0.html url: https://www.gnu.org/licenses/agpl-3.0.html
basePath: /oc basePath: /oc/
paths: paths:
/forward: /forward:
get: get:
@ -89,7 +89,7 @@ paths:
responses: responses:
"200": "200":
description: '{permission} string' description: '{permission} string'
/permission/{id}/{relation[get]}: /permission/{id}/{relation}:
get: get:
tags: tags:
- permission - permission