Skip to content

Commit 361012c

Browse files
authored
Merge pull request blackducksoftware#47 from blackducksoftware/amacdonald/add-users-assignment-to-project
Adding support for assigning users to projects
2 parents 8a444f2 + 501dbd5 commit 361012c

File tree

3 files changed

+184
-2
lines changed

3 files changed

+184
-2
lines changed

blackduck/HubRestApi.py

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,11 @@ def _find_user_group_url(self, assignable_user_groups, user_group_name):
10371037
if user_group['name'] == user_group_name:
10381038
return user_group['usergroup']
10391039

1040+
def _find_user_url(self, assignable_user, user_name):
1041+
for user in assignable_user['items']:
1042+
if user['name'] == user_name:
1043+
return user['user']
1044+
10401045
def _project_role_urls(self, project_role_names):
10411046
all_project_roles = self.get_project_roles()
10421047
project_role_urls = list()
@@ -1099,8 +1104,61 @@ def assign_user_group_to_project(self, project_name, user_group_name, project_ro
10991104
else:
11001105
logging.warning("Did not find a project by the name {}".format(project_name))
11011106

1102-
def assign_user_to_project(self, user_name, project_name, project_roles_l):
1103-
pass
1107+
def assign_user_to_project(self, user_name, project_name, project_roles, limit=1000):
1108+
# Assign users to projects
1109+
project = self.get_project_by_name(project_name)
1110+
1111+
if project:
1112+
project_url = project['_meta']['href']
1113+
assignable_users_link = self.get_link(project, 'assignable-users')
1114+
paramstring = self.get_limit_paramstring(limit)
1115+
url = assignable_users_link + paramstring
1116+
logging.debug("GET {}".format(url))
1117+
if assignable_users_link:
1118+
assignable_users_response = self.execute_get(url)
1119+
assignable_users = assignable_users_response.json()
1120+
1121+
# TODO: What to do if the user is already assigned to the project, and therefore
1122+
# does not appear in the list of 'assignable' user? Should we search the (assigned) user
1123+
# and re-apply the project-roles to the assignment?
1124+
1125+
user_url = self._find_user_url(assignable_users, user_name)
1126+
if user_url:
1127+
headers = self.get_headers()
1128+
1129+
# need project role urls to build the POST payload
1130+
project_roles_urls = self._project_role_urls(project_roles)
1131+
1132+
# The POST endpoint changes based on whether we found any project-roles to assign
1133+
# Also, due to what appears to be a defect, the Content-Type changes
1134+
if project_roles_urls:
1135+
url = user_url + "/roles"
1136+
# one dict per project role assignment
1137+
post_data = [{'role': r, 'scope': project_url} for r in project_roles_urls]
1138+
# I found I had to use this Content-Type (application/json resulted in 412)
1139+
# ref: https://jira.dc1.lan/browse/HUB-18417
1140+
headers['Content-Type'] = 'application/vnd.blackducksoftware.internal-1+json'
1141+
else:
1142+
url = project_url + "/users"
1143+
# Assigning a user with no project-roles
1144+
post_data = {"user": user_url}
1145+
headers['Content-Type'] = 'application/json'
1146+
1147+
response = requests.post(
1148+
url,
1149+
headers=headers,
1150+
data=json.dumps(post_data),
1151+
verify=not self.config['insecure'])
1152+
return response
1153+
else:
1154+
assignable_username = [u['name'] for u in assignable_users['items']]
1155+
logging.warning(
1156+
"The user {} was not found in the assignable user ({}) for this project {}. Is the user already assigned to this project?".format(
1157+
user_name, assignable_username, project_name))
1158+
else:
1159+
logging.warning("This project {} has no assignable users".format(project_name))
1160+
else:
1161+
logging.warning("Did not find a project by the name {}".format(project_name))
11041162

11051163
def assign_project_application_id(self, project_name, application_id, overwrite=False):
11061164
logging.debug("Assigning application_id {} to project_name {}, overwrite={}".format(

examples/assign_user_to_project.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
'''
2+
Created on April 26, 2019
3+
4+
@author: amacdonald
5+
6+
Assign a user to a project, providing the project-specific roles the user group should have (on the project)
7+
8+
Largely taken from assign_user_group_to_project, credit to gsnyder
9+
10+
'''
11+
12+
import argparse
13+
import logging
14+
import sys
15+
16+
from blackduck.HubRestApi import HubInstance
17+
18+
19+
project_roles = [
20+
"BOM Manager",
21+
"Policy Violation Reviewer",
22+
"Project Code Scanner",
23+
"Project Manager",
24+
"Security Manager",
25+
]
26+
27+
project_roles_str = ",".join(project_roles)
28+
29+
parser = argparse.ArgumentParser("Assign a user to a project along with a list of project roles (optional)")
30+
parser.add_argument("user", help="The name of a user to assign to the project")
31+
parser.add_argument("project", help="The name of the project you want to assign the user to")
32+
parser.add_argument(
33+
"--project_roles", help="A file with the project-specific roles ({}) that will be granted to the user, one per line".format(
34+
project_roles_str))
35+
parser.add_argument("--roles_list", nargs="+", help="The list of roles user should have.")
36+
37+
args = parser.parse_args()
38+
39+
logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s', stream=sys.stdout, level=logging.DEBUG)
40+
41+
hub = HubInstance()
42+
43+
if args.project_roles:
44+
project_roles_l = list()
45+
with open(args.project_roles) as f:
46+
project_roles_l = [role.strip() for role in f.readlines()]
47+
elif args.roles_list:
48+
project_roles_l = args.roles_list
49+
print('-----------------------')
50+
print(project_roles_l)
51+
for role in args.roles_list:
52+
role = project_roles_l
53+
else:
54+
project_roles_l = []
55+
56+
response = hub.assign_user_to_project(args.user, args.project, project_roles_l)
57+
58+
if response and response.status_code == 201:
59+
logging.info("Successfully assigned user {} to project {} with project-roles {}".format(
60+
args.user, args.project, project_roles_l))
61+
else:
62+
logging.warning("Failed to assign user {} to project {}".format(args.user, args.project))

examples/assign_users_from_CSV.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
'''
2+
Created on May 1, 2019
3+
4+
@author: amacdonald
5+
6+
Assign users to a project, providing the project-specific roles the user group should have (on the project) from a CSV file
7+
8+
9+
'''
10+
11+
import csv
12+
import logging
13+
import argparse
14+
import sys
15+
16+
from blackduck.HubRestApi import HubInstance
17+
18+
hub = HubInstance()
19+
20+
21+
project_roles = [
22+
"BOM Manager",
23+
"Policy Violation Reviewer",
24+
"Project Code Scanner",
25+
"Project Manager",
26+
"Security Manager",
27+
]
28+
29+
project_roles_str = ",".join(project_roles)
30+
31+
parser = argparse.ArgumentParser("Add users to project(s) with assigned roles (optional) from CSV file")
32+
parser.add_argument("CSV", help="Location of the CSV file to import")
33+
# "CSV File requires three columns titled 'User,' 'Project,' and 'Roles.'",
34+
# "In the 'Roles' column, separate the roles to assign with a ',' and no spaces")
35+
36+
args = parser.parse_args()
37+
38+
logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s', stream=sys.stdout, level=logging.DEBUG)
39+
40+
if args.CSV:
41+
with open(args.CSV, newline='') as csvfile:
42+
reader = csv.DictReader(csvfile)
43+
for row in reader:
44+
project = (row['Project'])
45+
user = (row['User'])
46+
roles = (row['Roles'])
47+
roles_l = []
48+
roles = roles.split(',')
49+
if roles:
50+
for x in range(len(roles)):
51+
project_roles_l = roles
52+
53+
else:
54+
project_roles_l = []
55+
56+
response = hub.assign_user_to_project(user, project, project_roles_l)
57+
58+
if response and response.status_code == 201:
59+
logging.info("Successfully assigned user {} to project {} with project-roles {}".format(user, project, project_roles_l))
60+
else:
61+
logging.warning("Failed to assign user {} to project {}".format(user, project))
62+
print('----------------------')

0 commit comments

Comments
 (0)