Important Update: Community URLs redirect issues are partially resolved. Learn More. .

cancel
Showing results for 
Search instead for 
Did you mean: 

Role Creation using RESTful requests.

BradleyHanna
Contributor III

I have a need to create users, groups, roles in Archer programmatically using the API.  Role Creation with permissions presented the greatest challenge because the AccessRoleTasks are added based on a TaskId that isn't easily accessed.

 

I have two custom types defined in C# that match the metadata accepted by the Archer API: Role and AccessRoleTask.  The data stored in their members is serialized to Json for the request body.  The general role definition is easy.  The AccessRoleTasks are more difficult.

 

So, if you are interested in creating Roles with permissions using the API, I hope this will help.  Mostly, I am open to suggestions for a better design that requires less computations and only one user session.

 

Create the Role object with the required general information:

/**** Inside Main ****/
Role testRole = new Role
{
Name = "Test Api Administrator",
Description = "This role was created by an API request.",
Membership = new RoleMembership
{
UserIds = new List<string>(){"208"},
GroupIds = new List<string>(){"216"}
}

};‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Create the AccessRoleTask objects with the permissions set using TaskName as a key (human readable):

/**** Still inside Main ****/

/**** I'll set permissions on only two tasks for the test ****/
AccessRoleTask TestTask1 = new AccessRoleTask("Archer API Templates: Content Record", true, true, true, true);
AccessRoleTask TestTask2 = new AccessRoleTask("Archer API Templates: Data Import", true, true, true, true);

/**** AccessRoleTask constructor for reference ****/
public AccessRoleTask(string taskName, bool hasCreate, bool hasRead, bool hasUpdate, bool hasDelete)
{
TaskId = string.Empty; // We need TaskId...
TaskName = taskName;
HasCreate = hasCreate;
HasRead = hasRead;
HasUpdate = hasUpdate;
HasDelete = hasDelete;
}

/**** We want to set multiple permissions so store them in a List ****/
List<AccessRoleTask> accessRoleTasks = new List<AccessRoleTask>();
accessRoleTasks.Add(TestTask1);
accessRoleTasks.Add(TestTask2);‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

We have to correlate AccessRoleTask, TaskIds to TaskNames to POST this to Archer.  So, I get the AccessRoleTasks using a "psuedo" GET to "platformapi/core/system/role/permission/1".  As far as I can tell, this request requires System Administrator user permissions.

/**** Still in Main ****/

// GetRolePermissionsLookupTable performs the GET and deserializes the data to a Hashtable
Hashtable permissionsLookupTable = ArcherRestClient.GetRolePermissionsLookupTable(archerSession).Result;

/**** Not in Main
GetRolePermissionsLookupTable definition ****/

public static async Task<Hashtable> GetRolePermissionsLookupTable(ArcherSession session)
{
string relativePath = "api/core/system/role/permission/1";
JToken responseObject = new JArray();
JToken requestedObject = new JObject();
string keyTaskName = string.Empty;
string valueTaskId = string.Empty;

Hashtable result = new Hashtable();

string bodyData =
@"{" +
" 'Value':'?$select=TaskName,TaskId&$orderby=TaskName'" +
"}";

try
{
responseObject = await ArcherRestClient.GetRequestAsync(session, relativePath, bodyData);
}
catch (Exception exception)
{
throw exception;
}

try
{
foreach (var item in responseObject)
{
requestedObject = item["RequestedObject"];
keyTaskName = requestedObject["TaskName"].ToString();
if (!result.ContainsKey(keyTaskName))
{
valueTaskId = requestedObject["TaskId"].ToString();
result.Add(keyTaskName, valueTaskId);
}
else
{
continue;
}
}
}
...
return result;
} // End GetRolePermissionsLookupTable‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

When we run this, we get 3520 unique representations of the AccessRoleTask with TableName for the key and TableId for the value.

Finally, we correlate the TableName values in our new Role's AccessRoleTask list to the matching TaskId in the Hashtable and add the TaskIds to the AccessRoleTasks.

 

/**** In Main ****/
testRole.AddAccessRoleTasks(ref accessRoleTasks, permissionsLookupTable);

/**** AddAccessRoleTasks Definition ****/
public void AddAccessRoleTasks(ref List<AccessRoleTask> accessRoleTasks, Hashtable taskIdLookupTable)
{
string taskId = string.Empty;

foreach (var task in accessRoleTasks)
{
if (taskIdLookupTable.ContainsKey(task.TaskName))
{
taskId = taskIdLookupTable[task.TaskName].ToString();
task.SetTaskId(taskId);
AccessRoleTasks.Add(task);
}
else
{
var message = "The provided TaskName," + task.TaskName + ", was not found.";
throw new InvalidOperationException(message);
}
}

} // End AddAccessRoleTasks

The Role object instantiation is now complete.  The application then serializes the Role, sends the request, and the Role is added with the correct permissions.

 

I do not want to use a System Administrator user to handle all Access Control requests sent to the API.  So, GetRolePermissionsLookupTable() will need to login another Archer Session with a SysAdmin user to obtain the "role/permission" data, then an Access Control user will do all the other operations.

 

I there a way to grab all "role/permission" without using the full SysAdmin role?

Is there a way to lookup task Ids without pulling all AccessControlTasks?

 

Note: We are not using RSA.Archer.Api.Client libraries to do this work because it is not fully supported.  One vote for your .net library being fully supported.

0 REPLIES 0