Adding domain user to Organisation Unit using Google Apps script - provisioning

I'm trying to add a user (newly created) to a specific org unit in my Google Apps domain, but I can't seem to find any documentation or examples on this. Is this even possible? Perhaps through the use of plain REST calls?
My code so far to create a user:
var user = UserManager.createUser(userName, firstName, lastName, "welcome").setChangePasswordAtNextLogin(true);
Now I want to attach the user to a specific org unit, and make it a member of certain groups (but that's another question I'm diving into).
Any help will greatly be appreciated!
Regards,
Kees.

The UserManager service doesn't support org units, but you can build the request manually.
The following Apps Script code adds an user to an OU. The parameters are the customerId, the email address of the user to add to the org unit and the org unit path:
function addUserToOU(customerId, email, ou) {
var oauthConfig = UrlFetchApp.addOAuthService("google");
var scope = "https://apps-apis.google.com/a/feeds/policies/";
oauthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oauthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oauthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oauthConfig.setConsumerKey("anonymous");
oauthConfig.setConsumerSecret("anonymous");
var body = "<?xml version=\"1.0\" encoding=\"utf-8\"?><atom:entry xmlns:atom=\"http://www.w3.org/2005/Atom\" xmlns:apps=\"http://schemas.google.com/apps/2006\"><apps:property name=\"orgUnitPath\" value=\"" + ou + "\" /></atom:entry>";
var requestData = {
"method": "put",
"contentType": "application/atom+xml",
"oAuthServiceName": "google",
"oAuthUseToken": "always",
"payload": body
};
var url = "https://apps-apis.google.com/a/feeds/orguser/2.0/" + customerId + "/" + email;
var result = UrlFetchApp.fetch(url, requestData);
Logger.log(result.getContentText());
}

I think that this task is quite easy nowadays:
This sinple code should work:
var emailAddress = 'myuser#mydomain.com';
var user = AdminDirectory.Users.get(emailAddress);
var orgunittomove='myorgunit' //you can set the whole path;
user.orgUnitPath = orgunittomove;
AdminDirectory.Users.update(user, emailAddress);

In the same way that the last answer, you can add the organization unit on the user object when you create the user. In the user object you have to set the orgUnitPath property.
var user = {
primaryEmail: "aperetz#austriajohn.edu",
orgUnitPath:"/Students",
name: {
givenName: "Albert",
familyName: "Peretz"
},
password: "XWYlkf"
};
userGsuite = AdminDirectory.Users.insert(user);

Related

Automatically map a Contact to an Account

I want to add a field to Accounts which shows the email domain for that account e.g. #BT.com. I then have a spreadsheet which lists all the Accounts and their email domains. What I want to do is when a new Contact is added to Dynamics that it checks the spreadsheet for the same email domain (obviously without the contacts name in the email) and then assigned the Contact to the Account linked to that domain. Any idea how I would do this. Thanks
Probably best chance would be to develop CRM plugin. Register your plugin to be invoked when on after contact is created or updated (so called post-event phase). And in your plugin update the parentaccountid property of the contact entity to point to account of your choice.
Code-wise it goes something like (disclaimer: not tested):
// IPluginExecutionContext context = null;
// IOrganizationService organizationService = null;
var contact = (Entity)context.InputParameters["Target"];
var email = organizationService.Retrieve("contact", contact.Id, new ColumnSet("emailaddress1")).GetAttributeValue<string>("emailaddress1");
string host;
try
{
var address = new MailAddress(email);
host = address.Host;
}
catch
{
return;
}
var query = new QueryExpression("account");
query.TopCount = 1;
// or whatever the name of email domain field on account is
query.Criteria.AddCondition("emailaddress1", ConditionOperator.Contains, "#" + host);
var entities = organizationService.RetrieveMultiple(query).Entities;
if (entities.Count != 0)
{
contact["parentaccountid"] = entities[0].ToEntityReference();
}
organizationService.Update(contact);
I took Ondrej's code and cleaned it up a bit, re-factored for pre-operation. I also updated the logic to only match active account records and moved the query inside the try/catch. I am unfamiliar with the MailAddress object, I personally would just use string mapping logic.
var target = (Entity)context.InputParameters["Target"];
try
{
string host = new MailAddress(target.emailaddress1).Host;
var query = new QueryExpression("account");
query.TopCount = 1;
// or whatever the name of email domain field on account is
query.Criteria.AddCondition("emailaddress1", ConditionOperator.Contains, "#" + host);
query.Criteria.AddCondition("statecode", ConditionOperator.Equals, 0); //Active records only
var entities = organizationService.RetrieveMultiple(query).Entities;
if (entities.Count != 0)
{
target["parentaccountid"] = entities[0].ToEntityReference();
}
}
catch
{
//Log error
}

