package audit_logs import ( "fmt" "net/http" "testing" "time" "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/stretchr/testify/assert" user_enums "databasus-backend/internal/features/users/enums" users_middleware "databasus-backend/internal/features/users/middleware" users_services "databasus-backend/internal/features/users/services" users_testing "databasus-backend/internal/features/users/testing" test_utils "databasus-backend/internal/util/testing" ) func Test_GetGlobalAuditLogs_WithDifferentUserRoles_EnforcesPermissionsCorrectly(t *testing.T) { adminUser := users_testing.CreateTestUser(user_enums.UserRoleAdmin) memberUser := users_testing.CreateTestUser(user_enums.UserRoleMember) router := createRouter() service := GetAuditLogService() workspaceID := uuid.New() testID := uuid.New().String() // Create test logs with unique identifiers userLogMessage := fmt.Sprintf("Test log with user %s", testID) workspaceLogMessage := fmt.Sprintf("Test log with workspace %s", testID) standaloneLogMessage := fmt.Sprintf("Test log standalone %s", testID) createAuditLog(service, userLogMessage, &adminUser.UserID, nil) createAuditLog(service, workspaceLogMessage, nil, &workspaceID) createAuditLog(service, standaloneLogMessage, nil, nil) // Test ADMIN can access global logs var response GetAuditLogsResponse test_utils.MakeGetRequestAndUnmarshal(t, router, "/api/v1/audit-logs/global?limit=100", "Bearer "+adminUser.Token, http.StatusOK, &response) // Verify our specific test logs are present messages := extractMessages(response.AuditLogs) assert.Contains(t, messages, userLogMessage) assert.Contains(t, messages, workspaceLogMessage) assert.Contains(t, messages, standaloneLogMessage) // Test MEMBER cannot access global logs resp := test_utils.MakeGetRequest(t, router, "/api/v1/audit-logs/global", "Bearer "+memberUser.Token, http.StatusForbidden) assert.Contains(t, string(resp.Body), "only administrators can view global audit logs") } func Test_GetUserAuditLogs_WithDifferentUserRoles_EnforcesPermissionsCorrectly(t *testing.T) { adminUser := users_testing.CreateTestUser(user_enums.UserRoleAdmin) user1 := users_testing.CreateTestUser(user_enums.UserRoleMember) user2 := users_testing.CreateTestUser(user_enums.UserRoleMember) router := createRouter() service := GetAuditLogService() workspaceID := uuid.New() testID := uuid.New().String() // Create test logs for different users with unique identifiers user1FirstMessage := fmt.Sprintf("Test log user1 first %s", testID) user1SecondMessage := fmt.Sprintf("Test log user1 second %s", testID) user2FirstMessage := fmt.Sprintf("Test log user2 first %s", testID) user2SecondMessage := fmt.Sprintf("Test log user2 second %s", testID) workspaceLogMessage := fmt.Sprintf("Test workspace log %s", testID) createAuditLog(service, user1FirstMessage, &user1.UserID, nil) createAuditLog(service, user1SecondMessage, &user1.UserID, &workspaceID) createAuditLog(service, user2FirstMessage, &user2.UserID, nil) createAuditLog(service, user2SecondMessage, &user2.UserID, &workspaceID) createAuditLog(service, workspaceLogMessage, nil, &workspaceID) // Test ADMIN can view any user's logs var user1Response GetAuditLogsResponse test_utils.MakeGetRequestAndUnmarshal(t, router, fmt.Sprintf("/api/v1/audit-logs/users/%s?limit=100", user1.UserID.String()), "Bearer "+adminUser.Token, http.StatusOK, &user1Response) // Verify user1's specific logs are present messages := extractMessages(user1Response.AuditLogs) assert.Contains(t, messages, user1FirstMessage) assert.Contains(t, messages, user1SecondMessage) // Count only our test logs for user1 testLogsCount := 0 for _, message := range messages { if message == user1FirstMessage || message == user1SecondMessage { testLogsCount++ } } assert.Equal(t, 2, testLogsCount) // Test user can view own logs var ownLogsResponse GetAuditLogsResponse test_utils.MakeGetRequestAndUnmarshal(t, router, fmt.Sprintf("/api/v1/audit-logs/users/%s?limit=100", user2.UserID.String()), "Bearer "+user2.Token, http.StatusOK, &ownLogsResponse) // Verify user2's specific logs are present ownMessages := extractMessages(ownLogsResponse.AuditLogs) assert.Contains(t, ownMessages, user2FirstMessage) assert.Contains(t, ownMessages, user2SecondMessage) // Test user cannot view other user's logs resp := test_utils.MakeGetRequest(t, router, fmt.Sprintf("/api/v1/audit-logs/users/%s", user1.UserID.String()), "Bearer "+user2.Token, http.StatusForbidden) assert.Contains(t, string(resp.Body), "insufficient permissions") } func Test_GetGlobalAuditLogs_WithBeforeDateFilter_ReturnsFilteredLogs(t *testing.T) { adminUser := users_testing.CreateTestUser(user_enums.UserRoleAdmin) router := createRouter() baseTime := time.Now().UTC() // Set filter time to 30 minutes ago beforeTime := baseTime.Add(-30 * time.Minute) var filteredResponse GetAuditLogsResponse test_utils.MakeGetRequestAndUnmarshal( t, router, fmt.Sprintf( "/api/v1/audit-logs/global?beforeDate=%s&limit=1000", beforeTime.Format(time.RFC3339), ), "Bearer "+adminUser.Token, http.StatusOK, &filteredResponse, ) // Verify ALL returned logs are older than the filter time for _, log := range filteredResponse.AuditLogs { assert.True(t, log.CreatedAt.Before(beforeTime), fmt.Sprintf("Log created at %s should be before filter time %s", log.CreatedAt.Format(time.RFC3339), beforeTime.Format(time.RFC3339))) } } func createRouter() *gin.Engine { gin.SetMode(gin.TestMode) router := gin.New() SetupDependencies() v1 := router.Group("/api/v1") protected := v1.Group("").Use(users_middleware.AuthMiddleware(users_services.GetUserService())) GetAuditLogController().RegisterRoutes(protected.(*gin.RouterGroup)) return router }