De Directory API of ADMIN api, geeft je heel wat mogelijkheden voor het beheer van gebruikers en groepen.
Onderaan bespreken we een aantal functies.
Het toevoegen van de AdminDirectory API in GAS is noodzakelijk alsook het bekomen van voldoende toegangsrechten(admin) om deze functies te kunnen gebuiken
Hiermee worden alle users in een organisatie afgevraagd en in een array geplaatst (array van objecten staffList)
Doordat het afvragen van users per pagina gaat, is een lus noodzakelijk om alle gebruikers te bekomen (maxResults 100).
Tevens willen we alle info bekomen om de fuctie export users binnen de admin console te kunnen nabootsen.
We kennen de waardes dan ook toe aan keys die dezelfde naam dragen als de export users functie (object user) gebruikt in zijn tabel headers.
Door de toekenning reeds te laten gebeuren in de map functie, is de uitkomst reeds in het correcte formaat en dien je nadien geen extra functie meer te voorzien voor de conversie van het formaat.
Het gebruik van "helperfuncties" zorgt ervoor dat de value waardes eveneens in de juiste formaten worden opgeslagen.
Deze helper functies worden binnenin de hoofdfunctie gedeclareerd, waardoor ze onder dezelfde namespace blijven.
function GetAllUsersInOrg() {
let page = '';
let pageToken = '';
let staffList = [];
do {
page = AdminDirectory.Users.list({
domain: 'myuba.be',
maxResults: 100,
pageToken: pageToken,
projection: 'full',
})
// Store only selected info for each user if users exist (last block has no users!)
if (page.users) {
let staffMember = page.users.map(user => {
return {
'First Name [Required]': getUserNames(user, "givenName"),
'Last Name [Required]': getUserNames(user, "familyName"),
'Email Address [Required]': user.primaryEmail,
'Password [Required]': '*****',
'Password Hash Function [UPLOAD ONLY]': '',
'Org Unit Path [Required]': user.orgUnitPath,
'New Primary Email [UPLOAD ONLY]': '',
'Recovery Email': user.recoveryEmail,
'Home Secondary Email': '',
'Work Secondary Email': '',
'Recovery Phone [MUST BE IN THE E.164 FORMAT]': user.recoveryPhone,
'Work Phone': getUserPhone(user, "work"),
'Home Phone': getUserPhone(user, "home"),
'Mobile Phone': getUserPhone(user, "mobile"),
'Work Address': getUserAddress(user, "work"),
'Home Address': getUserAddress(user, "home"),
'Employee ID': getExtIds(user, "organization"),
'Employee Type': getUserOrganizations(user, "description"),
'Employee Title': getUserOrganizations(user, "title"),
'Manager Email': getRelations(user, "manager"),
'Department': getUserOrganizations(user, "department"),
'Cost Center': getUserOrganizations(user, "costCenter"),
'Building ID': getLocations(user, "buildingId"),
'Floor Name': getLocations(user, "floorName"),
'Floor Section': getLocations(user, "floorSection"),
'Change Password at Next Sign-In': user.changePasswordAtNextLogin,
'New Status [UPLOAD ONLY]': '',
'Advanced Protection Program enrollment': user.isEnforcedIn2Sv
}
})
staffList = staffList.concat(staffMember)
}
pageToken = page.nextPageToken;
} while (pageToken)
return staffList;
Het name object kan zowel de naam van de gebruiker weergeven als family name maar ook als voornaam of beide.
'First Name [Required]': getUserNames(user, "givenName"),
'Last Name [Required]': getUserNames(user, "familyName"),
/**
* get names
* @param {object} user - user object for each user
* @param {string} item type
* @returns {string} Selected property's value
*
*/
function getUserNames(user, item) {
let retval = ""
if (user.hasOwnProperty('name')) {
if (user.name.hasOwnProperty("familyName") && item == "familyName") {
retval = user.name.familyName;
} else if (user.name.hasOwnProperty("givenName") && item == "givenName") {
retval = user.name.givenName;
}
} else {
retval = "";
} return retval;
}
Een gebruiker kan meerdere telefoonnummers hebben, die allemaal dienen bewaard te worden.
In het oorspronkelijk object worden de verschillende nummers gedefinieerd met een ander type.
'Work Phone': getUserPhone(user, "work"),
'Home Phone': getUserPhone(user, "home"),
'Mobile Phone': getUserPhone(user, "mobile"),
/**
* get phone number
* @param {object} user - user object for each user
* @param {string} item type
* @returns {string} Selected property's value
*
*/
function getUserPhone(user, item) {
let retval = ""
if (user.hasOwnProperty('phones')) {
for (i = 0; i < user.phones.length; i++) {
if (user.phones[i].type == item) {
retval = user.phones[i].value;
break
}
}
} else {
retval = "";
} return retval;
}
Er bestaan verschillende adressen, de functie wordt gestopt indien de gevraagde adreswaarde wordt gevonden, een aandere aanpak van een if/else loop, door gebruik te maken van een break.
Vermits het adres best wordt aangeboden in een formaat wat door google maps kan gebruikt worden, wordt er gebruik gemaakt van de formatted property.
'Work Address': getUserAddress(user, "work"),
'Home Address': getUserAddress(user, "home"),
/**
* get address number
* @param {object} user - user object for each user
* @param {string} item type
* @returns {string} Selected property's value
*
*/
function getUserAddress(user, item) {
let retval = ""
if (user.hasOwnProperty('addresses')) {
for (i = 0; i < user.addresses.length; i++) {
if (user.addresses[i].type == item) {
retval = user.addresses[i].formatted;
break
}
}
}
else {
retval = "";
} return retval
}
Binnen deze radioamateur toepassing maken we gebruik van de Employee velden voor de callsign, provicie en club weer te geven.
De Employee ID bevat de call sign en wordt bewaard in de organization property van het directory object.
'Employee ID': getExtIds(user, "organization"),
/**
* get ExtIds
* @param {object} user - user object for each user
* @param {string} item type
* @returns {string} Selected property's value
*
*/
function getExtIds(user, item) {
let retval = ""
if (user.hasOwnProperty('externalIds')) {
for (i = 0; i < user.externalIds.length; i++) {
if (user.externalIds[i].type == item) {
retval = user.externalIds[i].value;
break
}
}
} else {
retval = "";
} return retval
}
Binnen het sub object "Organisations" vinden we verschillende velden terug die wij gebruiken voor bepaalde informatie, zoals titel, costCenter, customType,description,department.
Binnen de RA werlend hebben we gekozen om volgende informatie hieraan toe te kennen.
Employee Type: Taal
Employee Title: MEMBER|titel binnen organisatie
Department: Provincie
Cost Center: 2 letter provincie code (administratie)
'Employee Type': getUserOrganizations(user, "description"),
'Employee Title': getUserOrganizations(user, "title"),
'Department': getUserOrganizations(user, "department"),
'Cost Center': getUserOrganizations(user, "costCenter"),
/**
* get Organisation info
* @param {object} user - user object for each user
* @param {string} item type
* @returns {string} Selected property's value
*
*/
function getUserOrganizations(user, item) {
let retval = ""
if (user.hasOwnProperty('organizations')) {
for (i = 0; i < user.organizations.length; i++) {
if (user.organizations[i].primary == true) {
if (user.organizations[i].hasOwnProperty("title") && item == "title") {
retval = user.organizations[i].title;
break
} else if (user.organizations[i].hasOwnProperty("costCenter") && item == "costCenter") {
retval = user.organizations[i].costCenter;
break
} else if (user.organizations[i].hasOwnProperty("customType") && item == "customType") {
retval = user.organizations[i].customType;
break
} else if (user.organizations[i].hasOwnProperty("description") && item == "description") {
retval = user.organizations[i].description;
break
} else if (user.organizations[i].hasOwnProperty("department") && item == "department") {
retval = user.organizations[i].department;
break
}
}
}
} else {
retval = ""
} return retval
}
Uit de relations halen we het manager email adres.
Dit is het adres van de verantwoordelijke, of dit nu de B-EARS verantwoordelijken zijn of deze van een comissie.
Manager Email: email van de verantwoordelijke
'Manager Email': getRelations(user, "manager"),
/**
* get relations
* @param {object} user - user object for each user
* @param {string} item type
* @returns {string} Selected property's value
*
*/
function getRelations(user, item) {
let retval = ""
if (user.hasOwnProperty('relations')) {
for (i = 0; i < user.relations.length; i++) {
if (user.relations[i].type == item) {
retval = user.relations[i].value;
}
}
} else {
retval = "";
} return retval
}
Dit "locations" object bevat verschillende informatie bronnen, die gebruikt kunnen worden in kalenders voor het plannen van vergaderruimtes etc.
Wij gebruiken dit om de club aan te geven, de ruimte en uitrusting.
floorname: vloernaam of naam van het gebouw
floorSection: lokaalnummer
BuildingID: clubnaam in 3 letter code
area en length worden momenteel niet gebruikt.
floorname: vloernaam of naam van het gebouw
floorSection: lokaalnummer
BuildingID: clubnaam in 3 letter code
area en length worden momenteel niet gebruikt.
'Building ID': getLocations(user, "buildingId"),
'Floor Name': getLocations(user, "floorName"),
'Floor Section': getLocations(user, "floorSection"),
/**
* get locations
* @param {object} user - user object for each user
* @param {string} item type
* @returns {string} Selected property's value
*
*/
function getLocations(user, item) {
let retval = ""
if (user.hasOwnProperty('locations')) {
for (i = 0; i < user.locations.length; i++) {
if (user.locations[i].hasOwnProperty("floorName") && item == "floorName") {
retval = user.locations[i].floorName;
} else if (user.locations[i].hasOwnProperty("type") && item == "type") {
retval = user.locations[i].type;
} else if (user.locations[i].hasOwnProperty("floorSection") && item == "floorSection") {
retval = user.locations[i].floorSection;
} else if (user.locations[i].hasOwnProperty("buildingID") && item == "buildingID") {
retval = user.locations[i].buildingID;
} else if (user.locations[i].hasOwnProperty("area") && item == "area") {
retval = user.locations[i].area;
} else if (user.locations[i].hasOwnProperty("length") && item == "length") {
retval = user.locations[i].length;
}
}
} else {
retval = ""
} return retval
}
Deze helperfunctie wordt hier niet gebruikt, maar kan gebruikt worden in situaties waar meer dan één organisatie onder hetzelfde domain wordt behandelt en een gebruiker kan behoren tot meerdere organisaties en sub organisaties.
Hierdoor kan je de structuur van één organisatie isoleren van de rest (flatmap)
/**
* Get users' organisation data if > 1 org in Workspace.
* @param {object} user - user object for each user.
* @param {string} item - property (Schema) to search.
* @returns {string} Selected property's value.
*/
function getUserOrgItem(user, item) {
let retval = ""
if (user.hasOwnProperty('organizations')) {
const primaryOrg = user.organizations.flatMap(org => (org.primary == true) ? org : "")[0]
retval = primaryOrg.hasOwnProperty(item) ? primaryOrg.title : "";
} else {
retval = "";
}
} return retval
}