Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
1a87f7fb
Commit
1a87f7fb
authored
3 years ago
by
Zamir Martins
Committed by
Natalia Tepluhina
3 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add validation for rule/yaml modes switch
it also fix a related inconsistency. EE: true Changelog: fixed
parent
7148f7c5
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
257 additions
and
9 deletions
+257
-9
ee/app/assets/javascripts/threat_monitoring/components/policy_editor/scan_result_policy/lib/actions.js
...omponents/policy_editor/scan_result_policy/lib/actions.js
+44
-0
ee/app/assets/javascripts/threat_monitoring/components/policy_editor/scan_result_policy/lib/index.js
.../components/policy_editor/scan_result_policy/lib/index.js
+1
-0
ee/app/assets/javascripts/threat_monitoring/components/policy_editor/scan_result_policy/policy_action_builder.vue
...olicy_editor/scan_result_policy/policy_action_builder.vue
+1
-0
ee/app/assets/javascripts/threat_monitoring/components/policy_editor/scan_result_policy/scan_result_policy_editor.vue
...y_editor/scan_result_policy/scan_result_policy_editor.vue
+11
-2
ee/spec/frontend/threat_monitoring/components/policy_editor/scan_result_policy/lib/actions_spec.js
...ents/policy_editor/scan_result_policy/lib/actions_spec.js
+178
-6
ee/spec/frontend/threat_monitoring/components/policy_editor/scan_result_policy/scan_result_policy_editor_spec.js
...itor/scan_result_policy/scan_result_policy_editor_spec.js
+22
-1
No files found.
ee/app/assets/javascripts/threat_monitoring/components/policy_editor/scan_result_policy/lib/actions.js
View file @
1a87f7fb
...
...
@@ -53,3 +53,47 @@ export function decomposeApprovers(action, approvers) {
);
return
{
...
newAction
,
...
approversInfo
};
}
/*
Check if users are present in approvers
*/
function
usersOutOfSync
(
action
,
approvers
)
{
const
users
=
approvers
.
filter
((
approver
)
=>
approver
.
type
===
USER_TYPE
);
const
usersIDs
=
action
?.
user_approvers_ids
?.
some
((
id
)
=>
!
users
.
find
((
approver
)
=>
approver
.
id
===
id
))
||
false
;
const
usersNames
=
action
?.
user_approvers
?.
some
(
(
userName
)
=>
!
users
.
find
((
approver
)
=>
approver
.
username
===
userName
),
)
||
false
;
const
userLength
=
(
action
?.
user_approvers
?.
length
||
0
)
+
(
action
?.
user_approvers_ids
?.
length
||
0
);
return
usersIDs
||
usersNames
||
userLength
!==
users
.
length
;
}
/*
Check if groups are present in approvers
*/
function
groupsOutOfSync
(
action
,
approvers
)
{
const
groups
=
approvers
.
filter
((
approver
)
=>
approver
.
type
===
GROUP_TYPE
);
const
groupsIDs
=
action
?.
group_approvers_ids
?.
some
((
id
)
=>
!
groups
.
find
((
approver
)
=>
approver
.
id
===
id
))
||
false
;
const
groupsPaths
=
action
?.
group_approvers
?.
some
(
(
path
)
=>
!
groups
.
find
((
approver
)
=>
approver
.
full_path
===
path
),
)
||
false
;
const
groupLength
=
(
action
?.
group_approvers
?.
length
||
0
)
+
(
action
?.
group_approvers_ids
?.
length
||
0
);
return
groupsIDs
||
groupsPaths
||
groupLength
!==
groups
.
length
;
}
/*
Check if yaml is out of sync with available approvers
*/
export
function
approversOutOfSync
(
action
,
existingApprovers
)
{
const
approvers
=
groupApprovers
(
existingApprovers
);
return
usersOutOfSync
(
action
,
approvers
)
||
groupsOutOfSync
(
action
,
approvers
);
}
This diff is collapsed.
Click to expand it.
ee/app/assets/javascripts/threat_monitoring/components/policy_editor/scan_result_policy/lib/index.js
View file @
1a87f7fb
export
{
fromYaml
}
from
'
./from_yaml
'
;
export
{
toYaml
}
from
'
./to_yaml
'
;
export
{
buildRule
}
from
'
./rules
'
;
export
{
approversOutOfSync
}
from
'
./actions
'
;
export
*
from
'
./humanize
'
;
export
const
DEFAULT_SCAN_RESULT_POLICY
=
`type: scan_result_policy
...
...
This diff is collapsed.
Click to expand it.
ee/app/assets/javascripts/threat_monitoring/components/policy_editor/scan_result_policy/policy_action_builder.vue
View file @
1a87f7fb
...
...
@@ -46,6 +46,7 @@ export default {
watch
:
{
approvers
(
values
)
{
this
.
action
=
decomposeApprovers
(
this
.
action
,
values
);
this
.
$emit
(
'
approversUpdated
'
,
this
.
approvers
);
},
approversToAdd
(
val
)
{
this
.
approvers
.
push
(
val
[
0
]);
...
...
This diff is collapsed.
Click to expand it.
ee/app/assets/javascripts/threat_monitoring/components/policy_editor/scan_result_policy/scan_result_policy_editor.vue
View file @
1a87f7fb
...
...
@@ -22,7 +22,7 @@ import { assignSecurityPolicyProject, modifyPolicy } from '../utils';
import
DimDisableContainer
from
'
../dim_disable_container.vue
'
;
import
PolicyActionBuilder
from
'
./policy_action_builder.vue
'
;
import
PolicyRuleBuilder
from
'
./policy_rule_builder.vue
'
;
import
{
DEFAULT_SCAN_RESULT_POLICY
,
fromYaml
,
toYaml
,
buildRule
}
from
'
./lib
'
;
import
{
DEFAULT_SCAN_RESULT_POLICY
,
fromYaml
,
toYaml
,
buildRule
,
approversOutOfSync
}
from
'
./lib
'
;
export
default
{
SECURITY_POLICY_ACTIONS
,
...
...
@@ -100,6 +100,7 @@ export default {
),
yamlEditorError
:
null
,
mode
:
EDITOR_MODE_RULE
,
existingApprovers
:
this
.
scanResultPolicyApprovers
,
};
},
computed
:
{
...
...
@@ -207,8 +208,15 @@ export default {
this
.
mode
=
mode
;
if
(
mode
===
EDITOR_MODE_YAML
&&
!
this
.
hasParsingError
)
{
this
.
yamlEditorValue
=
toYaml
(
this
.
policy
);
}
else
if
(
mode
===
EDITOR_MODE_RULE
&&
!
this
.
hasParsingError
)
{
if
(
approversOutOfSync
(
this
.
policy
.
actions
[
0
],
this
.
existingApprovers
))
{
this
.
yamlEditorError
=
new
Error
();
}
}
},
updatePolicyApprovers
(
values
)
{
this
.
existingApprovers
=
values
;
},
},
};
</
script
>
...
...
@@ -296,8 +304,9 @@ export default {
:key=
"index"
class=
"gl-mb-4"
:init-action=
"action"
:existing-approvers=
"
scanResultPolicy
Approvers"
:existing-approvers=
"
existing
Approvers"
@
changed=
"updateAction(index, $event)"
@
approversUpdated=
"updatePolicyApprovers"
/>
</dim-disable-container>
</template>
...
...
This diff is collapsed.
Click to expand it.
ee/spec/frontend/threat_monitoring/components/policy_editor/scan_result_policy/lib/actions_spec.js
View file @
1a87f7fb
...
...
@@ -3,6 +3,7 @@ import {
userIds
,
groupApprovers
,
decomposeApprovers
,
approversOutOfSync
,
}
from
'
ee/threat_monitoring/components/policy_editor/scan_result_policy/lib/actions
'
;
// As returned by endpoints based on API::Entities::UserBasic
...
...
@@ -10,7 +11,7 @@ const userApprover = {
id
:
1
,
name
:
null
,
state
:
null
,
username
:
null
,
username
:
'
user name
'
,
avatar_url
:
null
,
web_url
:
null
,
};
...
...
@@ -20,7 +21,7 @@ const groupApprover = {
id
:
2
,
name
:
null
,
full_name
:
null
,
full_path
:
null
,
full_path
:
'
full path
'
,
avatar_url
:
null
,
web_url
:
null
,
};
...
...
@@ -48,13 +49,13 @@ describe('groupApprovers', () => {
name
:
null
,
state
:
null
,
type
:
'
user
'
,
username
:
null
,
username
:
'
user name
'
,
web_url
:
null
,
},
{
avatar_url
:
null
,
full_name
:
null
,
full_path
:
null
,
full_path
:
'
full path
'
,
id
:
groupApprover
.
id
,
name
:
null
,
type
:
'
group
'
,
...
...
@@ -79,7 +80,7 @@ describe('groupApprovers', () => {
{
avatar_url
:
null
,
full_name
:
null
,
full_path
:
null
,
full_path
:
'
full path
'
,
id
:
groupApprover
.
id
,
name
:
null
,
type
:
'
group
'
,
...
...
@@ -96,7 +97,7 @@ describe('groupApprovers', () => {
name
:
null
,
state
:
null
,
type
:
'
user
'
,
username
:
null
,
username
:
'
user name
'
,
web_url
:
null
,
},
]);
...
...
@@ -168,3 +169,174 @@ describe('groupIds', () => {
expect
(
groupIds
(
groupedApprovers
)).
toStrictEqual
([
groupApprover
.
id
]);
});
});
describe
(
'
approversOutOfSync
'
,
()
=>
{
describe
(
'
with user_approvers_ids only
'
,
()
=>
{
it
.
each
`
ids | approvers | result
${[
1
]}
|
${[
userApprover
]}
|
${
false
}
${[]}
|
${[]}
|
${
false
}
${[]}
|
${[
userApprover
]}
|
${
true
}
${[
1
]}
|
${[]}
|
${
true
}
${[
1
,
2
]}
|
${[
userApprover
]}
|
${
true
}
${[
2
]}
|
${[]}
|
${
true
}
${[
2
]}
|
${[
userApprover
]}
|
${
true
}
`
(
'
return $result when ids and approvers length equal to $ids and $approvers.length
'
,
({
ids
,
approvers
,
result
})
=>
{
const
action
=
{
approvals_required
:
1
,
type
:
'
require_approval
'
,
user_approvers_ids
:
ids
,
};
expect
(
approversOutOfSync
(
action
,
approvers
)).
toBe
(
result
);
},
);
});
describe
(
'
with user_approvers only
'
,
()
=>
{
it
.
each
`
usernames | approvers | result
${[
'
user name
'
]}
|
${[
userApprover
]}
|
${
false
}
${[]}
|
${[]}
|
${
false
}
${[]}
|
${[
userApprover
]}
|
${
true
}
${[
'
user name
'
]}
|
${[]}
|
${
true
}
${[
'
user name
'
,
'
not present
'
]}
|
${[
userApprover
]}
|
${
true
}
${[
'
not present
'
]}
|
${[]}
|
${
true
}
${[
'
not present
'
]}
|
${[
userApprover
]}
|
${
true
}
`
(
'
return $result when usernames and approvers length equal to $usernames and $approvers.length
'
,
({
usernames
,
approvers
,
result
})
=>
{
const
action
=
{
approvals_required
:
1
,
type
:
'
require_approval
'
,
user_approvers
:
usernames
,
};
expect
(
approversOutOfSync
(
action
,
approvers
)).
toBe
(
result
);
},
);
});
describe
(
'
with user_approvers and user_approvers_ids
'
,
()
=>
{
it
.
each
`
ids | usernames | approvers | result
${[]}
|
${[
'
user name
'
]}
|
${[
userApprover
]}
|
${
false
}
${[
1
]}
|
${[]}
|
${[
userApprover
]}
|
${
false
}
${[]}
|
${[]}
|
${[]}
|
${
false
}
${[
1
]}
|
${[
'
user name
'
]}
|
${[
userApprover
]}
|
${
true
}
${[
1
]}
|
${[
'
not present
'
]}
|
${[
userApprover
]}
|
${
true
}
${[
2
]}
|
${[
'
user name
'
]}
|
${[
userApprover
]}
|
${
true
}
`
(
'
return $result when ids, usernames and approvers length equal to $ids, $usernames and $approvers.length
'
,
({
ids
,
usernames
,
approvers
,
result
})
=>
{
const
action
=
{
approvals_required
:
1
,
type
:
'
require_approval
'
,
user_approvers
:
usernames
,
user_approvers_ids
:
ids
,
};
expect
(
approversOutOfSync
(
action
,
approvers
)).
toBe
(
result
);
},
);
});
describe
(
'
with group_approvers_ids only
'
,
()
=>
{
it
.
each
`
ids | approvers | result
${[
2
]}
|
${[
groupApprover
]}
|
${
false
}
${[]}
|
${[]}
|
${
false
}
${[]}
|
${[
groupApprover
]}
|
${
true
}
${[
2
]}
|
${[]}
|
${
true
}
${[
2
,
3
]}
|
${[
groupApprover
]}
|
${
true
}
${[
3
]}
|
${[]}
|
${
true
}
${[
3
]}
|
${[
groupApprover
]}
|
${
true
}
`
(
'
return $result when ids and approvers length equal to $ids and $approvers.length
'
,
({
ids
,
approvers
,
result
})
=>
{
const
action
=
{
approvals_required
:
1
,
type
:
'
require_approval
'
,
group_approvers_ids
:
ids
,
};
expect
(
approversOutOfSync
(
action
,
approvers
)).
toBe
(
result
);
},
);
});
describe
(
'
with user_approvers, user_approvers_ids and group_approvers_ids
'
,
()
=>
{
it
.
each
`
user_ids | usernames | group_ids | approvers | result
${[]}
|
${[
'
user name
'
]}
|
${[
2
]}
|
${
allApprovers
}
|
${
false
}
${[
1
]}
|
${[]}
|
${[
2
]}
|
${
allApprovers
}
|
${
false
}
${[]}
|
${[]}
|
${[]}
|
${[]}
|
${
false
}
${[
1
]}
|
${[
'
user name
'
]}
|
${[
2
]}
|
${
allApprovers
}
|
${
true
}
${[]}
|
${[
'
user name
'
]}
|
${[
3
]}
|
${
allApprovers
}
|
${
true
}
${[
1
]}
|
${[]}
|
${[
3
]}
|
${
allApprovers
}
|
${
true
}
${[]}
|
${[]}
|
${[
2
]}
|
${[
groupApprover
]}
|
${
false
}
${[
1
]}
|
${[]}
|
${[
2
]}
|
${[
groupApprover
]}
|
${
true
}
${[]}
|
${[
'
user name
'
]}
|
${[
2
]}
|
${[
groupApprover
]}
|
${
true
}
${[]}
|
${[
'
user name
'
]}
|
${[]}
|
${[
userApprover
]}
|
${
false
}
${[
1
]}
|
${[]}
|
${[]}
|
${[
userApprover
]}
|
${
false
}
${[
1
]}
|
${[]}
|
${[
2
]}
|
${[
userApprover
]}
|
${
true
}
`
(
'
return $result when user_ids, usernames, group_ids and approvers length equal to $user_ids, $usernames, $group_ids and $approvers.length
'
,
({
user_ids
,
usernames
,
group_ids
,
approvers
,
result
})
=>
{
const
action
=
{
approvals_required
:
1
,
type
:
'
require_approval
'
,
user_approvers
:
usernames
,
user_approvers_ids
:
user_ids
,
group_approvers_ids
:
group_ids
,
};
expect
(
approversOutOfSync
(
action
,
approvers
)).
toBe
(
result
);
},
);
});
describe
(
'
with group_approvers only
'
,
()
=>
{
it
.
each
`
fullPath | approvers | result
${[
'
full path
'
]}
|
${[
groupApprover
]}
|
${
false
}
${[]}
|
${[]}
|
${
false
}
${[]}
|
${[
groupApprover
]}
|
${
true
}
${[
'
full path
'
]}
|
${[]}
|
${
true
}
${[
'
full path
'
,
'
not present
'
]}
|
${[
groupApprover
]}
|
${
true
}
${[
'
not present
'
]}
|
${[]}
|
${
true
}
${[
'
not present
'
]}
|
${[
groupApprover
]}
|
${
true
}
`
(
'
return $result when fullPath and approvers length equal to $fullPath and $approvers.length
'
,
({
fullPath
,
approvers
,
result
})
=>
{
const
action
=
{
approvals_required
:
1
,
type
:
'
require_approval
'
,
group_approvers
:
fullPath
,
};
expect
(
approversOutOfSync
(
action
,
approvers
)).
toBe
(
result
);
},
);
});
describe
(
'
with user_approvers, user_approvers_ids, group_approvers_ids and group_approvers
'
,
()
=>
{
it
.
each
`
user_ids | usernames | group_ids | group_paths | approvers | result
${[]}
|
${[
'
user name
'
]}
|
${[
2
]}
|
${[]}
|
${
allApprovers
}
|
${
false
}
${[
1
]}
|
${[]}
|
${[
2
]}
|
${[]}
|
${
allApprovers
}
|
${
false
}
${[
1
]}
|
${[]}
|
${[]}
|
${[
'
full path
'
]}
|
${
allApprovers
}
|
${
false
}
${[]}
|
${[
'
user name
'
]}
|
${[]}
|
${[
'
full path
'
]}
|
${
allApprovers
}
|
${
false
}
${[]}
|
${[]}
|
${[]}
|
${[]}
|
${[]}
|
${
false
}
${[]}
|
${[
'
user name
'
]}
|
${[
3
]}
|
${[]}
|
${
allApprovers
}
|
${
true
}
${[
1
]}
|
${[]}
|
${[
3
]}
|
${[]}
|
${
allApprovers
}
|
${
true
}
${[
1
]}
|
${[]}
|
${[]}
|
${[
'
not present
'
]}
|
${
allApprovers
}
|
${
true
}
${[]}
|
${[
'
user name
'
]}
|
${[]}
|
${[
'
not present
'
]}
|
${
allApprovers
}
|
${
true
}
${[
1
]}
|
${[]}
|
${[]}
|
${[
'
full path
'
]}
|
${[
groupApprovers
]}
|
${
true
}
${[]}
|
${[
'
user name
'
]}
|
${[]}
|
${[
'
full path
'
]}
|
${[
groupApprovers
]}
|
${
true
}
`
(
'
return $result when user_ids, usernames, group_ids, group_paths and approvers length equal to $user_ids, $usernames, $group_ids, $group_paths and $approvers.length
'
,
({
user_ids
,
usernames
,
group_ids
,
group_paths
,
approvers
,
result
})
=>
{
const
action
=
{
approvals_required
:
1
,
type
:
'
require_approval
'
,
user_approvers
:
usernames
,
user_approvers_ids
:
user_ids
,
group_approvers_ids
:
group_ids
,
group_approvers
:
group_paths
,
};
expect
(
approversOutOfSync
(
action
,
approvers
)).
toBe
(
result
);
},
);
});
});
This diff is collapsed.
Click to expand it.
ee/spec/frontend/threat_monitoring/components/policy_editor/scan_result_policy/scan_result_policy_editor_spec.js
View file @
1a87f7fb
...
...
@@ -52,7 +52,7 @@ describe('ScanResultPolicyEditor', () => {
branch
:
'
main
'
,
fullPath
:
'
path/to/existing-project
'
,
};
const
scanResultPolicyApprovers
=
[{
id
:
1
,
username
:
'
usernam
e
'
,
state
:
'
active
'
}];
const
scanResultPolicyApprovers
=
[{
id
:
1
,
username
:
'
the.on
e
'
,
state
:
'
active
'
}];
const
factory
=
({
propsData
=
{},
provide
=
{}
}
=
{})
=>
{
wrapper
=
shallowMount
(
ScanResultPolicyEditor
,
{
...
...
@@ -315,5 +315,26 @@ describe('ScanResultPolicyEditor', () => {
expect
(
findPolicyActionBuilder
().
props
(
'
initAction
'
)).
toEqual
(
UPDATED_ACTION
);
});
it
(
'
does not show alert when policy matches existing approvers
'
,
async
()
=>
{
factoryWithExistingPolicy
();
expect
(
findAlert
().
exists
()).
toBe
(
false
);
await
findPolicyEditorLayout
().
vm
.
$emit
(
'
update-editor-mode
'
,
EDITOR_MODE_RULE
);
expect
(
findAlert
().
exists
()).
toBe
(
false
);
});
it
(
'
shows alert when policy does not match existing approvers
'
,
async
()
=>
{
factory
();
expect
(
findAlert
().
exists
()).
toBe
(
false
);
await
findPolicyEditorLayout
().
vm
.
$emit
(
'
update-editor-mode
'
,
EDITOR_MODE_RULE
);
expect
(
findAlert
().
exists
()).
toBe
(
true
);
expect
(
findAlert
().
isVisible
()).
toBe
(
true
);
});
});
});
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment