diff --git a/brbac/active.go b/brbac/active.go index 7160aa5..c4bc5aa 100644 --- a/brbac/active.go +++ b/brbac/active.go @@ -24,11 +24,94 @@ package brbac +import "errs" + var ( + + // G Public vars + G = struct { + + ErrInvalidActor errs.ErrCode + ErrInvalidIDRole errs.ErrCode + ErrRoleCycle errs.ErrCode + + RoleProvider RoleProvider + + + } { + + ErrInvalidActor : errs.ErrCode("invalid-actor-type"), + ErrInvalidIDRole: errs.ErrCode("invalid-id-role"), + ErrRoleCycle : errs.ErrCode("role-cycle"), + } + + + // g Private vars g = struct { - agentAllFlags []AgentStateFlags + actorFlags []ActorFlags + actorNames []string }{ - agentAllFlags: []AgentStateFlags{AgentStateFlagVerified, AgentStateFlagRequired, AgentStateFlagRestricted, AgentStateFlagLimited}, + actorFlags: []ActorFlags{ + ActorFlagVerified, + ActorFlagRequired, + ActorFlagRestricted, + ActorFlagLimited}, + + actorNames: []string{ + "User", // 0x00 + "Role", // 0x01 + "Service", // 0x02 + "Device", // 0x03 + "Group", // 0x04 + "Organization", // 0x05 + "APIKey", // 0x06 + "System", // 0x07 + "Admin", // 0x08 + "Visitor", // 0x09 + "Auditor", // 0x0A + "ExternalClient", // 0x0B + "Provider", // 0x0C + "TemporaryToken", // 0x0D + "Bot", // 0x0E + "Reserved", // 0x0F + "BlockchainNode", // 0x10 + "BlockchainUser", // 0x11 + "SmartContract", // 0x12 + "BlockchainAPI", // 0x13 + "Wallet", // 0x14 + "Miner", // 0x15 + "Validator", // 0x16 + "DApp", // 0x17 + "Token", // 0x18 + "BlockchainOracle", // 0x19 + "BlockchainExplorer", // 0x1A + "DAO", // 0x1B + "NFT", // 0x1C + "BlockchainBridge", // 0x1D + "Staking", // 0x1E + "DefiPlatform", // 0x1F + "BlockchainWallet", // 0x20 + "BlockchainExplorerAPI", // 0x21 + "BlockchainTransaction", // 0x22 + "BlockchainBackup", // 0x23 + "SecurityModule", // 0x24 + "QuantumComputer", // 0x25 + "QuantumWallet", // 0x26 + "AI", // 0x30 + "CloudService", // 0x31 + "Microservice", // 0x32 + "ThirdParty", // 0x33 + "ExternalSystem", // 0x34 + "MobileDevice", // 0x35 + "ExternalAPI", // 0x36 + "Server", // 0x37 + "UserAgent", // 0x38 + "Container", // 0x39 + "Network", // 0x3A + "EdgeDevice", // 0x3B + "VirtualMachine", // 0x3C + "Hypervisor", // 0x3D + }, } ) diff --git a/brbac/agent_state_flags.go b/brbac/actor_flags.go similarity index 55% rename from brbac/agent_state_flags.go rename to brbac/actor_flags.go index e85cbe6..279f159 100644 --- a/brbac/agent_state_flags.go +++ b/brbac/actor_flags.go @@ -2,7 +2,7 @@ // 馃殌 Project Active8 // 馃敆 Active Thing (activething.com) git.activething.com/go // -// File name agent_state_flags.go +// File name actor_flags.go // 鉁嶏笍 Created by DEV // 馃搮 Modified 07/12/2024 // @@ -27,47 +27,51 @@ package brbac import "math/bits" const ( - AgentStateFlagVerified AgentStateFlags = 0b00000001 - AgentStateFlagRequired AgentStateFlags = 0b00000010 - AgentStateFlagRestricted AgentStateFlags = 0b00000011 - AgentStateFlagLimited AgentStateFlags = 0b00000100 + ActorFlagVerified ActorFlags = 0b00000001 + ActorFlagRequired ActorFlags = 0b00000010 + ActorFlagRestricted ActorFlags = 0b00000011 + ActorFlagLimited ActorFlags = 0b00000100 ) + type ( - AgentStateFlags uint8 + + ActorFlags uint8 + ) -func (a AgentStateFlags) Has(flag AgentStateFlags) bool { + +func (a ActorFlags) Has(flag ActorFlags) bool { return a&flag != 0 -} + } -func (a AgentStateFlags) HasVerified() bool { - return a&AgentStateFlagVerified != 0 +func (a ActorFlags) HasVerified() bool { + return a&ActorFlagVerified != 0 } -func (a AgentStateFlags) HasRequired() bool { - return a&AgentStateFlagRequired != 0 +func (a ActorFlags) HasRequired() bool { + return a&ActorFlagRequired != 0 } -func (a AgentStateFlags) HasRestricted() bool { - return a&AgentStateFlagRestricted != 0 +func (a ActorFlags) HasRestricted() bool { + return a&ActorFlagRestricted != 0 } -func (a AgentStateFlags) HasLimited() bool { - return a&AgentStateFlagLimited != 0 +func (a ActorFlags) HasLimited() bool { + return a&ActorFlagLimited != 0 } -func (a AgentStateFlags) Count() int { +func (a ActorFlags) Count() int { if a == 0 { return 0 } return bits.OnesCount8(uint8(a)) } -func (a AgentStateFlags) Actives() []AgentStateFlags { - var l []AgentStateFlags +func (a ActorFlags) Actives() []ActorFlags { + var l []ActorFlags if a > 0 { - for _, f := range g.agentAllFlags { + for _, f := range g.actorFlags { if a&f != 0 { l = append(l, f) } @@ -76,14 +80,14 @@ func (a AgentStateFlags) Actives() []AgentStateFlags { return l } -func (a AgentStateFlags) Set(flag AgentStateFlags) AgentStateFlags { +func (a ActorFlags) Set(flag ActorFlags) ActorFlags { return a | flag } -func (a AgentStateFlags) Del(flag AgentStateFlags) AgentStateFlags { +func (a ActorFlags) Del(flag ActorFlags) ActorFlags { return a &^ flag } -func (a AgentStateFlags) Clear() AgentStateFlags { +func (a ActorFlags) Clear() ActorFlags { return 0 } diff --git a/brbac/actor_id.go b/brbac/actor_id.go new file mode 100644 index 0000000..03b33da --- /dev/null +++ b/brbac/actor_id.go @@ -0,0 +1,66 @@ +// ------------------------------------------------------------------------ +// 馃殌 Project Active8 +// 馃敆 Active Thing (activething.com) git.activething.com/go +// +// File name actor_id.go +// 鉁嶏笍 Created by DEV +// 馃搮 Modified 07/12/2024 +// +// 馃敀 Copyright 2024 activething.com +// +// 馃摐 LICENSE -------------------------------------------------------------- +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package brbac + + +type ( + + + ActorID uint64 + +) + + + +// Type extrae los 6 bits m谩s significativos para determinar el tipo de Actor. +func (a ActorID) Type() ActorType { + // Desplazar el ActorID 58 bits a la derecha para que los 6 bits m谩s significativos est茅n al inicio, + // y luego convertirlos en un ActorType. + return ActorType(a >> 58) // Extraemos los 6 bits m谩s significativos +} + + +// SetType establece los 6 bits m谩s significativos como el tipo de Actor. +func (a ActorID) SetType(actorType ActorType) ActorID { + // Verificar que el tipo est谩 dentro del rango de 6 bits (0-63). + if actorType > 0x3F { // 0x3F es 63 en decimal, el rango de 6 bits + panic(G.ErrInvalidActor) + } + // Establecer el nuevo tipo en los 6 bits m谩s significativos. + return ActorID((a &^ (ActorID(0x3F) << 58)) | (ActorID(actorType) << 58)) +} + + + +func HasActor (actors []ActorID, id ActorID) bool { + for _,ai := range actors { + if ai == id { + return true + } + } + return false +} + + diff --git a/brbac/agent_state.go b/brbac/actor_state.go similarity index 70% rename from brbac/agent_state.go rename to brbac/actor_state.go index c0a359c..722727c 100644 --- a/brbac/agent_state.go +++ b/brbac/actor_state.go @@ -2,7 +2,7 @@ // 馃殌 Project Active8 // 馃敆 Active Thing (activething.com) git.activething.com/go // -// File name agent_state.go +// File name actor_state.go // 鉁嶏笍 Created by DEV // 馃搮 Modified 07/12/2024 // @@ -25,17 +25,17 @@ package brbac const ( - AgentStateActive AgentState = 0b000 // El usuario est谩 activo y no tiene restricciones - AgentStateInactive AgentState = 0b001 // El usuario est谩 inactivo y temporalmente deshabilitado - AgentStatePending AgentState = 0b010 // El usuario est谩 pendiente de activaci贸n (por ejemplo, verificaci贸n de correo electr贸nico) - AgentStateSuspended AgentState = 0b011 // El usuario est谩 suspendido debido a problemas de seguridad o pol铆ticas - AgentStateRevoked AgentState = 0b100 // El acceso del usuario ha sido revocado permanentemente - AgentStatePaused AgentState = 0b101 // El usuario ha pausado su cuenta (puede reactivarse) - AgentStateExpired AgentState = 0b110 // La cuenta del usuario ha expirado (por ejemplo, acceso temporal) - AgentStateDeleted AgentState = 0b111 // La cuenta del usuario est谩 eliminada y ya no existe + ActorStateActive ActorState = 0b000 // El usuario est谩 activo y no tiene restricciones + ActorStateInactive ActorState = 0b001 // El usuario est谩 inactivo y temporalmente deshabilitado + ActorStatePending ActorState = 0b010 // El usuario est谩 pendiente de activaci贸n (por ejemplo, verificaci贸n de correo electr贸nico) + ActorStateSuspended ActorState = 0b011 // El usuario est谩 suspendido debido a problemas de seguridad o pol铆ticas + ActorStateRevoked ActorState = 0b100 // El acceso del usuario ha sido revocado permanentemente + ActorStatePaused ActorState = 0b101 // El usuario ha pausado su cuenta (puede reactivarse) + ActorStateExpired ActorState = 0b110 // La cuenta del usuario ha expirado (por ejemplo, acceso temporal) + ActorStateDeleted ActorState = 0b111 // La cuenta del usuario est谩 eliminada y ya no existe ) type ( - AgentState uint8 + ActorState uint8 ) diff --git a/brbac/actor_type.go b/brbac/actor_type.go new file mode 100644 index 0000000..a99b3c4 --- /dev/null +++ b/brbac/actor_type.go @@ -0,0 +1,102 @@ +// ------------------------------------------------------------------------ +// 馃殌 Project Active8 +// 馃敆 Active Thing (activething.com) git.activething.com/go +// +// File name actor_type.go +// 鉁嶏笍 Created by DEV +// 馃搮 Modified 08/12/2024 +// +// 馃敀 Copyright 2024 activething.com +// +// 馃摐 LICENSE -------------------------------------------------------------- +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package brbac + + + +// Definici贸n de los valores posibles para ActorType (64 tipos con 8 bits). +const ( + // Tipos Generales + ActorTypeUser ActorType = 0x00 // Usuario + ActorTypeRole ActorType = 0x01 // Rol + ActorTypeService ActorType = 0x02 // Servicio + ActorTypeDevice ActorType = 0x03 // Dispositivo (IoT, hardware) + ActorTypeGroup ActorType = 0x04 // Grupo + ActorTypeOrganization ActorType = 0x05 // Organizaci贸n + ActorTypeAPIKey ActorType = 0x06 // API Key + ActorTypeSystem ActorType = 0x07 // Sistema interno + ActorTypeAdmin ActorType = 0x08 // Administrador + ActorTypeVisitor ActorType = 0x09 // Visitante + ActorTypeAuditor ActorType = 0x0A // Auditor + ActorTypeExternalClient ActorType = 0x0B // Cliente Externo + ActorTypeProvider ActorType = 0x0C // Proveedor + ActorTypeTemporaryToken ActorType = 0x0D // Token Temporal + ActorTypeBot ActorType = 0x0E // Bot o script + ActorTypeReserved ActorType = 0x0F // Reservado para futuras expansiones + + // Tipos Relacionados con Blockchain + ActorTypeBlockchainNode ActorType = 0x10 // Nodo de blockchain + ActorTypeBlockchainUser ActorType = 0x11 // Usuario de blockchain + ActorTypeSmartContract ActorType = 0x12 // Contrato inteligente (smart contract) + ActorTypeBlockchainAPI ActorType = 0x13 // API de blockchain + ActorTypeWallet ActorType = 0x14 // Billetera (wallet) de blockchain + ActorTypeMiner ActorType = 0x15 // Minero de blockchain + ActorTypeValidator ActorType = 0x16 // Validador de transacciones o bloques + ActorTypeDApp ActorType = 0x17 // Aplicaci贸n descentralizada (DApp) + ActorTypeToken ActorType = 0x18 // Token o criptomoneda + ActorTypeBlockchainOracle ActorType = 0x19 // Or谩culo de blockchain (proveedor de datos externos) + ActorTypeBlockchainExplorer ActorType = 0x1A // Explorador de blockchain + ActorTypeDAO ActorType = 0x1B // Organizaci贸n Aut贸noma Descentralizada (DAO) + ActorTypeNFT ActorType = 0x1C // Token No Fungible (NFT) + ActorTypeBlockchainBridge ActorType = 0x1D // Puente entre blockchains + ActorTypeStaking ActorType = 0x1E // Participante en staking + ActorTypeDefiPlatform ActorType = 0x1F // Plataforma de Finanzas Descentralizadas (DeFi) + ActorTypeBlockchainWallet ActorType = 0x20 // Billetera espec铆fica de blockchain + ActorTypeBlockchainExplorerAPI ActorType = 0x21 // API para exploradores de blockchain + ActorTypeBlockchainTransaction ActorType = 0x22 // Transacci贸n de blockchain + ActorTypeBlockchainBackup ActorType = 0x23 // Copia de seguridad o servicio de respaldo de blockchain + ActorTypeSecurityModule ActorType = 0x24 // M贸dulo de seguridad de blockchain + ActorTypeQuantumComputer ActorType = 0x25 // Computadora cu谩ntica (relacionada con blockchain) + ActorTypeQuantumWallet ActorType = 0x26 // Billetera cu谩ntica (relacionada con blockchain) + + // Otros Tipos + ActorTypeAI ActorType = 0x30 // Actor basado en inteligencia artificial + ActorTypeCloudService ActorType = 0x31 // Servicio en la nube + ActorTypeMicroservice ActorType = 0x32 // Microservicio + ActorTypeThirdParty ActorType = 0x33 // Actor externo o tercero + ActorTypeExternalSystem ActorType = 0x34 // Sistema Externo + ActorTypeMobileDevice ActorType = 0x35 // Dispositivo m贸vil + ActorTypeExternalAPI ActorType = 0x36 // API externa + ActorTypeServer ActorType = 0x37 // Servidor f铆sico o virtual + ActorTypeUserAgent ActorType = 0x38 // Agente de usuario (navegador, app, etc.) + ActorTypeContainer ActorType = 0x39 // Contenedor (Docker, etc.) + ActorTypeNetwork ActorType = 0x3A // Red o infraestructura de red + ActorTypeEdgeDevice ActorType = 0x3B // Dispositivo en la periferia de la red + ActorTypeVirtualMachine ActorType = 0x3C // M谩quina virtual + ActorTypeHypervisor ActorType = 0x3D // Hypervisor o administrador de m谩quinas virtuales +) + + +type ActorType uint8 + + + +func (a ActorType) Name () string { + i := int(a) + if i < len(g.actorNames) { + return g.actorNames[i] + } + return "" +} \ No newline at end of file diff --git a/brbac/role.go b/brbac/role.go new file mode 100644 index 0000000..79047fe --- /dev/null +++ b/brbac/role.go @@ -0,0 +1,135 @@ +// ------------------------------------------------------------------------ +// 馃殌 Project Active8 +// 馃敆 Active Thing (activething.com) git.activething.com/go +// +// File name role.go +// 鉁嶏笍 Created by DEV +// 馃搮 Modified 08/12/2024 +// +// 馃敀 Copyright 2024 activething.com +// +// 馃摐 LICENSE -------------------------------------------------------------- +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package brbac + +import "rsls" + +type ( + + + + Role struct { + roleID ActorID + State ActorState + Flags ActorFlags + name string + actors []ActorID + subRoles []ActorID + } + + +) + + +func (r *Role) AddRole (roleID ...ActorID) error { + if len(roleID) == 0 { + return nil + } + + // Usamos un mapa persistente para verificar los ciclos + state := make(map[ActorID]byte) + + for _,ri := range roleID { + if ri == r.roleID { + return G.ErrRoleCycle + } + // Check if is RoleID + if ri.Type() != ActorTypeRole { + return G.ErrInvalidIDRole + } + // Check if already exists + if HasActor(r.subRoles,ri) { + continue + } + + // **Verificaci贸n de ciclo antes de agregar el rol** + cycleResult := detectRoleCycleInHierarchy(r.roleID, ri, G.RoleProvider, &state) + if !cycleResult.IsOk() { + return cycleResult.Fail() + } else if cycleResult.Result() { + return G.ErrRoleCycle // Retornar error si se detecta un ciclo + } + + // Agregar el rol a los subroles + r.subRoles = append(r.subRoles, ri) + } + return nil +} + + + + + + + +func DetectRoleCycleInHierarchy(roleID, newRoleID ActorID, provider RoleProvider) rsls.RBool { + state := make(map[ActorID]byte) + return detectRoleCycleInHierarchy(roleID, newRoleID, G.RoleProvider, &state) +} + + + + +// detectRoleCycleInHierarchy realiza la verificaci贸n recursiva de si se forma un ciclo +func detectRoleCycleInHierarchy(roleID, newRoleID ActorID, provider RoleProvider, state *map[ActorID]byte) rsls.RBool { + + // Si el nuevo rol ya est谩 en la jerarqu铆a del rol actual, entonces hemos encontrado un ciclo + if (*state)[newRoleID] == 1 { + return rsls.BoolSuccessTrue // Ciclo detectado + } + + // Si el rol ha sido visitado completamente, entonces no es necesario revisarlo de nuevo + if (*state)[newRoleID] == 2 { + return rsls.BoolSuccessFalse + } + + // Marcar el rol como "en proceso" + (*state)[newRoleID] = 1 + + // Obtener los subroles del nuevo rol + subRoles, err := provider.GetSubRoles(newRoleID) + if err != nil { + return rsls.MakeBoolError(err) // Error al obtener los subroles + } + + // Realizar DFS para cada subrol del nuevo rol + for _, subRoleID := range subRoles { + if subRoleID == roleID { + // Detectar referencia directa al rol original, indicando un ciclo + return rsls.BoolSuccessTrue + } + cycleCheck := detectRoleCycleInHierarchy(roleID, subRoleID, provider, state) + if !cycleCheck.IsOk() ||cycleCheck.Result() { + return cycleCheck + } + } + + // Marcar el rol como "visitado" despu茅s de procesar todos sus subroles + (*state)[newRoleID] = 2 + return rsls.BoolSuccessFalse // No se ha detectado un ciclo +} + + + diff --git a/brbac/tests/user_test.go b/brbac/role_provider.go similarity index 75% rename from brbac/tests/user_test.go rename to brbac/role_provider.go index 5a99975..0dd3f15 100644 --- a/brbac/tests/user_test.go +++ b/brbac/role_provider.go @@ -1,13 +1,13 @@ // ------------------------------------------------------------------------ // 馃殌 Project Active8 -// 馃敆 UserStateActive Thing (activething.com) git.activething.com/go +// 馃敆 Active Thing (activething.com) git.activething.com/go // -// File name user_test.go +// File name role_provider.go // 鉁嶏笍 Created by DEV -// 馃搮 Modified 04/12/2024 +// 馃搮 Modified 08/12/2024 // // 馃敀 Copyright 2024 activething.com -// +// // 馃摐 LICENSE -------------------------------------------------------------- // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,4 +22,16 @@ // limitations under the License. // ------------------------------------------------------------------------ -package tests +package brbac + + + +type ( + + RoleProvider interface { + //GetRole (roleID ActorID) (*Role,error) + GetSubRoles(roleID ActorID) ([]ActorID,error) + } +) + + diff --git a/brbac/roles_test.go b/brbac/roles_test.go new file mode 100644 index 0000000..c97aa4b --- /dev/null +++ b/brbac/roles_test.go @@ -0,0 +1,112 @@ +// ------------------------------------------------------------------------ +// 馃殌 Project Active8 +// 馃敆 Active Thing (activething.com) git.activething.com/go +// +// File name roles_test.go +// 鉁嶏笍 Created by DEV +// 馃搮 Modified 09/12/2024 +// +// 馃敀 Copyright 2024 activething.com +// +// 馃摐 LICENSE -------------------------------------------------------------- +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package brbac + +import "testing" + +// MockRoleProvider simula un proveedor de roles que contiene roles predefinidos +type MockRoleProvider struct { + roles map[ActorID][]ActorID +} + +func (m *MockRoleProvider) GetSubRoles(roleID ActorID) ([]ActorID, error) { + if subRoles, exists := m.roles[roleID]; exists { + return subRoles, nil + } + return nil, nil +} + + +func TestAddRole(t *testing.T) { + // Crear un RoleProvider simulado con algunos roles y subroles + + provider := &MockRoleProvider{ + roles: map[ActorID][]ActorID{ + 0x10: {0x11, 0x12}, // El rol 0x10 tiene subroles 0x11 y 0x12 + 0x11: {0x12}, // El rol 0x11 tiene subrol 0x12 + 0x12: {}, // El rol 0x12 no tiene subroles + }, + } + G.RoleProvider = provider + + // Crear un rol inicial + role := &Role{ + roleID: 0x10, + State: ActorStateActive, + name: "Role10", + } + + // Test 1: A帽adir un rol que no crea ciclo + err := role.AddRole(0x11) + if err != nil { + t.Errorf("Error inesperado al agregar un rol no c铆clico: %v", err) + } + + // Test 2: Intentar a帽adir un rol que ya existe + err = role.AddRole(0x11) // El rol 0x11 ya fue a帽adido + if err != nil { + t.Errorf("Error inesperado al agregar un rol ya existente: %v", err) + } + + // Test 3: Intentar a帽adir un rol que causa un ciclo + provider.roles[0x12] = []ActorID{0x10} // Esto crea un ciclo: 0x10 -> 0x11 -> 0x12 -> 0x10 + err = role.AddRole(0x12) + if err == nil { + t.Errorf("Se esperaba un error de ciclo al agregar el rol") + } + + // Test 4: A帽adir m煤ltiples roles + provider.roles[0x12] = []ActorID{} // Eliminar el ciclo previo + err = role.AddRole(0x12) + if err != nil { + t.Errorf("Error inesperado al agregar m煤ltiples roles: %v", err) + } +} + +func TestDetectRoleCycleInHierarchy(t *testing.T) { + // Crear un RoleProvider simulado con algunos roles y subroles + provider := &MockRoleProvider{ + roles: map[ActorID][]ActorID{ + 0x10: {0x11, 0x12}, // El rol 0x10 tiene subroles 0x11 y 0x12 + 0x11: {0x12}, // El rol 0x11 tiene subrol 0x12 + 0x12: {0x10}, // El rol 0x12 tiene subrol 0x10, lo que genera un ciclo + }, + } + + // Test 1: Detectar ciclo entre roles + state := make(map[ActorID]byte) + result := detectRoleCycleInHierarchy(0x10, 0x11, provider, &state) + if !result.Result() { + t.Errorf("Se esperaba detectar un ciclo entre los roles, pero no se detect贸") + } + + // Test 2: No hay ciclo, rol 0x11 no tiene subroles + provider.roles[0x12] = []ActorID{} // Romper el ciclo eliminando subroles de 0x12 + state = make(map[ActorID]byte) // Reiniciar el estado + result = detectRoleCycleInHierarchy(0x10, 0x11, provider, &state) + if result.Result() { + t.Errorf("No deber铆a haber un ciclo cuando no hay subroles") + } +} \ No newline at end of file diff --git a/brbac/tests/go.mod b/brbac/tests/go.mod deleted file mode 100644 index b9b8073..0000000 --- a/brbac/tests/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module tests - -go 1.22 diff --git a/core/errs/err_code.go b/core/errs/err_code.go new file mode 100644 index 0000000..fd62636 --- /dev/null +++ b/core/errs/err_code.go @@ -0,0 +1,44 @@ +// ------------------------------------------------------------------------ +// 馃殌 Project Active8 +// 馃敆 Active Thing (activething.com) git.activething.com/go +// +// File name err_code.go +// 鉁嶏笍 Created by DEV +// 馃搮 Modified 08/12/2024 +// +// 馃敀 Copyright 2024 activething.com +// +// 馃摐 LICENSE -------------------------------------------------------------- +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package errs + + +type ( + + ErrCode string + +) + + + + +func (e ErrCode) Error() string { + return string(e) } + +func (e ErrCode) Code () string { + return string(e) } + + + diff --git a/core/errs/go.mod b/core/errs/go.mod new file mode 100644 index 0000000..4695350 --- /dev/null +++ b/core/errs/go.mod @@ -0,0 +1,3 @@ +module errs + +go 1.22 diff --git a/core/go.mod b/core/go.mod new file mode 100644 index 0000000..913f135 --- /dev/null +++ b/core/go.mod @@ -0,0 +1,3 @@ +module core + +go 1.22 diff --git a/core/rsls/go.mod b/core/rsls/go.mod new file mode 100644 index 0000000..0f10ca8 --- /dev/null +++ b/core/rsls/go.mod @@ -0,0 +1,3 @@ +module rsls + +go 1.22 diff --git a/core/rsls/r_bool.go b/core/rsls/r_bool.go new file mode 100644 index 0000000..c2191ea --- /dev/null +++ b/core/rsls/r_bool.go @@ -0,0 +1,85 @@ +// ------------------------------------------------------------------------ +// 馃殌 Project Active8 +// 馃敆 Active Thing (activething.com) git.activething.com/go +// +// File name r_bool.go +// 鉁嶏笍 Created by DEV +// 馃搮 Modified 08/12/2024 +// +// 馃敀 Copyright 2024 activething.com +// +// 馃摐 LICENSE -------------------------------------------------------------- +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package rsls + + +const ( + BoolSuccessTrue BoolSuccess = true + BoolSuccessFalse BoolSuccess = false +) + + +type ( + + RBool interface { + IsOk () bool + Result() bool + Fail () error + } + + BoolSuccess bool + + BoolError struct { + error + } + +) + + +func (s BoolSuccess) IsOk () bool { + return true } + +func (s BoolSuccess) Result() bool { + return bool(s) } + +func (s BoolSuccess) Fail () error { + return nil } + + + +func MakeBoolError (err error) BoolError { + return BoolError{ err } +} + +func (s BoolError) IsOk () bool { + return false } + +func (s BoolError) Result() bool { + return false } + +func (s BoolError) Fail () error { + return s.error } + + + + + + + + + + + + diff --git a/core/rsls/rboolBench_test.go b/core/rsls/rboolBench_test.go new file mode 100644 index 0000000..0dac828 --- /dev/null +++ b/core/rsls/rboolBench_test.go @@ -0,0 +1,63 @@ +// ------------------------------------------------------------------------ +// 馃殌 Project Active8 +// 馃敆 Active Thing (activething.com) git.activething.com/go +// +// File name rboolBench_test.go +// 鉁嶏笍 Created by DEV +// 馃搮 Modified 08/12/2024 +// +// 馃敀 Copyright 2024 activething.com +// +// 馃摐 LICENSE -------------------------------------------------------------- +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package rsls + +import ( + "errors" + "rsls" + "testing" +) + + +// M茅todo tradicional +func traditionalBoolError(input int) (bool, error) { + if input > 0 { + return true, nil + } + return false, errors.New("input must be greater than zero") +} + +// M茅todo con RBool +func rboolMethod(input int) rsls.RBool { + if input > 0 { + return rsls.BoolSuccessTrue + } + return rsls.MakeBoolError(errors.New("input must be greater than zero")) +} + +func BenchmarkTraditional(b *testing.B) { + for i := 0; i < b.N; i++ { + _, _ = traditionalBoolError(i) + } +} + +func BenchmarkRBool(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = rboolMethod(i) + } +} + + + diff --git a/go.work b/go.work index 3528a75..37c7150 100644 --- a/go.work +++ b/go.work @@ -2,6 +2,9 @@ go 1.22 use ( . + core + core/errs + core/rsls brbac - brbac/tests + ) \ No newline at end of file