Adding User to Organization Unit and Group using Google Directory API - c#

I am successful to create new user account using Google Directory API in .Net platform, but now I need to add that created user to Organization Unit and Group. I see the API details in this link to add the user to Organization Unit but any example showing insertion to Organization Unit would be greatly appreciated.
Updated with working code: Below is the code to create new user account using Directory API:
String serviceAccountEmail = ".........#developer.gserviceaccount.com";
X509Certificate2 certificate = new X509Certificate2(#"C:\key.p12", "secret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[]
{
DirectoryService.Scope.AdminDirectoryUser
},
User = "test#example.com",
}.FromCertificate(certificate));
var ser = new DirectoryService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Google Account",
});
try
{
var user = new Google.Apis.Admin.Directory.directory_v1.Data.User()
{
Name = new Google.Apis.Admin.Directory.directory_v1.Data.UserName()
{
GivenName = FirstName.Text,
FamilyName = LastName.Text
},
Password = password
};
User newUser = new User();
UserName newUserName = new UserName();
newUser.PrimaryEmail = Email.Text;
newUserName.GivenName = FirstName_txt.Text;
newUserName.FamilyName = LastName_txt.Text;
newUser.Name = newUserName;
newUser.Password = password;
//Adding User to OU:
newUser.OrgUnitPath = "/Employee";
User results = ser.Users.Insert(newUser).Execute();
//Adding User to Group:
Member newMember = new Member();
newMember.Email = Email.Text;
newMember.Role = "MEMBER";
newMember.Kind = "admin#directory#member";
api.Members.Insert(newMember, "Employee#example.com").Execute();
Any idea how to insert the created user in Organization Unit and Group using Directory API?

To insert the new user into a Organization Unit just set the OU path when you create the user.
User newUser = new User();
UserName newUserName = new UserName();
newUser.PrimaryEmail = Email.Text;
newUserName.GivenName = FirstName_txt.Text;
newUserName.FamilyName = LastName_txt.Text;
newUser.Name = newUserName;
newUser.Password = password;
**newUser.OrgUnitPath ="\My\Organization\Unit\path\";**
User results = ser.Users.Insert(newUser).Execute();
Now your user has been added to the OU path.
To add a member into a group see the following code.
Member newMember = new Member();
newMember.Email = userKey;//email of the user that you want to add
newMember.Role = "MEMBER";
newMember.Type = "USER";
newMember.Kind = "admin#directory#member";
ser.Members.Insert(newMember, "MyDestinationGroup#mydomain").Execute();
that's it.
Note: you must review the scopes for the correct permissions.
Hope this help you.

Related

Add role to already created application using Azure AD Graph API in C#

How to add roles in application that is already created on azure ad using Azure AD Graph API in c#.
I create role like this in c#:
Guid _id = new Guid();
AppRole appRole = new AppRole
{
AllowedMemberTypes = _AllowedMemberTypes,
Description = "Admins can manage roles and perform all actions.",
DisplayName = "Global Admin",
Id = _id,
IsEnabled = true,
Value = "Admin"
};
What call will be used to add this new role in application using Azure AD Graph API.
Finally i was able to create a new role on azure using Azure Ad Graph API
1) Create a Role:
Guid _id = Guid.NewGuid();
List<String> _AllowedMemberTypes = new List<string> {
"User"
};
AppRole appRole = new AppRole
{
AllowedMemberTypes = _AllowedMemberTypes,
Description = "Admins can manage roles and perform all actions.",
DisplayName = "Global Admin",
Id = _id,
IsEnabled = true,
Value = "Admin"
};
2) Get Application in which role needed to be created:
IPagedCollection<IApplication> pagedCollection = await activeDirectoryClient.Applications.Where(x => x.AppId == AppclientId).ExecuteAsync();
var appObject = pagedCollection.CurrentPage.ToList().FirstOrDefault();
3) Add Role to Applicationa and Update Application:
appObject.AppRoles.Add(appRole as AppRole);
await appObject.UpdateAsync();
You could refer to the code as below to assign application role.
1.get access token
private static async Task<string> GetAppTokenAsync(string graphResourceId, string tenantId, string clientId, string secretKey)
{
string aadInstance = "https://login.microsoftonline.com/" + tenantId + "/oauth2/token";
AuthenticationContext authenticationContext = new AuthenticationContext(aadInstance, false);
var result = await authenticationContext.AcquireTokenAsync(graphResourceId,
new ClientCredential(clientId, userId));
return result.AccessToken;
}
2.Init the graphclient.
var graphResourceId = "https://graph.windows.net";
var tenantId = "tenantId";
var clientId = "client Id";
var secretKey = "secret key";
var servicePointUri = new Uri(graphResourceId);
var serviceRoot = new Uri(servicePointUri, tenantId);
var activeDirectoryClient = new ActiveDirectoryClient(serviceRoot, async () => await GetAppTokenAsync(graphResourceId, tenantId, clientId, secretKey));
3.create role
AppRole appRole = new AppRole
{
Id = Guid.NewGuid(),
IsEnabled = true,
Description = "Admins can manage roles and perform all actions.",
DisplayName = "Global Admin",
Value = "Admin"
};
4.add role assginments
User user = (User) activeDirectoryClient.Users.GetByObjectId("userobjectId").ExecuteAsync().Result;
AppRoleAssignment appRoleAssignment = new AppRoleAssignment
{
Id = appRole.Id,
ResourceId = Guid.Parse(newServicePrincpal.ObjectId),
PrincipalType = "User",
PrincipalId = Guid.Parse(user.ObjectId),
};
user.AppRoleAssignments.Add(appRoleAssignment);
user.UpdateAsync().Wait();

