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 @@
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,