Parse Cloud Right Query to retrieve Friendslist and not (like Instagram)

I have the class "Users" the default of Parse Dashboad. I have also the class "Friends", where I store the friendships between users like this:
There are two columns, "toUser" and "fromUser", which are showing who of the two users sent the friend request. These two columns are Pointers(Pointer<_User>) to the Users Class.
My concept is to retrieve two lists:
1. Friendlist for the logged in user
2. Userlist of users (who are not friends with the logged in user)
What would be the appropriate queries for that?
The first one logically should not scan all the class Users because it may slow down the perfomance of the app which is using Ionic 3 and Angular 4
Thank you
you don't need another class to do so all you need is a relation column in the default user class
to add new friend you just need the following code
var friendtoadd
//this is the friend object from parse user class you want to add you can get it by anyway you want
var currentUser = Parse.User.current();
var relation = currentUser.relation("friends");
relation.add(friendtoadd)
currentUser.save();
to retrieve array of friends of logged in user you can use the following code
var currentUser = Parse.User.current();
var friendRelation = currentUser.relation('friends');
var env = this
friendRelation.query().find({
success: function(users) {
for (var i = 0; i< users.length; i++) {
var object = users[i];
env.friends.push(object)
console.log(env.friends)
}
}
});
// you should define friends = []; in the class
if I understood your question right you want to find the friend requests you sent, or the ones you received. because I don't see where you made a relation between the user and his friends.
this is the code if you want to do this using cloud code:
First I validated the parameters of the friendRequest being saved :
Parse.Cloud.beforeSave("Friends", function(request, response){
var friendRequest = request.object;
if (!friendRequest.has("toUser") || !friendRequest.has("fromUser")) {
response.error("Invalid parameters");
return;
}
response.success();
});
then I created two cloud functions, one for retrieving the sentRequests:
Parse.Cloud.define("getSentRequests", function(request, response){
var query = new Parse.Query("Friends");
query.equalTo("fromUser", request.user);
if (!request.master) {
query.find({ sessionToken: request.user.getSessionToken() }).then(function(friends){
response.success(friends);
});
}else{
query.find({useMasterKey:true}).then(function(friends){
response.success(friends);
});
}
});
and you can call this either from a logged in user or using the masterKey if you want, and the other query is for the recievedRequests:
Parse.Cloud.define("getRecievedRequests", function(request, response){
var query = new Parse.Query("Friends");
query.equalTo("toUser", request.user);
if (!request.master) {
query.find({ sessionToken: request.user.getSessionToken() }).then(function(users){
response.success(users);
});
}else{
query.find({useMasterKey:true}).then(function(users){
response.success(users);
});
}
});

How do you update objects in a Parse.com database using Xamarin?

I have an online Parse.com database and I can create objects and query them but not update. In the Xamarin section of the Parse.com documentation it only tells you how to update an object directly after you've created it which I don't want to do. I tried adapting what the documentation says for other platforms but it hasn't worked, I have also tried querying the database and entering the new field values directly after that but it treats them as separate functions. Does anyone have any help?
Parse.com documentation:
// Create the object.
var gameScore = new ParseObject("GameScore")
{
{ "score", 1337 },
{ "playerName", "Sean Plott" },
{ "cheatMode", false },
{ "skills", new List<string> { "pwnage", "flying" } },
};
await gameScore.SaveAsync();
// Now let's update it with some new data. In this case, only cheatMode
// and score will get sent to the cloud. playerName hasn't changed.
gameScore["cheatMode"] = true;
gameScore["score"] = 1338;
await gameScore.SaveAsync();
What I tried most recently:
ParseQuery<ParseObject> query = ParseObject.GetQuery("cust_tbl");
IEnumerable<ParseObject> customers = await query.FindAsync();
customers["user"] = admin;
record["score"] = 1338;
await record;
In your example, you are getting an list (IEnumerable) of objects instead of single object. Instead, try something like this:
ParseQuery<ParseObject> query = ParseObject.GetQuery("cust_tbl");
// you need to keep track of the ObjectID assigned when you first saved,
// otherwise you will have to query by some unique field like email or username
ParseObject customer = await query.GetAsync(objectId);
customer["user"] = admin;
customer["score"] = 1338;
await customer.SaveAsync();