Google Contacts API returns list of email addresses I sent to, but not those in my Contacts list?

Google Contacts API returns list of email addresses I sent to, but not those in my Contacts list?
I'm using google contact api and try to get the list of emails in my gmail contacts. The google contact is at https://contacts.google.com/u/0/preview/all .
Below it is the code I use:
public List<GMail> GetContacts(GooglePlusAccessToken serStatus)
{
List<GMail> ret = new List<GMail>();
string google_client_id = _ClientId;
string google_client_sceret = _ClientSeceret;
string refreshToken = serStatus.refresh_token;
string accessToken = serStatus.access_token;
string scopes = "https://www.google.com/m8/feeds/contacts/default/full/";
OAuth2Parameters oAuthparameters = new OAuth2Parameters()
{
ClientId = google_client_id,
ClientSecret = google_client_sceret,
RedirectUri = GetRedirectUrl(),
Scope = scopes,
AccessToken = accessToken,
RefreshToken = refreshToken
};
RequestSettings settings = new RequestSettings("<var>Invite GMail Friends</var>", oAuthparameters);
ContactsRequest cr = new ContactsRequest(settings);
ContactsQuery query = new ContactsQuery(ContactsQuery.CreateContactsUri("default"));
query.NumberToRetrieve = _NumberToRetrieve;
Feed<Contact> feed = cr.Get<Contact>(query);
foreach (Contact entry in feed.Entries)
{
foreach (EMail email in entry.Emails)
{
GMail g = new GMail(email.Address);
ret.Add(g);
}
}
return ret;
}
But for some reasons, the code returns the list of email addresses that I sent to in the past, but not the emails in my contact list. Is this correct? Anyone knows why?
Thanks
** Thanks for Allen's answer, here is my code, and it works great! The contact group is actually: SystemGroup:MyContacts#gmail.com**
public List<GMail> GetContacts_2(GooglePlusAccessToken serStatus)
{
List<GMail> ret = new List<GMail>();
string google_client_id = _ClientId;
string google_client_sceret = _ClientSeceret;
/*Get Google Contacts From Access Token and Refresh Token*/
string refreshToken = serStatus.refresh_token;
string accessToken = serStatus.access_token;
string scopes = "https://www.google.com/m8/feeds/groups/default/full/?v=3.0";
OAuth2Parameters oAuthparameters = new OAuth2Parameters()
{
ClientId = google_client_id,
ClientSecret = google_client_sceret,
RedirectUri = GetRedirectUrl(),
Scope = scopes,
AccessToken = accessToken,
RefreshToken = refreshToken
};
RequestSettings settings = new RequestSettings("<var>Invite GMail Friends</var>", oAuthparameters);
ContactsRequest cr = new ContactsRequest(settings);
GroupsQuery query = new GroupsQuery(GroupsQuery.CreateGroupsUri("default"));
query.NumberToRetrieve = 1000; // _NumberToRetrieve; // 100;// 5000;
//Feed feed = cr.Get(query);
Feed<Group> feed = cr.Get<Group>(query);
string gpId = string.Empty;
foreach (Group gp in feed.Entries)
{
if (gp.Title.Contains("Contacts"))
{
gpId = gp.Id;
//break;
}
//// for testing
//GMail g = new GMail(gp.Title.Replace(" ", "") + "#gmail.com");
//ret.Add(g);
}
if (gpId.Length > 0)
{
scopes = "https://www.google.com/m8/feeds/contacts/default/full/?v=3.0";
oAuthparameters = new OAuth2Parameters()
{
ClientId = google_client_id,
ClientSecret = google_client_sceret,
RedirectUri = GetRedirectUrl(),
Scope = scopes,
AccessToken = accessToken,
RefreshToken = refreshToken
};
settings = new RequestSettings("<var>Invite GMail Friends</var>", oAuthparameters);
//ContactsRequest cr = new ContactsRequest(settings);
cr = new ContactsRequest(settings);
ContactsQuery query2 = new ContactsQuery(ContactsQuery.CreateContactsUri("default"));
query2.NumberToRetrieve = _NumberToRetrieve; // 100;// 5000;
query2.OrderBy = ContactsQuery.OrderByLastModified;
query2.SortOrder = ContactsQuery.SortOrderDescending;
query2.Group = gpId;
Feed<Contact> feed2 = cr.Get<Contact>(query2);
foreach (Contact entry in feed2.Entries)
{
foreach (EMail email in entry.Emails)
{
GMail g = new GMail(email.Address);
ret.Add(g);
}
}
//if (ret.Count <= 0)
//{
// GMail g = new GMail("NoContact#gmail.com");
// ret.Add(g);
//}
}
//else
//{
// // for testing
// GMail g = new GMail("NoGroup#gmail.com");
// ret.Add(g);
//}
return ret;
}
To start with, I feel your pain. Google's APIs are the worst. Period.
The way I got around it (not an efficient way of doing things but this is the best I could find. Else Google returns all those bogus contact emails that were ever communicated with the account holder, could be thousands of such entries in a typical GMail account)) is this (its VB.net code but you can get a gist and convert easily)
FIRST RETRIEVE CONTACT GROUPS AND LOOK FOR THE TITLE "CONTACTS"
Dim settings As New RequestSettings("MyApp", RefreshOAuthToken())
Dim cr As New ContactsRequest(settings)
'retrieve Contacts group (this is to retrieve only real contacts)
Dim groupquery As New GroupsQuery(GroupsQuery.CreateGroupsUri("default"))
Dim fgrp As Feed(Of Group) = cr.Get(Of Group)(groupquery)
Dim GroupAtomId As String = ""
For Each gr In fgrp.Entries
If gr.Title.Contains("Contacts") Then
GroupAtomId = gr.Id
Exit For
End If
Next
THEN USE THE ID OF THE CONTACT GROUP TO SEARCH IN CONTACT
Dim query As New ContactsQuery(ContactsQuery.CreateContactsUri("default"))
query.NumberToRetrieve = 2000
query.OrderBy = ContactsQuery.OrderByLastModified
query.SortOrder = ContactsQuery.SortOrderDescending
query.Group = GroupAtomId
Dim f As Feed(Of Contact) = cr.Get(Of Contact)(query)
For Each entry As Contact In f.Entries
'Do something with the data, these are real contacts in GMail
Next
So the point here is to first get the group id and use it in contact search. I believe this is what your code is missing.

