149 lines
5.9 KiB
Go
149 lines
5.9 KiB
Go
package router_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/veylant/ia-gateway/internal/config"
|
|
"github.com/veylant/ia-gateway/internal/router"
|
|
)
|
|
|
|
// defaultRBACConfig is a realistic config used across most tests.
|
|
var defaultRBACConfig = &config.RBACConfig{
|
|
UserAllowedModels: []string{"gpt-4o-mini", "gpt-3.5-turbo", "mistral-small"},
|
|
AuditorCanComplete: false,
|
|
}
|
|
|
|
// ─── Admin ───────────────────────────────────────────────────────────────────
|
|
|
|
func TestHasAccess_Admin_AllModelsAllowed(t *testing.T) {
|
|
for _, model := range []string{"gpt-4o", "claude-3-opus", "mistral-medium", "llama3"} {
|
|
err := router.HasAccess([]string{"admin"}, model, defaultRBACConfig)
|
|
assert.NoError(t, err, "admin should access %q", model)
|
|
}
|
|
}
|
|
|
|
func TestHasAccess_AdminCaseInsensitive(t *testing.T) {
|
|
err := router.HasAccess([]string{"ADMIN"}, "claude-3-opus", defaultRBACConfig)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
// ─── Manager ─────────────────────────────────────────────────────────────────
|
|
|
|
func TestHasAccess_Manager_AllModelsAllowed(t *testing.T) {
|
|
for _, model := range []string{"gpt-4o", "claude-3-opus", "mistral-medium"} {
|
|
err := router.HasAccess([]string{"manager"}, model, defaultRBACConfig)
|
|
assert.NoError(t, err, "manager should access %q", model)
|
|
}
|
|
}
|
|
|
|
func TestHasAccess_ManagerCaseInsensitive(t *testing.T) {
|
|
err := router.HasAccess([]string{"Manager"}, "gpt-4o", defaultRBACConfig)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
// ─── Auditor ─────────────────────────────────────────────────────────────────
|
|
|
|
func TestHasAccess_Auditor_Blocked_WhenCanCompleteIsFalse(t *testing.T) {
|
|
err := router.HasAccess([]string{"auditor"}, "gpt-4o-mini", defaultRBACConfig)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "auditor")
|
|
}
|
|
|
|
func TestHasAccess_Auditor_Allowed_WhenCanCompleteIsTrue(t *testing.T) {
|
|
cfg := &config.RBACConfig{
|
|
UserAllowedModels: defaultRBACConfig.UserAllowedModels,
|
|
AuditorCanComplete: true,
|
|
}
|
|
err := router.HasAccess([]string{"auditor"}, "gpt-4o-mini", cfg)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
func TestHasAccess_AuditorCaseInsensitive(t *testing.T) {
|
|
err := router.HasAccess([]string{"AUDITOR"}, "gpt-4o-mini", defaultRBACConfig)
|
|
require.Error(t, err)
|
|
}
|
|
|
|
// ─── User ─────────────────────────────────────────────────────────────────────
|
|
|
|
func TestHasAccess_User_AllowedModel_ExactMatch(t *testing.T) {
|
|
err := router.HasAccess([]string{"user"}, "gpt-4o-mini", defaultRBACConfig)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
func TestHasAccess_User_AllowedModel_PrefixMatch(t *testing.T) {
|
|
// "gpt-4o-mini" prefix matches "gpt-4o-mini-2024-07-18"
|
|
err := router.HasAccess([]string{"user"}, "gpt-4o-mini-2024-07-18", defaultRBACConfig)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
func TestHasAccess_User_AllowedModel_MistralSmall(t *testing.T) {
|
|
err := router.HasAccess([]string{"user"}, "mistral-small", defaultRBACConfig)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
func TestHasAccess_User_UnauthorizedModel_Claude(t *testing.T) {
|
|
err := router.HasAccess([]string{"user"}, "claude-3-opus", defaultRBACConfig)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "claude-3-opus")
|
|
}
|
|
|
|
func TestHasAccess_User_UnauthorizedModel_GPT4o(t *testing.T) {
|
|
err := router.HasAccess([]string{"user"}, "gpt-4o", defaultRBACConfig)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "gpt-4o")
|
|
}
|
|
|
|
func TestHasAccess_UserCaseInsensitive(t *testing.T) {
|
|
err := router.HasAccess([]string{"USER"}, "gpt-4o-mini", defaultRBACConfig)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
// ─── Unknown / empty roles ────────────────────────────────────────────────────
|
|
|
|
func TestHasAccess_UnknownRole_TreatedAsUser_AllowedModel(t *testing.T) {
|
|
err := router.HasAccess([]string{"viewer"}, "gpt-4o-mini", defaultRBACConfig)
|
|
require.NoError(t, err) // gpt-4o-mini is in UserAllowedModels
|
|
}
|
|
|
|
func TestHasAccess_UnknownRole_TreatedAsUser_BlockedModel(t *testing.T) {
|
|
err := router.HasAccess([]string{"viewer"}, "claude-3-opus", defaultRBACConfig)
|
|
require.Error(t, err)
|
|
}
|
|
|
|
func TestHasAccess_EmptyRoles_TreatedAsUser(t *testing.T) {
|
|
err := router.HasAccess([]string{}, "gpt-4o-mini", defaultRBACConfig)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
func TestHasAccess_EmptyRoles_BlockedModel(t *testing.T) {
|
|
err := router.HasAccess([]string{}, "claude-3-opus", defaultRBACConfig)
|
|
require.Error(t, err)
|
|
}
|
|
|
|
// ─── Multi-role ───────────────────────────────────────────────────────────────
|
|
|
|
func TestHasAccess_MultiRole_AdminWins(t *testing.T) {
|
|
// user has both "user" and "admin" — admin takes priority
|
|
err := router.HasAccess([]string{"user", "admin"}, "claude-3-opus", defaultRBACConfig)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
func TestHasAccess_MultiRole_ManagerWins(t *testing.T) {
|
|
err := router.HasAccess([]string{"auditor", "manager"}, "claude-3-opus", defaultRBACConfig)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
// ─── Empty allowed models ─────────────────────────────────────────────────────
|
|
|
|
func TestHasAccess_EmptyAllowedModels_UserAlwaysBlocked(t *testing.T) {
|
|
cfg := &config.RBACConfig{
|
|
UserAllowedModels: []string{},
|
|
AuditorCanComplete: false,
|
|
}
|
|
err := router.HasAccess([]string{"user"}, "gpt-4o-mini", cfg)
|
|
require.Error(t, err)
|
|
}
|