Skip to content

Commit

Permalink
Merge pull request #88 from veracode/identity-roles
Browse files Browse the repository at this point in the history
Identity roles
  • Loading branch information
tjarrettveracode authored Oct 9, 2024
2 parents bb6330c + d069ce9 commit e1fc5b3
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 2 deletions.
2 changes: 2 additions & 0 deletions docs/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ See the topics below for more information on how to use this library.
* [Teams](teams.md) - create, update, access, and delete teams.
* [Business Units](businessunits.md) - create, update, access, and delete business units.
* [API Credentials](apicreds.md) - create, access, renew, and revoke API credentials.
* [Roles and Permissions](roles.md) - access system roles and permissions; create, update, access, and delete custom roles.
* [JIT Default Settings](jitdefaults.md) - create and update default Just-In-Time Provisioning settings.

## API Object

Expand Down
19 changes: 19 additions & 0 deletions docs/jitdefaults.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Just In Time Provisioning Default Settings

The following methods call Veracode REST APIs and return JSON. More information about the JIT settings is available in the [Veracode Docs](https://docs.veracode.com/r/Configure_SAML_Self_Registration).

- `JITDefaultSettings().get()` - retrieve the current Just In Time (JIT) default settings.
- `JITDefaultSettings().create(ip_restricted(opt),prefer_veracode_data(opt), allowed_ip_addresses(opt), use_csv_for_roles_claim(opt), use_csv_for_teams_claim(opt), use_csv_for_teams_managed_claim(opt), use_csv_for_ip_address_claim(opt),teams(opt),roles(opt))` - create new Just In Time (JIT) default settings. Settings include:
- `ip_restricted`: set to `True` to apply IP restrictions (defined in `allowed_ip_addresses`) for a JIT user.
- `prefer_veracode_data`: set to `True` to allow an administrator to manage roles, teams, and other settings for users in the Veracode administrative console after user creation. If set to `False`, the SAML assertion sent from the customer's Identity Provider must contain these values.
- `allowed_ip_addresses`: an array of IP addresses. See the [Veracode Docs](https://docs.veracode.com/r/admin_ip) for more information.
- `use_csv_for_roles_claim`: set to `True` if your IDP will send a comma separated list of roles (instead of an array).
- `use_csv_for_teams_claim`: set to `True` if your IDP will send a comma separated list of teams (instead of an array).
- `use_csv_for_teams_managed_claim`: set to `True` if your IDP will send a comma separated list of teams managed by a team admin (instead of an array).
- `use_csv_for_ip_address_claim`: set to `True` if your IDP will send a comma separated list of IP address restrictions (instead of an array).
- `teams`: an array of team IDs (UUIDs) that should be assigned to a JIT user by default.
- `roles`: an array of role IDs (UUIDs) that should be assigned to a JIT user by default.
- `JITDefaultSettings().update(jit_default_id, ip_restricted(opt),prefer_veracode_data(opt), allowed_ip_addresses(opt), use_csv_for_roles_claim(opt), use_csv_for_teams_claim(opt), use_csv_for_teams_managed_claim(opt), use_csv_for_ip_address_claim(opt),teams(opt),roles(opt))` - update existing Just In Time (JIT) default settings identified by `jit_default_id`.
- `JITDefaultSettings().delete(jit_default_id)` - delete the Just In Time (JIT) default settings identified by `jit_default_id`.

[All docs](docs.md)
20 changes: 20 additions & 0 deletions docs/roles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Roles and Permissions

The following methods call Veracode REST APIs and return JSON.

- `Roles().get_all()`: get the list of roles for the organization.
- `Roles().get(role_guid)`: get the role definition for a given role.
- `Roles().create(role_name,role_description,is_api (opt),jit_assignable(opt),jit_assignable_default (opt),permissions (opt),child_roles (opt))`: create a role named `role_name`. You must specify either `permissions` or `child_roles`, or both. Arguments include:
- `role_description`: The human readable description of the role.
- `is_api`: Set to `True` to create a role for an API user. Defaults to `False`.
- `jit_assignable`: Set to `True` to allow the role to be assigned by a SAML assertion using just-in-time provisioning. Defaults to `True`.
- `jit_assignable_default`: Set to `True` to allow the role to be assigned by default during just-in-time provisioning. Defaults to `True`.
- `permissions`: An array of permission names. Use `Permissions().get_all()` to see the list of assignable permissions.
- `child_roles`: An array of role names. Adding a child role to a custom role gives the user all the permissions contained in the child role, in addition to any permissions defined in `permissinos`. You can add more than one child role.
- `Roles().update(role_name,role_description,role_guid,is_api (opt),jit_assignable(opt),jit_assignable_default (opt),permissions (opt),child_roles (opt))`: update the role identified by `role_guid` with the provided information.
- `Roles().delete(role_guid)`: delete the role identified by `role_guid`. Note: You can only delete custom roles.
- `Permissions().get_all()`: get the list of permissions that can be part of custom roles.
- `Permissions().get(permission_guid)`: get the permission definition for a given permission.


[All docs](docs.md)
29 changes: 28 additions & 1 deletion veracode_api_py/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from .policy import Policies
from .sca import ComponentActivity, Workspaces, SBOM, SCAApplications
from .collections import Collections
from .identity import Users, Teams, BusinessUnits, APICredentials, Roles
from .identity import Users, Teams, BusinessUnits, APICredentials, Roles, Permissions
from .healthcheck import Healthcheck
from .dynamic import Analyses, Scans, Occurrences, Configuration, CodeGroups, ScanCapacitySummary, ScanOccurrences, \
ScannerVariables, DynUtils
Expand Down Expand Up @@ -314,6 +314,33 @@ def revoke_creds(self, api_id):

def get_roles(self):
return Roles().get_all()

def get_role(self, role_guid: GUID):
return Roles().get(role_guid=role_guid)

def create_role(self, role_name, role_description, is_api=False, jit_assignable=True,
jit_assignable_default=True, permissions=[], child_roles=[]):
return Roles().create(role_name=role_name, role_description=role_description,
is_api=is_api, jit_assignable=jit_assignable,
jit_assignable_default=jit_assignable_default,
permissions=permissions, child_roles=child_roles)

def update_role(self, role_name, role_description, role_guid: UUID, is_api=False,
jit_assignable=True, jit_assignable_default=True,
permissions=[], child_roles=[]):
return Roles().update(role_name=role_name, role_description=role_description,
role_guid=role_guid, is_api=is_api, jit_assignable=jit_assignable,
jit_assignable_default=jit_assignable_default,
permissions=permissions, child_roles=child_roles)

def delete_role(self, role_guid: UUID):
return Roles().delete(role_guid=role_guid)

def get_permissions(self):
return Permissions().get_all()

def get_permission(self, permission_guid: UUID):
return Permissions().get(permission_guid=permission_guid)

## SCA APIs - note must be human user to use these, not API user

Expand Down
108 changes: 107 additions & 1 deletion veracode_api_py/identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,5 +251,111 @@ def revoke (self, api_id):
return APIHelper()._rest_request(self.base_uri + '/{}'.format(api_id), "DELETE")

class Roles():
base_uri = "api/authn/v2/roles"
def get_all(self):
return APIHelper()._rest_paged_request("api/authn/v2/roles","GET","roles",{'page':0})
return APIHelper()._rest_paged_request(self.base_uri,"GET","roles",{'page':0})

def get(self, role_guid: UUID):
return APIHelper()._rest_request("{}/{}".format(self.base_uri,role_guid),"GET")

def create(self, role_name, role_description, is_api=False, jit_assignable=True,
jit_assignable_default=True, permissions=[], child_roles=[]):
return self._create_or_update("CREATE", role_name=role_name, role_description=role_description,
is_api=is_api, jit_assignable=jit_assignable,
jit_assignable_default=jit_assignable_default,
permissions=permissions, child_roles=child_roles)

def update(self, role_name, role_description, role_guid: UUID, is_api=False,
jit_assignable=True, jit_assignable_default=True,
permissions=[], child_roles=[]):
# TODO handle partial and incremental
return self._create_or_update("UPDATE", role_name=role_name, role_description=role_description,
role_guid=role_guid, is_api=is_api, jit_assignable=jit_assignable,
jit_assignable_default=jit_assignable_default,
permissions=permissions, child_roles=child_roles)

def delete(self, role_guid: UUID):
return APIHelper()._rest_request("{}/{}".format(self.base_uri,role_guid),"DELETE")

def _create_or_update(self, method, role_name, role_description, role_guid: UUID=None, is_api=False,
jit_assignable=True,jit_assignable_default=True,
permissions=[], child_roles=[]):
uri = self.base_uri
if method == 'CREATE':
httpmethod = 'POST'
elif method == 'UPDATE':
uri = uri + '/{}'.format(role_guid)
httpmethod = 'PUT'
else:
return

role_def = { 'role_name': role_name, 'role_description': role_description, 'is_api': is_api,
'jit_assignable': jit_assignable, 'jit_assignable_default': jit_assignable_default}

if len(permissions) > 0:
role_def['permissions'] = permissions

if len(child_roles) > 0:
role_def['child_roles'] = child_roles

payload = json.dumps({"profile": role_def})
return APIHelper()._rest_request(uri,httpmethod,body=payload)

class Permissions():
base_uri = "api/authn/v2/permissions"
def get_all(self):
return APIHelper()._rest_paged_request( self.base_uri,"GET","permissions",{'page':0})

def get(self, permission_guid: UUID):
return APIHelper()._rest_request("{}/{}".format(self.base_uri,permission_guid),"GET")

class JITDefaultSettings():
base_uri = "api/authn/v2/jit_default_settings"

def get(self):
return APIHelper()._rest_request( self.base_uri, "GET")

def create(self, ip_restricted=False,prefer_veracode_data=True, allowed_ip_addresses=[],
use_csv_for_roles_claim=False, use_csv_for_teams_claim=False, use_csv_for_teams_managed_claim=False,
use_csv_for_ip_address_claim=True,teams=[],roles=[]):
return self._create_or_update("CREATE", ip_restricted=ip_restricted, prefer_veracode_data=prefer_veracode_data,
allowed_ip_addresses=allowed_ip_addresses, use_csv_for_roles_claim=use_csv_for_roles_claim,
use_csv_for_teams_claim=use_csv_for_teams_claim,
use_csv_for_teams_managed_claim=use_csv_for_teams_managed_claim,
use_csv_for_ip_address_claim=use_csv_for_ip_address_claim, teams=teams, roles=roles)

def update(self, jit_default_id: UUID, ip_restricted=False,prefer_veracode_data=True, allowed_ip_addresses=[],
use_csv_for_roles_claim=False, use_csv_for_teams_claim=False, use_csv_for_teams_managed_claim=False,
use_csv_for_ip_address_claim=True,teams=[],roles=[]):
return self._create_or_update("UPDATE", jit_default_id = jit_default_id, ip_restricted=ip_restricted,
prefer_veracode_data=prefer_veracode_data,allowed_ip_addresses=allowed_ip_addresses,
use_csv_for_roles_claim=use_csv_for_roles_claim,
use_csv_for_teams_claim=use_csv_for_teams_claim,
use_csv_for_teams_managed_claim=use_csv_for_teams_managed_claim,
use_csv_for_ip_address_claim=use_csv_for_ip_address_claim, teams=teams, roles=roles)

def _create_or_update(self, method, jit_default_id: UUID=None, ip_restricted=False,prefer_veracode_data=True, allowed_ip_addresses=[],
use_csv_for_roles_claim=False, use_csv_for_teams_claim=False, use_csv_for_teams_managed_claim=False,
use_csv_for_ip_address_claim=True,teams=[],roles=[]):

if method == "CREATE":
uri = self.base_uri
httpmethod = "POST"
elif method == "UPDATE":
uri = '{}/{}'.format(self.base_uri, jit_default_id)
httpmethod = "PUT"
else:
return

params = { 'ip_restricted': ip_restricted, 'prefer_veracode_data': prefer_veracode_data, 'allowed_ip_addresses': allowed_ip_addresses,
'use_csv_for_roles_claim': use_csv_for_roles_claim, 'use_csv_for_teams_claim': use_csv_for_teams_claim,
'use_csv_for_teams_managed_claim': use_csv_for_teams_managed_claim, 'use_csv_for_ip_address_claim': use_csv_for_ip_address_claim,
'teams': teams, 'roles': roles}

body = json.dumps(params)

return APIHelper()._rest_request(url=uri, method=httpmethod, params=body)

def delete(self, jit_default_id: UUID):
uri = '{}/{}'.format(self.base_uri, jit_default_id)
return APIHelper()._rest_request( uri, "DELETE")

0 comments on commit e1fc5b3

Please sign in to comment.