Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alerts table and events with allowed agents only #3120

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions public/kibana-integrations/kibana-discover.js
Original file line number Diff line number Diff line change
Expand Up @@ -528,9 +528,10 @@ function discoverController(
searchBarChanges,
{
next: () => {
$scope.filters = filterManager.filters;
const customFilterAllowedAgents = getFilterWithAuthorizedAgents(store.getState().appStateReducers.allowedAgents);
frankeros marked this conversation as resolved.
Show resolved Hide resolved
$scope.filters = customFilterAllowedAgents ? _.union($scope.filters, [customFilterAllowedAgents]) : $scope.filters;
filterManager.filters = customFilterAllowedAgents ? _.union(filterManager.filters, [customFilterAllowedAgents]) : filterManager.filters;
$scope.filters = filterManager.filters;

// Wazuh. Hides the alerts of the '000' agent if it is in the configuration
const buildFilters = () => {
const { hideManagerAlerts } = wazuhConfig.getConfig();
Expand Down
2 changes: 1 addition & 1 deletion public/kibana-integrations/kibana-vis.js
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ class KibanaVis extends Component {

if (!filters.find((filter) => filter.meta.controlledBy === AUTHORIZED_AGENTS)) {
const agentsFilters = getFilterWithAuthorizedAgents(this.props.allowedAgents, vizPattern);
filters = Object.keys(agentsFilters).length ? union(filters, [agentsFilters]) : filters;
filters = agentsFilters ? union(filters, [agentsFilters]) : filters;
}

const visInput = {
Expand Down
127 changes: 127 additions & 0 deletions public/react-services/wz-authentication.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import { WzAuthentication } from './wz-authentication';

describe('Wazuh Authentication', () => {
describe('User has agent permissions', () => {

describe('Given a user without agent:read permission', () => {
it('Should return true', () => {
const policies = {};
const result = WzAuthentication.userHasAgentsPermissions(policies);
expect(result).toBeTruthy();
});
});

describe('Given a user with read permission for all ids and groups', () => {
it('Should return false', () => {
const policies = {
'agent:read': {
'agent:id:*': 'allow',
'agent:group:*': 'allow',
}
};
const result = WzAuthentication.userHasAgentsPermissions(policies);
expect(result).not.toBeTruthy();
});
});

describe('Given a user with read permission for all ids only', () => {
it('Should return false', () => {
const policies = {
'agent:read': {
'agent:id:*': 'allow',
}
};
const result = WzAuthentication.userHasAgentsPermissions(policies);
expect(result).not.toBeTruthy();
});
});

describe('Given a user with read permission for all groups only', () => {
it('Should return false', () => {
const policies = {
'agent:read': {
'agent:id:*': 'allow',
}
};
const result = WzAuthentication.userHasAgentsPermissions(policies);
expect(result).not.toBeTruthy();
});
});

describe('Given a user with read permission for all ids and some ids too', () => {
it('Should return false', () => {
const policies = {
'agent:read': {
'agent:id:*': 'allow',
'agent:id:001': 'allow',
}
};
const result = WzAuthentication.userHasAgentsPermissions(policies);
expect(result).not.toBeTruthy();
});
});

describe('Given a user with read permission for all ids and some groups too', () => {
it('Should return false', () => {
const policies = {
'agent:read': {
'agent:id:*': 'allow',
'agent:group:default': 'allow',
}
};
const result = WzAuthentication.userHasAgentsPermissions(policies);
expect(result).not.toBeTruthy();
});
});

describe('Given a user with read permission for all ids but deny some ids too', () => {
it('Should return true', () => {
const policies = {
'agent:read': {
'agent:id:*': 'allow',
'agent:id:001': 'deny',
}
};
const result = WzAuthentication.userHasAgentsPermissions(policies);
expect(result).toBeTruthy();
});
});

describe('Given a user with read permission for all groups ids but deny some groups too', () => {
it('Should return true', () => {
const policies = {
'agent:read': {
'agent:groups:*': 'allow',
'agent:group:default': 'deny',
}
};
const result = WzAuthentication.userHasAgentsPermissions(policies);
expect(result).toBeTruthy();
});
});

describe('Given a user with read permission for some ids', () => {
it('Should return true', () => {
const policies = {
'agent:read': {
'agent:id:001': 'allow',
}
};
const result = WzAuthentication.userHasAgentsPermissions(policies);
expect(result).toBeTruthy();
});
});

describe('Given a user with read permission for some groups', () => {
it('Should return true', () => {
const policies = {
'agent:read': {
'agent:groups:default': 'allow',
}
};
const result = WzAuthentication.userHasAgentsPermissions(policies);
expect(result).toBeTruthy();
});
});
});
});
31 changes: 28 additions & 3 deletions public/react-services/wz-authentication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,18 @@ export class WzAuthentication{
// Decode token and get expiration time
const jwtPayload = jwtDecode(token);

// Get user Policies
const userPolicies = await WzAuthentication.getUserPolicies();

//Get allowed agents for the current user
const allowedAgents = await getAuthorizedAgents();
let allowedAgents: any = [];
if (WzAuthentication.userHasAgentsPermissions(userPolicies)) {
allowedAgents = await getAuthorizedAgents();
allowedAgents = allowedAgents.length ? allowedAgents : ['-1']; // users without read:agent police should not view info about any agent
}
store.dispatch(updateAllowedAgents(allowedAgents));

// Get user Policies
const userPolicies = await WzAuthentication.getUserPolicies();

// Dispatch actions to set permissions and roles
store.dispatch(updateUserPermissions(userPolicies));
store.dispatch(updateUserRoles(WzAuthentication.mapUserRolesIDToAdministratorRole(jwtPayload.rbac_roles || [])));
Expand Down Expand Up @@ -98,4 +104,23 @@ export class WzAuthentication{
throw error;
}
}

/**
* This function returns true only if the user has some police that need be filtered.
* Returns false if the user has permission for all agents.
* Returns true if the user has no one police for agent:read.
* @param policies
* @returns boolean
*/
static userHasAgentsPermissions(policies) {
const agentReadPolicies = policies['agent:read'];
if (agentReadPolicies) {
const allIds = agentReadPolicies['agent:id:*'] == 'allow';
const allGroups = agentReadPolicies['agent:group:*'] == 'allow';
const denyAgents = Object.keys(agentReadPolicies).filter(k => !k.includes('*') && agentReadPolicies[k] == 'deny').length;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you could use .some instead of .filter. You don't need the array filtered.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, great catch tks

return !((allIds || allGroups) && !denyAgents);
}
// users without read:agent police should not view info about any agent
return true;
}
}