Google Contacts API with Service Account

I am having trouble to Create a contact in google using google api v3.
I can successfully call cr.GetContacts() to get all the contacts (for the user I'm specifying), but cr.Insert is giving me the error:
Execution of request failed: https://www.google.com/m8/feeds/contacts/someuser#mydomain.com/full
Am I missing something?
string serviceAccountEmail = "111111111111-aaaa1a1aa11a1aaaaaaa11aaaa1aaa11#developer.gserviceaccount.com";
X509Certificate2 certificate = new X509Certificate2(#"C:\All\ContactsManager-1aa1bbb1ab11.p12", "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[]
{
"https://www.google.com/m8/feeds"
},
User = "someuser#mydomain.com"
}.FromCertificate(certificate));
credential.RequestAccessTokenAsync(System.Threading.CancellationToken.None).Wait();
RequestSettings rs = new RequestSettings("ContactsManager", credential.Token.AccessToken);
//rs.AutoPaging = true;
ContactsRequest cr = new ContactsRequest(rs);
//var contacts = cr.GetContacts(); //////THIS LINE WORKS AND GETS ALL THE CONTACTS
Uri feedUri = new Uri(ContactsQuery.CreateContactsUri("someuser#mydomain.com"));
//feedUri will now be https://www.google.com/m8/feeds/contacts/someuser%40mydomain.com/full
Contact createdEntry = cr.Insert(feedUri, newContact);
Console.WriteLine("Contact's ID: " + createdEntry.Id);
EDIT: I figured out the problem, just want to update for anybody else who has the same issue.
If you followed the v3 documentation for creating a contact: they have a section on that contact entity like this:
newEntry.IMs.Add(new IMAddress()
{
Primary = true,
Rel = ContactsRelationships.IsHome,
Protocol = ContactsProtocols.IsGoogleTalk,
});
if you remove this IMAddress, then the contact creates fine.

