Files
Authorization/services/authorize_test.go
T
2025-12-16 10:57:26 +08:00

283 lines
8.8 KiB
Go

package services
import (
"authorization/db"
"authorization/models"
"errors"
"testing"
"github.com/DATA-DOG/go-sqlmock"
)
func setupMockDB(t *testing.T) (sqlmock.Sqlmock, func()) {
mockDB, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("Failed to create mock database: %v", err)
}
originalDB := db.DB
db.DB = mockDB
cleanup := func() {
db.DB = originalDB
mockDB.Close()
}
return mock, cleanup
}
func TestAuthorize_PermissionNotFound(t *testing.T) {
mock, cleanup := setupMockDB(t)
defer cleanup()
ctx := &models.AuthorizationContext{
UserID: "user123",
Resource: "nonexistent",
Action: "read",
ResourceData: make(map[string]string),
Environment: make(map[string]string),
}
mock.ExpectQuery("SELECT id, permission_name, description, resource, action FROM permissions WHERE resource = \\? AND action = \\? LIMIT 1").
WithArgs("nonexistent", "read").
WillReturnError(errors.New("permission not found"))
result, err := Authorize(ctx)
if err != nil {
t.Errorf("Expected no error, got %v", err)
}
if result.Allowed {
t.Error("Expected access denied")
}
if result.Message == "" {
t.Error("Expected error message")
}
}
func TestAuthorize_Success(t *testing.T) {
mock, cleanup := setupMockDB(t)
defer cleanup()
ctx := &models.AuthorizationContext{
UserID: "user123",
Resource: "document",
Action: "read",
ResourceData: make(map[string]string),
Environment: make(map[string]string),
}
// Mock permission query
permRows := sqlmock.NewRows([]string{"id", "permission_name", "description", "resource", "action"}).
AddRow(1, "read_document", "Read document permission", "document", "read")
mock.ExpectQuery("SELECT id, permission_name, description, resource, action FROM permissions WHERE resource = \\? AND action = \\? LIMIT 1").
WithArgs("document", "read").
WillReturnRows(permRows)
// Mock user attributes query
attrRows := sqlmock.NewRows([]string{"attribute_name", "attribute_value"}).
AddRow("department", "engineering")
mock.ExpectQuery("SELECT attribute_name, attribute_value FROM user_attributes WHERE user_id = \\?").
WithArgs("user123").
WillReturnRows(attrRows)
// Mock policy attributes query (empty for this test)
policyRows := sqlmock.NewRows([]string{"id", "attribute_name", "attribute_type", "comparison", "attribute_value", "permission_id"})
mock.ExpectQuery("SELECT id, attribute_name, attribute_type, comparison, attribute_value, permission_id FROM policy_attributes WHERE permission_id = \\?").
WithArgs(1).
WillReturnRows(policyRows)
result, err := Authorize(ctx)
if err != nil {
t.Errorf("Expected no error, got %v", err)
}
if !result.Allowed {
t.Error("Expected access granted")
}
if result.Message != "Access granted" {
t.Errorf("Expected 'Access granted', got '%s'", result.Message)
}
}
func TestAuthorize_UserAttributesError(t *testing.T) {
mock, cleanup := setupMockDB(t)
defer cleanup()
ctx := &models.AuthorizationContext{
UserID: "user123",
Resource: "document",
Action: "read",
ResourceData: make(map[string]string),
Environment: make(map[string]string),
}
// Mock permission query
permRows := sqlmock.NewRows([]string{"id", "permission_name", "description", "resource", "action"}).
AddRow(1, "read_document", "Read document permission", "document", "read")
mock.ExpectQuery("SELECT id, permission_name, description, resource, action FROM permissions WHERE resource = \\? AND action = \\? LIMIT 1").
WithArgs("document", "read").
WillReturnRows(permRows)
// Mock user attributes query with error
mock.ExpectQuery("SELECT attribute_name, attribute_value FROM user_attributes WHERE user_id = \\?").
WithArgs("user123").
WillReturnError(errors.New("database error"))
result, err := Authorize(ctx)
if err == nil {
t.Error("Expected error for user attributes failure")
}
if result.Allowed {
t.Error("Expected access denied")
}
}
func TestAuthorize_PolicyAttributesError(t *testing.T) {
mock, cleanup := setupMockDB(t)
defer cleanup()
ctx := &models.AuthorizationContext{
UserID: "user123",
Resource: "document",
Action: "read",
ResourceData: make(map[string]string),
Environment: make(map[string]string),
}
// Mock permission query
permRows := sqlmock.NewRows([]string{"id", "permission_name", "description", "resource", "action"}).
AddRow(1, "read_document", "Read document permission", "document", "read")
mock.ExpectQuery("SELECT id, permission_name, description, resource, action FROM permissions WHERE resource = \\? AND action = \\? LIMIT 1").
WithArgs("document", "read").
WillReturnRows(permRows)
// Mock user attributes query
attrRows := sqlmock.NewRows([]string{"attribute_name", "attribute_value"}).
AddRow("department", "engineering")
mock.ExpectQuery("SELECT attribute_name, attribute_value FROM user_attributes WHERE user_id = \\?").
WithArgs("user123").
WillReturnRows(attrRows)
// Mock policy attributes query with error
mock.ExpectQuery("SELECT id, attribute_name, attribute_type, comparison, attribute_value, permission_id FROM policy_attributes WHERE permission_id = \\?").
WithArgs(1).
WillReturnError(errors.New("database error"))
result, err := Authorize(ctx)
if err == nil {
t.Error("Expected error for policy attributes failure")
}
if result.Allowed {
t.Error("Expected access denied")
}
}
func TestCheckPermission_Success(t *testing.T) {
mock, cleanup := setupMockDB(t)
defer cleanup()
// Mock permission query
permRows := sqlmock.NewRows([]string{"id", "permission_name", "description", "resource", "action"}).
AddRow(1, "read_document", "Read document permission", "document", "read")
mock.ExpectQuery("SELECT id, permission_name, description, resource, action FROM permissions WHERE resource = \\? AND action = \\? LIMIT 1").
WithArgs("document", "read").
WillReturnRows(permRows)
// Mock user attributes query
attrRows := sqlmock.NewRows([]string{"attribute_name", "attribute_value"}).
AddRow("department", "engineering")
mock.ExpectQuery("SELECT attribute_name, attribute_value FROM user_attributes WHERE user_id = \\?").
WithArgs("user123").
WillReturnRows(attrRows)
// Mock policy attributes query
policyRows := sqlmock.NewRows([]string{"id", "attribute_name", "attribute_type", "comparison", "attribute_value", "permission_id"})
mock.ExpectQuery("SELECT id, attribute_name, attribute_type, comparison, attribute_value, permission_id FROM policy_attributes WHERE permission_id = \\?").
WithArgs(1).
WillReturnRows(policyRows)
resourceData := map[string]string{"document_id": "123"}
allowed, message, err := CheckPermission("user123", "document", "read", resourceData)
if err != nil {
t.Errorf("Expected no error, got %v", err)
}
if !allowed {
t.Error("Expected access allowed")
}
if message != "Access granted" {
t.Errorf("Expected 'Access granted', got '%s'", message)
}
}
func TestCheckPermission_Denied(t *testing.T) {
mock, cleanup := setupMockDB(t)
defer cleanup()
mock.ExpectQuery("SELECT id, permission_name, description, resource, action FROM permissions WHERE resource = \\? AND action = \\? LIMIT 1").
WithArgs("document", "read").
WillReturnError(errors.New("permission not found"))
resourceData := map[string]string{"document_id": "123"}
allowed, message, err := CheckPermission("user123", "document", "read", resourceData)
if err != nil {
t.Errorf("Expected no error, got %v", err)
}
if allowed {
t.Error("Expected access denied")
}
if message == "" {
t.Error("Expected error message")
}
}
func TestCheckPermission_NilResourceData(t *testing.T) {
mock, cleanup := setupMockDB(t)
defer cleanup()
// Mock permission query
permRows := sqlmock.NewRows([]string{"id", "permission_name", "description", "resource", "action"}).
AddRow(1, "read_document", "Read document permission", "document", "read")
mock.ExpectQuery("SELECT id, permission_name, description, resource, action FROM permissions WHERE resource = \\? AND action = \\? LIMIT 1").
WithArgs("document", "read").
WillReturnRows(permRows)
// Mock user attributes query
attrRows := sqlmock.NewRows([]string{"attribute_name", "attribute_value"})
mock.ExpectQuery("SELECT attribute_name, attribute_value FROM user_attributes WHERE user_id = \\?").
WithArgs("user123").
WillReturnRows(attrRows)
// Mock policy attributes query
policyRows := sqlmock.NewRows([]string{"id", "attribute_name", "attribute_type", "comparison", "attribute_value", "permission_id"})
mock.ExpectQuery("SELECT id, attribute_name, attribute_type, comparison, attribute_value, permission_id FROM policy_attributes WHERE permission_id = \\?").
WithArgs(1).
WillReturnRows(policyRows)
allowed, message, err := CheckPermission("user123", "document", "read", nil)
if err != nil {
t.Errorf("Expected no error, got %v", err)
}
// Should not panic with nil resourceData
if !allowed {
t.Logf("Access denied with message: %s", message)
}
}