Creating new users without resetting current user session

In my Parse web app, I have a user management page that is accessible to administrators. This page allows admins to create new user accounts.
To create the accounts, I use Parse.User.signUp().
It works great, but it has the nasty side effect of resetting the current user session, which logs out the admin who created the new user account.
This is actually the documented behaviour of User.signUp():
This will create a new Parse.User on the server, and also persist the session in localStorage so that you can access the user using #current.
But I want to create new users without changing the current user. How do I do this?
Before creating the new user account with User.signUp, save the current user's sessionToken. Then, once the new user has been created, restore the session with User.become:
var sessionToken = Parse.User.current().getSessionToken();
Parse.User.signUp(username, password).then(function(newUser) {
Parse.User.become(sessionToken);
});
I can create a 'Parse Cloud' method that allows you use the 'Master Key' and call it from the SDK using the Cloud.
Parse.Cloud.define('salvarUsuario', function(request, response) {
var nomeCompleto = request.params.nomeCompleto;
var Email = request.params.Email;
var Username = request.params.Username;
var cpf = request.params.cpf;
var Password = request.params.Password;
var funcionarioBool = request.params.funcionarioBool;
var ativo = request.params.ativo;
var primeiroAcesso = request.params.primeiroAcesso;
var tipoAcesso = request.params.tipoAcesso;
var medicoBool = request.params.medicoBool;
//Parâmetros de controle
var fotoSelecionada = request.params.fotoSelecionada;
var usuario = new Parse.User();
usuario.set("nomeCompleto", nomeCompleto);
usuario.set("email", Email);
usuario.set("username", Username);
usuario.set("cpf", cpf);
usuario.set("password", Password);
usuario.set("funcionarioBool", funcionarioBool);
usuario.set("ativo", ativo);
usuario.set("primeiroAcesso", primeiroAcesso);
usuario.set("tipoAcesso", tipoAcesso);
usuario.set("medicoBool", medicoBool);
if(medicoBool) {
var medicoId = request.params.medico;
var Medico = Parse.Object.extend("Medico");
var medicoPointer = Medico.createWithoutData(medicoId);
usuario.set("medico", medicoPointer);
}
if(fotoSelecionada) {
var bytes = request.params.bytesFoto;
var file = new Parse.File("foto.png", bytes, "image/png");
usuario.set("foto", file);
}
usuario.save(null, {
useMasterKey: true,
success: function(salvoUsuario){
// The user was saved correctly
response.success("1");
},
error: function(error){
response.error("Erro ao criar novo usuário");
}
});
});

Parse.com Role Base access not working

I am experiencing problems with accessing an object i created with role ACL. I created the object like this
var Enquiry = Parse.Object.extend("Enquiry");
var enquiry = new Enquiry();
enquiry.set("first", firstName);
enquiry.set("last", lastName);
var enquiryACL = new Parse.ACL();
enquiryACL.setRoleWriteAccess("XXX_User", true);
enquiryACL.setRoleReadAccess("XXX_User", true);
enquiry.setACL(enquiryACL);
enquiry.save();
I later on try to access the same object i created when a user of the role "XXX_User" is logged in
var Item = Parse.Object.extend("Enquiry");
var query = new Parse.Query(Item);
query.find({
success : function(items) {
displayItems(items);
},
error : function(error) {
alert("couldn't display list: " + error.code + " " + error.message);
}
});
Now the problem is that the query doesn't return any rows even though i can see in the dashboard that the object is created. The ACL set for the enquiry objects is {"role:XXX_User":{"write":true,"read":true}}
I can see that there is a Role Object with name "XXX_User" in the data browser and i can also see that the user i log in with is shown when i click "View Relations" on the Role object in the data browser.
Is there anything i am missing? Any help on this is deeply appreciated.
I figured out the problem. It was not working because the role XXX_User i created was saved with public read access to be false. I had to make sure that the role is publicly readable and then it worked like a charm.

Resources