C# EWS copy contacts to a mailbox

I want to select the user "test" so I can create a contact into his mailbox.
My actual problem is that it will create Contacts into my user "c-sharp".
"c-sharp" has full access on "test" mailbox
I changed the IP and the contact infos users are also only for testing.
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013);
service.TraceEnabled = true;
service.TraceFlags = TraceFlags.All;
service.EnableScpLookup = false;
service.Credentials = new WebCredentials("c-sharp", "c-sharp", "domain");
service.UseDefaultCredentials = false;
IgnoreBadCertificates();
service.Url = new Uri("https://192.000.000.000/EWS/Exchange.asmx");
Contact contact = new Contact(service);
// Specify the name and how the contact should be filed.
contact.GivenName = "n.a.";
contact.FileAsMapping = FileAsMapping.SurnameCommaGivenName;
contact.DisplayName = "bau gmbh";
// Specify the company name.
contact.CompanyName = "bau";
// Specify the business, home, and car phone numbers.
contact.PhoneNumbers[PhoneNumberKey.BusinessPhone] = "00000 00000";
contact.PhoneNumbers[PhoneNumberKey.MobilePhone] = "n.a.";
contact.PhoneNumbers[PhoneNumberKey.BusinessFax] = "00000 00000";
// Specify two email addresses.
contact.EmailAddresses[EmailAddressKey.EmailAddress1] = new EmailAddress("e#mail.de");
//homepage
contact.BusinessHomePage = "n.a.";
// Specify the home address.
PhysicalAddressEntry paEntry1 = new PhysicalAddressEntry();
paEntry1.Street = "straße";
paEntry1.City = "stadt";
paEntry1.State = "D";
paEntry1.PostalCode = "88890";
paEntry1.CountryOrRegion = "Deutschland";
contact.PhysicalAddresses[PhysicalAddressKey.Home] = paEntry1;
contact.Save();
Already tried this:
service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.PrincipalName, "test");
I tested it with "test" and "test#domain" and "test#domain.de"
And get back this error:
"Der Name des Identitätsprinzipals ist ungültig."
Own translation: "The name of the identity principal is unvailed"
You can use Impersonation like this
ExchangeUserData exchangeUserData = new ExchangeUserData();
exchangeUserData.Username = "c-sharp";
exchangeUserData.Password = "c-sharp"; // c-sharp's Password
ExchangeService service = Service.ConnectToServiceWithImpersonation(exchangeUserData, impersonatedUserPrincipal);
Contact contact = new Contact(service);
// Specify the name and how the contact should be filed.
contact.GivenName = "n.a.";
contact.FileAsMapping = FileAsMapping.SurnameCommaGivenName;
contact.DisplayName = "bau gmbh";
// Specify the company name.
contact.CompanyName = "bau";
// Specify the business, home, and car phone numbers.
contact.PhoneNumbers[PhoneNumberKey.BusinessPhone] = "00000 00000";
contact.PhoneNumbers[PhoneNumberKey.MobilePhone] = "n.a.";
contact.PhoneNumbers[PhoneNumberKey.BusinessFax] = "00000 00000";
// Specify two email addresses.
contact.EmailAddresses[EmailAddressKey.EmailAddress1] = new EmailAddress("e#mail.de");
//homepage
contact.BusinessHomePage = "n.a.";
// Specify the home address.
PhysicalAddressEntry paEntry1 = new PhysicalAddressEntry();
paEntry1.Street = "straße";
paEntry1.City = "stadt";
paEntry1.State = "D";
paEntry1.PostalCode = "88890";
paEntry1.CountryOrRegion = "Deutschland";
contact.PhysicalAddresses[PhysicalAddressKey.Home] = paEntry1;
contact.Save();
If your c-sharp user has the proper rights in Exchange, you should be able to do:
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013);
service.Credentials = new WebCredentials("c-sharp", "c-sharp", "domain");
service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.PrincipalName, "test");
If this doesn't work for you, please comment below or update your question (there's an "edit" link under it) with the exact behavior you are seeing including any error messages.
Problem sloved.
I found the bug... both of you are right just change:
service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.PrincipalName, "test");
Into:
service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "test#domain.de");
Thats all ...
Great thanks to you

