diff --git a/frontend/dist/index.html b/frontend/dist/index.html index 46335453..5e986325 100644 --- a/frontend/dist/index.html +++ b/frontend/dist/index.html @@ -9,6 +9,7 @@

ShotGrid Sync

+

From this page you can Import projects from ShotGrid or trigger a project Sync!
In order for the Synchronization to work, a ShotgridProcessor service must be running, this page will only create events (with the topic: "shotgrid.event.project.sync") for the processor to handle. diff --git a/frontend/dist/shotgrid-addon.js b/frontend/dist/shotgrid-addon.js index 6ce38f26..d8eb3638 100644 --- a/frontend/dist/shotgrid-addon.js +++ b/frontend/dist/shotgrid-addon.js @@ -122,6 +122,174 @@ const populateTable = async () => { } +const syncUsers = async () => { + /* Get all the Users from AYON and Shotgrid, then populate the table with their info + and a button to Synchronize if they pass the requirements */ + ayonUsers = await getAyonUsers(); + sgUsers = await getShotgridUsers(); + + sgUsers.forEach((sg_user) => { + let already_exists = false + ayonUsers.forEach((user) => { + if (sg_user.login == user.name) { + already_exists = true + } + }) + if (!already_exists) { + createNewUserInAyon( + sg_user.id ,sg_user.login, sg_user.email, sg_user.name) + } + }) +} + + +const getShotgridUsers = async () => { + /* Query Shotgrid for all active users. */ + const sgBaseUrl = `${addonSettings.shotgrid_server.replace(/\/+$/, '')}/api/v1` + sgAuthToken = await axios + .post(`${sgBaseUrl}/auth/access_token`, { + client_id: `${addonSettings.service_settings.script_name}`, + client_secret: addonSettings.shotgrid_api_key, + grant_type: "client_credentials", + }, { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Accept': 'application/json' + } + }) + .then((result) => result.data.access_token) + .catch((error) => { + console.log("Unable to Acquire the Shotgrid Authorization Token!") + console.log(error) + }); + + sgUsers = await axios + .get(`${sgBaseUrl}/entity/human_users?filter[sg_status_list]=act&fields=login,name,email`, { + headers: { + 'Authorization': `Bearer ${sgAuthToken}`, + 'Accept': 'application/json' + } + }) + .then((result) => result.data.data) + .catch((error) => { + console.log("Unable to Fetch Shotgrid Users!") + console.log(error) + }); + + /* Do some extra clean up on the users returned. */ + var sgUsersConformed = [] + users_to_ignore = ["dummy", "root", "support"] + if (sgUsers) { + sgUsers.forEach((sg_user) => { + if ( + !users_to_ignore.some(item => sg_user.attributes.email.includes(item)) + ) { + sgUsersConformed.push({ + "id": sg_user.id, + "login": sg_user.attributes.login, + "name": sg_user.attributes.name, + "email": sg_user.attributes.email, + }) + } + }); + } + return sgUsersConformed; +} + + +const getAyonUsers = async () => { + /* Query AYON for all existing users. */ + ayonUsers = await axios({ + url: '/graphql', + headers: {"Authorization": `Bearer ${accessToken}`}, + method: 'post', + data: { + query: ` + query ActiveUsers { + users { + edges { + node { + attrib { + email + fullName + } + active + name + } + } + } + } + ` + } + }).then((result) => result.data.data.users.edges); + + var ayonUsersConformed = [] + + if (ayonUsers) { + ayonUsers.forEach((user) => { + ayonUsersConformed.push({ + "name": user.node.name, + "email": user.node.attrib.email, + "fullName": user.node.attrib.fullName, + }) + }) + } + return ayonUsersConformed +} + +function validateLogin(login) { + // First sanitize by replacing @ with underscore + let new_login = login.replace(/@/g, '_'); + + // Ensure valid pattern + const validPattern = /^[a-zA-Z0-9][a-zA-Z0-9_\.\-]*[a-zA-Z0-9]$/; + + if (!validPattern.test(new_login)) { + // If invalid, create valid string by: + // 1. Remove invalid chars + // 2. Ensure starts/ends with alphanumeric + let _new_login = new_login.replace(/[^a-zA-Z0-9_\.\-]/g, '') + .replace(/^[^a-zA-Z0-9]+/, '') + .replace(/[^a-zA-Z0-9]+$/, ''); + + // If result too short, append 'user' + if (_new_login.length < 2) { + new_login = 'user' + _new_login; + } + } + + return new_login; +} + +const createNewUserInAyon = async (id, login, email, name) => { + /* Spawn an AYON Event of topic "shotgrid.event" to synchcronize a project + from Shotgrid into AYON. */ + call_result_paragraph = document.getElementById("call-result"); + + // make sure no @ and . or - is in login string + let fixed_login = validateLogin(login); + + response = await ayonAPI + .put("/api/users/" + fixed_login, { + "active": true, + "attrib": { + "fullName": name, + "email": email, + }, + "data": { + "sg_user_id": id + }, + "password": login, + }) + .then((result) => result) + .catch((error) => { + console.log("Unable to create user in AYON!") + console.log(error) + call_result_paragraph.innerHTML = `Unable to create user in AYON! ${error}` + }); +} + + const getShotgridProjects = async () => { /* Query Shotgrid for all existing projects. */ const sgBaseUrl = `${addonSettings.shotgrid_server.replace(/\/+$/, '')}/api/v1` @@ -159,7 +327,7 @@ const getShotgridProjects = async () => { if (sgProjects) { sgProjects.forEach((project) => { - sgProjectsConformed.push({ + sgProjectsConformed.push({ "name": project.attributes.name, "code": project.attributes[`${addonSettings.shotgrid_project_code_field}`], "shotgridId": project.id,