Inspiration

I was inspired by an idea in the BIM 360 Ideas forum to make a tool for BIM 360 Docs project list export.

What it does

With the BIM 360 Docs Project List Export app, you can download your projects in Excel and CSV format, then view and manipulate them in Excel to answer whatever questions you have.

How I built it

I used Heroku with a nodejs express server. I used a template from the Forge Partner Development team at Autodesk, then modified it heavily for my needs. The template was very helpful for getting started. On the frontend, I used sheetjs, Blob.js, FileSaver.js, jquery, and bootstrap.

Challenges I ran into

It was interesting to allow Excel and CSV download from frontend JS. I hadn't done that before. Integrating with sheetjs, Blob.js, and FileSaver.js allowed this.

I also needed to use the two-legged oAuth API in order to access /hq/v1/accounts/:account_id/projects, but I also needed to know which account_id to use for the viewing user and I wanted to make sure that the viewing user had the correct permissions to view this data from the given account, as it would be easy to mistakenly have a security vulnerability by not checking the viewing user's permissions. To make this safe, I use both three-legged and two-legged oAuth, first getting three-legged access for the current user to check their user profile, then accessing that account view two-legged oAuth and making sure the user's oid shows up on the account's user list with a role of account_admin. Here's a snippet:

function getAllProjects(accountId, oauth2client, credentials) {
  return forgeSDK.ApiClient.instance.callApi(
    '/hq/v1/accounts/{account_id}/projects', 'GET',
    { 'account_id': accountId },
    {}, {}, {}, null, ['application/json'], ['application/json'], null, oauth2client, credentials
  );
};

function getUsers(accountId, oauth2client, credentials) {
  return forgeSDK.ApiClient.instance.callApi(
    '/hq/v1/accounts/{account_id}/users', 'GET',
    { 'account_id': accountId },
    {}, {}, {}, null, ['application/json'], ['application/json'], null, oauth2client, credentials
  );
};

function getProjects(hubId, tokenSession, res) {
  var accountId = hubId.replace(/^b\./, '');

  getUsers(hubId, tokenSession.getTwoLeggedOAuth(), tokenSession.getTwoLeggedCredentials()).then(function (users) {
    var profileApi = new forgeSDK.UserProfileApi();
    profileApi.getUserProfile(tokenSession.getInternalOAuth(), tokenSession.getInternalCredentials()).then(function(profile) {
      var userInAccount = false;

      users.body.forEach(function(user) {
        if (user.uid == profile.body.userId && user.role == 'account_admin' && user.account_id == accountId) {
          userInAccount = true;
          console.log("Verified that " + user.email + " is on account " + accountId);
        }
      });

      if (userInAccount) {
        getAllProjects(hubId, tokenSession.getTwoLeggedOAuth(), tokenSession.getTwoLeggedCredentials()).then(function (projects) {
          // Send the project list to the frontend.
          res.json(projects.body);
        })
        .catch(function (error) {
          res.status(500).end();
        });        
      } else {
        ...

Built With

Share this project:
×

Updates