Dynamics 2011: Setting Owner of Activity record

I am trying create Activity record in Dynamics 2011 with owner name set as "test_user". Instead below code is taking credential which is used to access Dynamics API. Is there any way to impersonate "test_user" user without passing his password? Thank you.
string TargetCrmService = ConfigurationManager.AppSettings["TargetCrmService"];
string UserName = ConfigurationManager.AppSettings["UserName"];
string Domain = ConfigurationManager.AppSettings["Domain"];
string Password = ConfigurationManager.AppSettings["Password"];
Uri organizationUri = new Uri("http://CRMDEV/XRMServices/2011/Organization.svc");
Uri homeRealmUri = null;
ClientCredentials credentials = new ClientCredentials();
credentials.UserName.UserName = Domain + "\\" + UserName;
credentials.UserName.Password = Password;
OrganizationServiceProxy orgProxy = new OrganizationServiceProxy(organizationUri, homeRealmUri, credentials, null);
var _userId = (from u in orgProxy.CreateQuery<SystemUser>()
where u.FullName == "Kevin Cook"
select u.SystemUserId.Value).FirstOrDefault();
IOrganizationService _service = (IOrganizationService)orgProxy;
_service.CallerId = _userId;
try
{
//Entity activity = new Entity("activitypointer");
Entity activity = new Entity("appointment");
activity["subject"] = "Test Meeting 1";
activity["description"] = "Test Description";
activity["scheduledstart"] = DateTime.Now;
activity["scheduledend"] = DateTime.Now.AddMinutes(30);
activity["createdbyname"] = "test_user";
activity["modifiedbyname"] = "test_user";
activity["createdbyname"] = "test_user";
activity["owneridname"] = "test_user";
Guid id = _service.Create(activity);
Console.WriteLine("id: " + id);
}
catch (Exception ex)
{
//MessageBox.Show(ex.Message);
}
Modified Code
Based on example on http://msdn.microsoft.com/en-us/library/gg309629.aspx
var _userId = (from u in orgProxy.CreateQuery<SystemUser>()
where u.FullName == "Kevin Cook"
select u.SystemUserId.Value).FirstOrDefault();
You have two methods of setting the owenr id of an entity in CRM.
Use the AssignRequest to update the record after it is created.
Use impersonation with the OrganizationServiceProxy, CallerId to use the particular user you'd like to be the owner when it's created. You don't need their password to do impersonation, just their CRM SystemUserId

Categories

Resources