Skip to content
This repository was archived by the owner on Dec 5, 2025. It is now read-only.

Conversation

@peritz
Copy link

@peritz peritz commented Jan 27, 2025

Proposed changes

  • Addition of administrative entities such as:
    • Settings
    • User
    • Group
    • Role
    • Capability
  • Updating documentation to autodoc class members for entity classes
  • Perform cleanup of test entities in the event that tests fail (important when testing User, since you cannot create a user that already exists)

Related issues

None that I'm aware of

Checklist

  • I consider the submitted work as finished
  • I tested the code for its functionality
  • I wrote test cases for the relevant uses case
  • I added/update the relevant documentation (either on github or on notion)
  • Where necessary I refactored code to improve the overall quality

Further comments

The rationale behind adding administrative functionality is to allow scripts to be more easily created which manage the platform in a programatic fashion, such as to create users for connectors as part of a Terraform module, or automatic rotation of user API tokens for service accounts.

This can be achieved through the GraphQL queries, but by including these in the library we reduce the code overhead and can take advantage of existing session management code in the API client. It also reduces the barrier to entry for those looking to create administrative tooling.

Addition of all administrative functionality is not complete. Currently, only user, group, role, and settings management has been included.

In the future I'd also like to include entities for managing vocabularies, entity settings, etc.

@marieflorescontact marieflorescontact self-requested a review January 29, 2025 11:19
@marieflorescontact marieflorescontact self-assigned this Jan 29, 2025
Copy link
Member

@marieflorescontact marieflorescontact left a comment

Choose a reason for hiding this comment

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

Hi @peritz,
I've started to review your code. I've made some comments. I'll go further next week 🙂
thank you for your submission!!!

orderMode = kwargs.get("orderMode", None)
search = kwargs.get("search", None)
filters = kwargs.get("filters", None)
customAttributes = kwargs.get("customAttributes", None)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
customAttributes = kwargs.get("customAttributes", None)
custom_attributes = kwargs.get("customAttributes", None)

we prefer to use snake_case for variable name

Copy link
Author

Choose a reason for hiding this comment

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

Fixed this in all new entities

)
query = (
"""
mutation MarkingForbid($groupId: ID!, $markingId: StixRef!) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
mutation MarkingForbid($groupId: ID!, $markingId: StixRef!) {
mutation GroupEditMarkingRemove($groupId: ID!, $markingId: StixRef!) {

Copy link
Member

Choose a reason for hiding this comment

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

or GroupEditRemoveRelation=> something staring w/ GroupEdit

Copy link
Author

Choose a reason for hiding this comment

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

Updated query names to include Edit for each relevant query


entity_class.base_class().delete(id=test_indicator["id"])
finally:
entity_class.base_class().delete(id=test_indicator["id"])
Copy link
Member

Choose a reason for hiding this comment

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

Using finally can be a problem:
The finally block is always executed, whether or not the assertion fails.
The solution would be to add a check before accessing test_indicator[‘id’] in finally :

finally:
    if test_indicator and "id" in test_indicator:
        entity_class.base_class().delete(id=test_indicator["id"])

Copy link
Author

Choose a reason for hiding this comment

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

Updated to check existence of entities before deletions in entity crud tests

@peritz
Copy link
Author

peritz commented Jan 31, 2025

@marieflorescontact I've updated the PR with changes you suggested, looking forward to the rest of the review :)

Copy link
Member

@marieflorescontact marieflorescontact left a comment

Choose a reason for hiding this comment

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

last "snake_case" comments :)

functionnaly tested ok User / Group / Role APIs
I will test the Setting part during the next days 🙂

entity_type
parent_types
created_at
updated_at
Copy link
Member

Choose a reason for hiding this comment

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

created_at and updated_at should be removed (there are User properties but not on Me type)

first = kwargs.get("first", 500)
after = kwargs.get("after", None)
orderBy = kwargs.get("orderBy", None)
orderMode = kwargs.get("orderMode", None)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
orderMode = kwargs.get("orderMode", None)
order_mode = kwargs.get("orderMode", None)

search = kwargs.get("search", None)
first = kwargs.get("first", 500)
after = kwargs.get("after", None)
orderBy = kwargs.get("orderBy", None)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
orderBy = kwargs.get("orderBy", None)
order_by = kwargs.get("orderBy", None)

"""
first = kwargs.get("first", 500)
after = kwargs.get("after", None)
orderBy = kwargs.get("orderBy", None)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
orderBy = kwargs.get("orderBy", None)
order_by = kwargs.get("orderBy", None)

first = kwargs.get("first", 500)
after = kwargs.get("after", None)
orderBy = kwargs.get("orderBy", None)
orderMode = kwargs.get("orderMode", None)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
orderMode = kwargs.get("orderMode", None)
order_mode = kwargs.get("orderMode", None)

filters = kwargs.get("filters", None)
custom_attributes = kwargs.get("customAttributes", None)
getAll = kwargs.get("getAll", False)
withPagination = kwargs.get("withPagination", False)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
withPagination = kwargs.get("withPagination", False)
with_pagination = kwargs.get("withPagination", False)

orderBy = kwargs.get("orderBy", None)
orderMode = kwargs.get("orderMode", None)
custom_attributes = kwargs.get("customAttributes", None)
getAll = kwargs.get("getAll", False)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
getAll = kwargs.get("getAll", False)
get_all = kwargs.get("getAll", False)

"""
first = kwargs.get("first", 500)
after = kwargs.get("after", None)
orderBy = kwargs.get("orderBy", "name")
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
orderBy = kwargs.get("orderBy", "name")
order_by = kwargs.get("orderBy", "name")

first = kwargs.get("first", 500)
after = kwargs.get("after", None)
orderBy = kwargs.get("orderBy", "name")
orderMode = kwargs.get("orderMode", "asc")
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
orderMode = kwargs.get("orderMode", "asc")
order_mode = kwargs.get("orderMode", "asc")

search = kwargs.get("search", None)
include_sessions = kwargs.get("include_sessions", False)
custom_attributes = kwargs.get("customAttributes", None)
getAll = kwargs.get("getAll", False)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
getAll = kwargs.get("getAll", False)
get_all = kwargs.get("getAll", False)

self.opencti = opencti
self.properties = """
id
entity_type
Copy link
Member

Choose a reason for hiding this comment

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

missing standard_id

standard_id
name
description
Copy link
Member

Choose a reason for hiding this comment

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

Not a big deal but for queries prefer to group all properties without empty line

}
}
fragment GroupEditionMarkings_group on Group {
Copy link
Member

Choose a reason for hiding this comment

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

we can remove the fragment and use same thing that in add_member API

created_at
updated_at
enterprise_edition
Copy link
Member

Choose a reason for hiding this comment

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

enterprise_edition has been removed in OpenCTI 6.5 freshly released, replaced by platform_enterprise_edition

@richard-julien richard-julien changed the base branch from master to issue/827 February 11, 2025 11:18
@richard-julien
Copy link
Member

richard-julien commented Feb 11, 2025

Will merge that in a branch and fix the latest comments.
Thanks for your PR @peritz

@richard-julien richard-julien merged commit a9a0ed1 into OpenCTI-Platform:issue/827 Feb 11, 2025
5 checks passed
@peritz
Copy link
Author

peritz commented Feb 13, 2025

Apologies I was out of office there for a time, thanks @richard-julien for the fixes and @marieflorescontact for the review

@marieflorescontact
Copy link
Member

Thanks for your contribution @peritz !!!! 🙂👌

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants