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

Microsoft graph applications enhancement #29750

Merged
merged 45 commits into from Oct 1, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
b0cc0c1
remove_service_principals_command was edited and a UT was added for it.
rshunim Sep 11, 2023
5d296b2
update command with UT
rshunim Sep 12, 2023
aa72642
password add and remove with UTs
rshunim Sep 13, 2023
6bc3473
autopep8
rshunim Sep 19, 2023
d632012
change application to service principal
rshunim Sep 19, 2023
69cf487
add new command
rshunim Sep 20, 2023
d76a038
remove dev from yml
rshunim Sep 20, 2023
650b56a
Merge branch 'master' into Microsoft_Graph_Applications_Enhancement
rshunim Sep 20, 2023
851fd6c
CR fixes
rshunim Sep 20, 2023
930766c
Merge branch 'master' of github.com:demisto/content into Microsoft_Gr…
rshunim Sep 20, 2023
262435e
Merge branch 'Microsoft_Graph_Applications_Enhancement' of github.com…
rshunim Sep 20, 2023
26e339e
pre commit
rshunim Sep 20, 2023
b70d41d
README.md
rshunim Sep 20, 2023
34d9d14
Merge branch 'master' into Microsoft_Graph_Applications_Enhancement
rshunim Sep 20, 2023
31c51bd
improve implementation
rshunim Sep 20, 2023
efb3f9f
Merge remote-tracking branch 'origin/Microsoft_Graph_Applications_Enh…
rshunim Sep 20, 2023
c927bdc
add two UTs
rshunim Sep 21, 2023
2883d24
fix pre commit
rshunim Sep 21, 2023
4ab81e9
fix pre commit
rshunim Sep 21, 2023
033f084
Merge branch 'master' into Microsoft_Graph_Applications_Enhancement
rshunim Sep 21, 2023
5cf2740
add UT
rshunim Sep 21, 2023
54df872
Merge remote-tracking branch 'origin/Microsoft_Graph_Applications_Enh…
rshunim Sep 21, 2023
e73bf5b
Merge branch 'master' into Microsoft_Graph_Applications_Enhancement
rshunim Sep 21, 2023
4ad1fed
Update Packs/MicrosoftGraphApplications/Integrations/MicrosoftGraphAp…
rshunim Sep 26, 2023
30d4777
Update Packs/MicrosoftGraphApplications/Integrations/MicrosoftGraphAp…
rshunim Sep 26, 2023
2e7b652
Update Packs/MicrosoftGraphApplications/Integrations/MicrosoftGraphAp…
rshunim Sep 26, 2023
a067eb6
Update Packs/MicrosoftGraphApplications/Integrations/MicrosoftGraphAp…
rshunim Sep 26, 2023
5cbed0f
CR's fixes
rshunim Sep 26, 2023
727b45d
Merge remote-tracking branch 'origin/Microsoft_Graph_Applications_Enh…
rshunim Sep 26, 2023
1ce5511
mypy error
rshunim Sep 26, 2023
acb57ac
Merge branch 'master' into Microsoft_Graph_Applications_Enhancement
rshunim Sep 26, 2023
36bdfda
fixture
rshunim Sep 26, 2023
5271dc9
fix description
rshunim Sep 26, 2023
8a07d6e
fix description
rshunim Sep 26, 2023
e4eb666
CR's fixes
rshunim Sep 27, 2023
ae9ba13
Merge branch 'master' into Microsoft_Graph_Applications_Enhancement
rshunim Sep 27, 2023
f50f26e
command examples were added
rshunim Sep 27, 2023
9d704c5
Merge remote-tracking branch 'origin/Microsoft_Graph_Applications_Enh…
rshunim Sep 27, 2023
6684ab0
Merge branch 'master' into Microsoft_Graph_Applications_Enhancement
rshunim Sep 27, 2023
db799a4
Demo's fixes
rshunim Sep 28, 2023
c7450ef
Merge remote-tracking branch 'origin/Microsoft_Graph_Applications_Enh…
rshunim Sep 28, 2023
186f965
Merge branch 'master' into Microsoft_Graph_Applications_Enhancement
rshunim Sep 28, 2023
ab86f04
Merge branch 'master' into Microsoft_Graph_Applications_Enhancement
rshunim Sep 30, 2023
dd7abaf
docker image
rshunim Sep 30, 2023
be41128
Merge remote-tracking branch 'origin/Microsoft_Graph_Applications_Enh…
rshunim Sep 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -82,6 +82,44 @@ def get_service_principals(
results.extend(res.get('value'))
return results

def get_single_service_principal(
self,
service_id: str
):
"""

Arguments:
service_id: object id or application id of the service.

Returns:
Retrieve the properties and relationships of a servicePrincipal object.

Docs:
https://learn.microsoft.com/en-us/graph/api/serviceprincipal-get?view=graph-rest-1.0&tabs=http
"""
suffix = f'v1.0/servicePrincipals{service_id}'
return self.ms_client.http_request(method='GET', url_suffix=suffix)

def update_single_service_principal(
self,
service_id: str,
data: dict
):
"""

Arguments:
service_id: object id or application id of the service.
data: Fields to update.
rshunim marked this conversation as resolved.
Show resolved Hide resolved

Returns:
Update the properties of servicePrincipal object.

Docs:
https://learn.microsoft.com/en-us/graph/api/serviceprincipal-update?view=graph-rest-1.0&tabs=http
"""
suffix = f'v1.0/servicePrincipals{service_id}'
return self.ms_client.http_request(method='PATCH', url_suffix=suffix, json_data=data, return_empty_response=True)

def delete_service_principals(
self,
service_id: str
Expand All @@ -100,9 +138,48 @@ def delete_service_principals(
Docs:
https://docs.microsoft.com/en-us/graph/api/serviceprincipal-delete?view=graph-rest-1.0&tabs=http
"""
self.ms_client.http_request(
'DELETE', f'v1.0/servicePrincipals/{service_id}', return_empty_response=True
)
self.ms_client.http_request(method='DELETE', url_suffix=f'v1.0/servicePrincipals{service_id}', return_empty_response=True)

def add_password_application(
self,
service_id: str,
data: dict
):
"""

Arguments:
service_id: object id or application id of the service.
data: the body request.
rshunim marked this conversation as resolved.
Show resolved Hide resolved

Returns:
Adds a strong password or secret to an application.

Docs:
https://learn.microsoft.com/en-us/graph/api/application-addpassword?view=graph-rest-1.0&tabs=http
"""
suffix = f'v1.0/applications{service_id}/addPassword'
json_data = {"passwordCredential": data}
return self.ms_client.http_request(method='POST', url_suffix=suffix, json_data=json_data)

def remove_password_application(
self,
service_id: str,
data: dict
):
"""

Arguments:
service_id: object id or application id of the service.
data: the body request.
rshunim marked this conversation as resolved.
Show resolved Hide resolved

Returns:
Remove a password from an application.

Docs:
https://learn.microsoft.com/en-us/graph/api/application-removepassword?view=graph-rest-1.0&tabs=http
"""
suffix = f'v1.0/applications{service_id}/removePassword'
return self.ms_client.http_request(method='POST', url_suffix=suffix, json_data=data, return_empty_response=True)


''' COMMAND FUNCTIONS '''
Expand Down Expand Up @@ -152,6 +229,134 @@ def list_service_principals_command(ms_client: Client, args: dict) -> CommandRes
)


def validate_service_principal_input(args: dict) -> tuple:
rshunim marked this conversation as resolved.
Show resolved Hide resolved
"""
Ensure at least one argument is given.
rshunim marked this conversation as resolved.
Show resolved Hide resolved

Args:
args: The arguments were passed with the command.

Returns:
If the two arguments are missing, raise an exception, otherwise return one of them.
rshunim marked this conversation as resolved.
Show resolved Hide resolved
rshunim marked this conversation as resolved.
Show resolved Hide resolved
"""
object_id = args.get('id')
app_client_id = args.get('app_id')
if not (object_id or app_client_id):
raise DemistoException("User must provide one of (object) id or application id.")
rshunim marked this conversation as resolved.
Show resolved Hide resolved

# if both are provided, pass the object_id
if object_id:
return f"/{object_id}", object_id
return f"(appId='{app_client_id}')", app_client_id


def get_service_principal_command(ms_client: Client, args: dict) -> CommandResults:
"""

Args:
ms_client: The Client
args: demisto.args()

Returns:
Results to post in demisto
"""
id_for_request, service_id = validate_service_principal_input(args=args)
results = ms_client.get_single_service_principal(id_for_request)
return CommandResults(
'MSGraphApplication',
'id',
outputs=results,
readable_output=tableToMarkdown(
'Available service (application):',
results,
headers=['id', 'appId', 'appDisplayName', 'accountEnabled', 'deletedDateTime'],
removeNull=True
)
)


def update_service_principal_command(ms_client: Client, args: dict) -> CommandResults:
"""
Update the properties of servicePrincipal object.
Args:
ms_client: The Client
args: demisto.args()

Returns:
an informative message.
"""
id_for_request, service_id = validate_service_principal_input(args=args)
data = {}

if account_enabled := args.get("account_enabled"):
data["accountEnabled"] = argToBoolean(account_enabled)

# Dict
rshunim marked this conversation as resolved.
Show resolved Hide resolved
if add_ins := args.get("add_ins"):
data["addIns"] = add_ins

rshunim marked this conversation as resolved.
Show resolved Hide resolved
# String collection
if alternative_names := args.get("alternative_names"):
data["alternativeNames"] = alternative_names

if app_role_assignment_required := args.get("app_role_assignment_required"):
data["appRoleAssignmentRequired"] = argToBoolean(app_role_assignment_required)

# Dict collection
if app_roles := args.get("app_roles"):
data["appRoles"] = app_roles

# Dict
if custom_security_attributes := args.get("custom_security_attributes"):
data["customSecurityAttributes"] = custom_security_attributes

# String
if display_name := args.get("display_name"):
data["displayName"] = display_name

# String
if home_page := args.get("home_page"):
data["homepage"] = home_page

# Dict collection
if key_credentials := args.get("key_credentials"):
data["keyCredentials"] = key_credentials

# String
if logout_url := args.get("logout_url"):
data["logoutUrl"] = logout_url

# Dict collection
if oauth2_permission_scopes := args.get("oauth2_permission_scopes"):
data["oauth2PermissionScopes"] = oauth2_permission_scopes

# String
if preferred_single_sign_on_mode := args.get("preferred_single_sign_on_mode"):
data["preferredSingleSignOnMode"] = preferred_single_sign_on_mode

# String collection
if reply_urls := args.get("reply_urls"):
data["replyUrls"] = reply_urls

# String collection
if service_principal_names := args.get("service_principal_names"):
data["servicePrincipalNames"] = service_principal_names

# String collection
if tags := args.get("tags"):
data["tags"] = tags

# String
if token_encryption_key_id := args.get("token_encryption_key_id"):
data["tokenEncryptionKeyId"] = token_encryption_key_id

ms_client.update_single_service_principal(id_for_request, data=data)

return CommandResults(
readable_output=f'Service {service_id} was updated successfully.'
)


def remove_service_principals_command(ms_client: Client, args: dict) -> CommandResults:
"""Remove an authorized app.

Expand All @@ -162,10 +367,64 @@ def remove_service_principals_command(ms_client: Client, args: dict) -> CommandR
Returns:
Results to post in demisto
"""
app_id = str(args.get('id'))
ms_client.delete_service_principals(app_id)
id_for_request, service_id = validate_service_principal_input(args=args)
ms_client.delete_service_principals(id_for_request)
return CommandResults(
readable_output=f'Service {service_id} was deleted.'
)


def add_password_application_command(ms_client: Client, args: dict) -> CommandResults:
"""
Adds a strong password or secret to an application.

Arguments:
ms_client: The Client
args: demisto.args()

Returns:
Results to post in demisto
"""
id_for_request, service_id = validate_service_principal_input(args=args)

data = {}

if display_name := args.get("display_name"):
data["displayName"] = display_name
if end_date_time := args.get("end_date_time"):
data["endDateTime"] = end_date_time
if start_date_time := args.get("start_date_time"):
data["startDateTime"] = start_date_time
rshunim marked this conversation as resolved.
Show resolved Hide resolved

results = ms_client.add_password_application(id_for_request, data=data)

return CommandResults(
'MSGraphApplication',
'id',
outputs=results,
readable_output=f'A password was added to application {service_id} successfully.'
)


def remove_password_application_command(ms_client: Client, args: dict) -> CommandResults:
"""
Remove a password from an application.

Arguments:
ms_client: The Client
args: demisto.args()

Returns:
Results to post in demisto
"""
id_for_request, service_id = validate_service_principal_input(args=args)

data = {"keyId": args["key_id"]}

ms_client.remove_password_application(id_for_request, data=data)

return CommandResults(
readable_output=f'Service {app_id} was deleted.'
readable_output=f'The password of the unique identifier {args["key_id"]} was removed successfully.'
)


Expand Down Expand Up @@ -227,6 +486,14 @@ def main():
return_results(list_service_principals_command(client, args))
elif command == 'msgraph-apps-service-principal-remove':
return_results(remove_service_principals_command(client, args))
elif command == 'msgraph-apps-service-principal-get':
return_results(get_service_principal_command(client, args))
elif command == 'msgraph-apps-service-principal-update':
return_results(update_service_principal_command(client, args))
elif command == 'msgraph-apps-application-password-add':
return_results(add_password_application_command(client, args))
elif command == 'msgraph-apps-application-password-remove':
return_results(remove_password_application_command(client, args))
else:
raise NotImplementedError(f"Command '{command}' not found.")

Expand Down