Project Admin
Some issue attributes are related to project members, we will use ACC Admin API to get the information. This sample demos how to fetch project users.
ACC Admin SDK
First, let's include the ACC Admin SDK:
- Node.js & VSCode
- .NET & VSCode
- .NET & VS2022
Add the @aps_sdk/construction-account-admin
library, and also create an instance of
SDK client of adminClient
at the beginning of services/aps.js
file:
const { SdkManagerBuilder } = require('@aps_sdk/autodesk-sdkmanager');
const { AuthenticationClient, Scopes, ResponseType } = require('@aps_sdk/authentication');
const { DataManagementClient } = require('@aps_sdk/data-management');
const { IssueClient } = require('@aps_sdk/construction-issues');
const { AdminClient } = require('@aps_sdk/construction-account-admin');
const { APS_CLIENT_ID, APS_CLIENT_SECRET, APS_CALLBACK_URL, INTERNAL_TOKEN_SCOPES, PUBLIC_TOKEN_SCOPES } = require('../config.js');
const service = module.exports = {};
const sdk = SdkManagerBuilder.create().build();
const authenticationClient = new AuthenticationClient(sdk);
const dataManagementClient = new DataManagementClient(sdk);
const issueClient = new IssueClient(sdk);
const adminClient = new AdminClient(sdk);
Project users
Next, we will add helper function to extract project users. Append the following code to the end of the services/aps.js
file. Similaly, this API also works with pagination.
The code will extract all users.
// ACC Admin APIs
//get project users list
service.getProjectUsers = async (projectId, token) => {
let allUsers = [];
let offset = 0;
let totalResults = 0;
do{
const resp = await adminClient.getProjectUsers( projectId, {accessToken:token,offset:offset});
allUsers = allUsers.concat(resp.results);
offset += resp.pagination.limit;
totalResults = resp.pagination.totalResults;
}while (offset < totalResults)
return allUsers;
};
Create APS.Admin.cs
file under Models
folder, add following content.
using System.Collections.Generic;
using System.Threading.Tasks;
using Autodesk.Construction.AccountAdmin;
using Autodesk.Construction.AccountAdmin.Model;
public partial class APS
{
// ACC Issue API, only tells the user id with related fields.
//to fetch the information of the user, call the endpoint below and map with the user id.
public async Task<IEnumerable<dynamic>> GetProjectUsersACC(string projectId, Tokens tokens)
{
AdminClient adminClient = new AdminClient(_SDKManager);
var allUsers = new List<ProjectUser>();
var offset = 0;
var totalResult = 0;
do
{
var users = await adminClient.GetProjectUsersAsync(projectId, accessToken: tokens.InternalToken, offset: offset);
allUsers.AddRange(users.Results);
offset += (int)users.Pagination.Limit;
totalResult = (int)users.Pagination.TotalResults;
} while (offset < totalResult);
return allUsers;
}
}
Create APS.Admin.cs
file under Models
folder, add following content.
using System.Collections.Generic;
using System.Threading.Tasks;
using Autodesk.Construction.AccountAdmin;
using Autodesk.Construction.AccountAdmin.Model;
public partial class APS
{
// ACC Issue API, only tells the user id with related fields.
//to fetch the information of the user, call the endpoint below and map with the user id.
public async Task<IEnumerable<dynamic>> GetProjectUsersACC(string projectId, Tokens tokens)
{
AdminClient adminClient = new AdminClient(_SDKManager);
var allUsers = new List<ProjectUser>();
var offset = 0;
var totalResult = 0;
do
{
var users = await adminClient.GetProjectUsersAsync(projectId, accessToken: tokens.InternalToken, offset: offset);
allUsers.AddRange(users.Results);
offset += (int)users.Pagination.Limit;
totalResult = (int)users.Pagination.TotalResults;
} while (offset < totalResult);
return allUsers;
}
}
Server endpoints
Next, let's expose the routings to get project users to the client-side code through another set of endpoints.
- Node.js & VSCode
- .NET & VSCode
- .NET & VS2022
Create a admin.js
file under the routes
subfolder with the following content:
const express = require('express');
var bodyParser = require('body-parser');
const { authRefreshMiddleware,
getProjectUsers
} = require('../services/aps.js');
let router = express.Router();
router.use(authRefreshMiddleware);
//get project users list
router.get('/api/admin/projectUsers', async function (req, res, next) {
try {
const users = await getProjectUsers(req.query.projectId, req.internalOAuthToken.access_token);
res.json(users);
} catch (err) {
next(err);
}
});
module.exports = router;
And mount the router to our server application by modifying server.js
:
const express = require('express');
const session = require('cookie-session');
const { PORT, SERVER_SESSION_SECRET } = require('./config.js');
let app = express();
app.use(express.static('wwwroot'));
app.use(session({ secret: SERVER_SESSION_SECRET, maxAge: 24 * 60 * 60 * 1000 }));
app.use(require('./routes/auth.js'));
app.use(require('./routes/hubs.js'));
app.use(require('./routes/issues.js'));
app.use(require('./routes/admin.js'));
app.listen(PORT, () => console.log(`Server listening on port ${PORT}...`));
Create a AdminController.cs
file under the Controllers
subfolder with the following content:
using System.Threading.Tasks;
using aps_acc_issues_dotnet.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
[ApiController]
[Route("api/[controller]")]
public class AdminController : ControllerBase
{
private readonly ILogger<AdminController> _logger;
private readonly APS _aps;
public AdminController(ILogger<AdminController> logger, APS aps)
{
_logger = logger;
_aps = aps;
}
[HttpGet("projectUsers")]
public async Task<ActionResult<string>> ListProjectUsers(string projectId)
{
var tokens = await AuthController.PrepareTokens(Request, Response, _aps);
if (tokens == null)
{
return Unauthorized();
}
var projects = await _aps.GetProjectUsersACC(Request.Query["projectId"], tokens);
return JsonConvert.SerializeObject(projects);
}
}
Create a AdminController.cs
file under the Controllers
subfolder with the following content:
using System.Threading.Tasks;
using aps_acc_issues_dotnet.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
[ApiController]
[Route("api/[controller]")]
public class AdminController : ControllerBase
{
private readonly ILogger<AdminController> _logger;
private readonly APS _aps;
public AdminController(ILogger<AdminController> logger, APS aps)
{
_logger = logger;
_aps = aps;
}
[HttpGet("projectUsers")]
public async Task<ActionResult<string>> ListProjectUsers(string projectId)
{
var tokens = await AuthController.PrepareTokens(Request, Response, _aps);
if (tokens == null)
{
return Unauthorized();
}
var projects = await _aps.GetProjectUsersACC(Request.Query["projectId"], tokens);
return JsonConvert.SerializeObject(projects);
}
}
Try it out
And that's it for the server side. Time to try it out!
- Use same project ID in previous step (remove b.) and try to call the endpoint: http://localhost:8080/api/admin/projectUsers?projectId={your-project-id}, the server application should respond with a JSON list of all the users from this project.
Admin API has not exposed endpoint to get project roles. The workaround is to use Data Connector API.
Admin API exposes endpoint to get project companies, but it supports App context authentication only. While this tutorial sample builds the skeleton of user context authentication. if you want to fetch, you could add code to get 2-legged token to call this API.
Or by Data Connector APIto get list of roles, companies and even users.