fix(routing): unify route based architecture
This commit is contained in:
137
test/core/utils/test.shared-security-manager.ts
Normal file
137
test/core/utils/test.shared-security-manager.ts
Normal file
@ -0,0 +1,137 @@
|
||||
import { expect } from '@push.rocks/tapbundle';
|
||||
import { SharedSecurityManager } from '../../../ts/core/utils/shared-security-manager.js';
|
||||
import type { IRouteConfig, IRouteContext } from '../../../ts/proxies/smart-proxy/models/route-types.js';
|
||||
|
||||
// Test security manager
|
||||
expect.describe('Shared Security Manager', async () => {
|
||||
let securityManager: SharedSecurityManager;
|
||||
|
||||
// Set up a new security manager before each test
|
||||
expect.beforeEach(() => {
|
||||
securityManager = new SharedSecurityManager({
|
||||
maxConnectionsPerIP: 5,
|
||||
connectionRateLimitPerMinute: 10
|
||||
});
|
||||
});
|
||||
|
||||
expect.it('should validate IPs correctly', async () => {
|
||||
// Should allow IPs under connection limit
|
||||
expect(securityManager.validateIP('192.168.1.1').allowed).to.be.true;
|
||||
|
||||
// Track multiple connections
|
||||
for (let i = 0; i < 4; i++) {
|
||||
securityManager.trackConnectionByIP('192.168.1.1', `conn_${i}`);
|
||||
}
|
||||
|
||||
// Should still allow IPs under connection limit
|
||||
expect(securityManager.validateIP('192.168.1.1').allowed).to.be.true;
|
||||
|
||||
// Add one more to reach the limit
|
||||
securityManager.trackConnectionByIP('192.168.1.1', 'conn_4');
|
||||
|
||||
// Should now block IPs over connection limit
|
||||
expect(securityManager.validateIP('192.168.1.1').allowed).to.be.false;
|
||||
|
||||
// Remove a connection
|
||||
securityManager.removeConnectionByIP('192.168.1.1', 'conn_0');
|
||||
|
||||
// Should allow again after connection is removed
|
||||
expect(securityManager.validateIP('192.168.1.1').allowed).to.be.true;
|
||||
});
|
||||
|
||||
expect.it('should authorize IPs based on allow/block lists', async () => {
|
||||
// Test with allow list only
|
||||
expect(securityManager.isIPAuthorized('192.168.1.1', ['192.168.1.*'])).to.be.true;
|
||||
expect(securityManager.isIPAuthorized('192.168.2.1', ['192.168.1.*'])).to.be.false;
|
||||
|
||||
// Test with block list
|
||||
expect(securityManager.isIPAuthorized('192.168.1.5', ['*'], ['192.168.1.5'])).to.be.false;
|
||||
expect(securityManager.isIPAuthorized('192.168.1.1', ['*'], ['192.168.1.5'])).to.be.true;
|
||||
|
||||
// Test with both allow and block lists
|
||||
expect(securityManager.isIPAuthorized('192.168.1.1', ['192.168.1.*'], ['192.168.1.5'])).to.be.true;
|
||||
expect(securityManager.isIPAuthorized('192.168.1.5', ['192.168.1.*'], ['192.168.1.5'])).to.be.false;
|
||||
});
|
||||
|
||||
expect.it('should validate route access', async () => {
|
||||
// Create test route with IP restrictions
|
||||
const route: IRouteConfig = {
|
||||
match: { ports: 443 },
|
||||
action: { type: 'forward', target: { host: 'localhost', port: 8080 } },
|
||||
security: {
|
||||
ipAllowList: ['192.168.1.*'],
|
||||
ipBlockList: ['192.168.1.5']
|
||||
}
|
||||
};
|
||||
|
||||
// Create test contexts
|
||||
const allowedContext: IRouteContext = {
|
||||
port: 443,
|
||||
clientIp: '192.168.1.1',
|
||||
serverIp: 'localhost',
|
||||
isTls: true,
|
||||
timestamp: Date.now(),
|
||||
connectionId: 'test_conn_1'
|
||||
};
|
||||
|
||||
const blockedContext: IRouteContext = {
|
||||
port: 443,
|
||||
clientIp: '192.168.1.5',
|
||||
serverIp: 'localhost',
|
||||
isTls: true,
|
||||
timestamp: Date.now(),
|
||||
connectionId: 'test_conn_2'
|
||||
};
|
||||
|
||||
const outsideContext: IRouteContext = {
|
||||
port: 443,
|
||||
clientIp: '192.168.2.1',
|
||||
serverIp: 'localhost',
|
||||
isTls: true,
|
||||
timestamp: Date.now(),
|
||||
connectionId: 'test_conn_3'
|
||||
};
|
||||
|
||||
// Test route access
|
||||
expect(securityManager.isAllowed(route, allowedContext)).to.be.true;
|
||||
expect(securityManager.isAllowed(route, blockedContext)).to.be.false;
|
||||
expect(securityManager.isAllowed(route, outsideContext)).to.be.false;
|
||||
});
|
||||
|
||||
expect.it('should validate basic auth', async () => {
|
||||
// Create test route with basic auth
|
||||
const route: IRouteConfig = {
|
||||
match: { ports: 443 },
|
||||
action: { type: 'forward', target: { host: 'localhost', port: 8080 } },
|
||||
security: {
|
||||
basicAuth: {
|
||||
enabled: true,
|
||||
users: [
|
||||
{ username: 'user1', password: 'pass1' },
|
||||
{ username: 'user2', password: 'pass2' }
|
||||
],
|
||||
realm: 'Test Realm'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Test valid credentials
|
||||
const validAuth = 'Basic ' + Buffer.from('user1:pass1').toString('base64');
|
||||
expect(securityManager.validateBasicAuth(route, validAuth)).to.be.true;
|
||||
|
||||
// Test invalid credentials
|
||||
const invalidAuth = 'Basic ' + Buffer.from('user1:wrongpass').toString('base64');
|
||||
expect(securityManager.validateBasicAuth(route, invalidAuth)).to.be.false;
|
||||
|
||||
// Test missing auth header
|
||||
expect(securityManager.validateBasicAuth(route)).to.be.false;
|
||||
|
||||
// Test malformed auth header
|
||||
expect(securityManager.validateBasicAuth(route, 'malformed')).to.be.false;
|
||||
});
|
||||
|
||||
// Clean up resources after tests
|
||||
expect.afterEach(() => {
|
||||
securityManager.clearIPTracking();
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user