Using Delegates with Exchange Web Services - delegates

Has anyone used delegates with exchnage web services? I would like one user to be able to control other users' calendars in Exchange. I'm finding this problem to be a little tricky, and I'd like to see how others have been able to get it to work properly.

I'm just getting started here, but i managed to get access to Resource calendars via a delegate account.
I used the recommendations from this article about delegate account and resource accounts. (Resource accounts are tricky because they are disabled in the AD, and you have to use a delegate account to get access to them)
After setting up the delegate account on the server, I set up the ExchangeServerBinding using the credentials of the delegate account:
ExchangeServiceBinding binding = new ExchangeServiceBinding();
binding.Url = #"https://dc1.litwareinc.com/ews/exchange.asmx";
// Setup binding with username and password of the delegate account
binding.Credentials =
new NetworkCredential(delegateuserName, delegatepassword, "litwareinc.com");
(I'm using Microsofts prepared virtual server image for testing)
Then when accessing the mailbox, I set up a FindItemType request and use the smtp address of the account i want to access:
// Prepare request
var findItemRequest = new FindItemType();
// Setup the mailbox using the smtp address of the account wanted
var mailbox = new EmailAddressType {EmailAddress = mailboxId};
findItemRequest.ParentFolderIds =
new[] {new DistinguishedFolderIdType {Mailbox = mailbox}};
((DistinguishedFolderIdType) findItemRequest.ParentFolderIds[0]).Id =
DistinguishedFolderIdNameType.calendar;
findItemRequest.Traversal = ItemQueryTraversalType.Shallow;
// Add ItemResponseShapeType and Calendarview to request here ...
// The create a FindItemResponseType using the binding and the request
var response = binding.FindItem(findItemRequest);
So in short:
Setup an account with delegate access on the Exchange server, this can be done via owa or with a Exchange Shell script
Use the account with delegate access on the ExchangeServiceBinding object
Access target account using a FindItemType with the target account smtp-addres as EmailAddressType
Regards
Jesper Hauge

Related

Interactive Logon Required for Azure Resources NodeJS App

I am looking to pull a list of Azure resources such as VMs, AppServices, etc and possibly interact (create, delete, scale, etc.) via the Azure SDK for NodeJS. The examples seem to demonstrate/push the use of an interactive login.
The reason I don't want to use the interactive logon is so I can schedule these tasks instead of requiring interaction.
Example, I looked at the authentication module and it is focused on interactive logon as well. Is there another means to authenticate instead of interactive as the previous SDK seemed to allow to authentication via secrets and subscription ID:
//Environment Setup
_validateEnvironmentVariables();
var clientId = process.env['CLIENT_ID'];
var domain = process.env['DOMAIN'];
var secret = process.env['APPLICATION_SECRET'];
var subscriptionId = process.env['AZURE_SUBSCRIPTION_ID'];
var credentials = new msRestAzure.ApplicationTokenCredentials(clientId, domain, secret, { 'tokenCache': tokenCache });
After assistance with the SDK team, there are options for auth for node, but better to get these from the node site and use the #azure ones as those are the most up to date. Ex: https://www.npmjs.com/package/#azure/ms-rest-nodeauth

Classroom API - Access classroom with Service Account

I need some help as I'm really stuck!!!! I have spent days and hours on this one but I can't figure it. I have searched all possible forums and other similar posts without any success.
So, the requirement :
We are trying to integrate Classroom API on our .Net platforms. The tricky part is that they want to use service accounts.
The problem :
Google.Apis.Requests.RequestError The caller does not have permission [403]
The caller does not have permission] Location[ - ] Reason[forbidden] Domain[global]
I have followed the documentation as shown in :
https://developers.google.com/identity/protocols/OAuth2ServiceAccount.
I understand that we need to set up a service account in the Google API Console, so I've done the following:
1) I have created a service account and enabled G Suite Domain-wide Delegation in the Google API Console
2) In the Admin Console, in Manage API Client Access, I have entered the service account's client id and have enabled scopes.
3) A have downloaded the json file with all the service account credentials (private key, email)
and the code...
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(cr.client_email)
{
Scopes = new[] { ClassroomService.Scope.ClassroomCourses },
}.FromPrivateKey(cr.private_key));
// Create the service.
service = new ClassroomService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Demo-School",
});
and the actual call to the Classroom API to create a course :
var resource = service.Courses.Create(course);
var result = await resource.ExecuteAsync();
So, despite all that, whenever i try to create a course, I get the above error.
When I try to create a Course using the Reference page (https://developers.google.com/classroom/reference/rest/v1/courses/create) it works fine. I can create courses, teachers, set permissions etc..
But when I try to do that programmatically.. i.e from a console app, there is NO way I can get it working.
Can ANYONE please advice???????What am I missing??

How to impersonate a user and insert a calendar in its behalf using service account?

I'm trying to create calendars and share them with my organization's users using a service account.
What I would like to obtain is the ability to manage the created calendars both from my website code (using the service account) and from the regular google calendar web interface.
So i thought I could create a dumb user account (with credentials), impersonate it with a service account and then create and share my calendars and manage events both from my weba pp code and google regular user interface.
Is it the right way to proceed? Am I missing something?
If my last guess is right how can I achieve it using laravel and google-api-clients for PHP?
Thank you for your advices
After Sleeping on it I realized there's no need to impersonate a user and insert a new calendar.
To manage a service account calendar from the officiale web interface you can simply share it with owner rights to the "dumb user"
With something like this:
//create calendar
$calendar = new Google_Service_Calendar_Calendar();
$calendar->setSummary('calendarname');
$calendar->setTimeZone('Europe/Berlin');
$service = new Google_Service_Calendar();
$createdCalendar = $service->calendars->insert($calendar);
//share it with your dumb user
$rule = new Google_Service_Calendar_AclRule();
$scope = new Google_Service_Calendar_AclRuleScope();
$scope->setType("user");
$scope->setValue('dumbuser#organization.com');
$rule->setScope($scope);
$rule->setRole("owner");
$createdRule = $service->acl->insert(createdCalendar->getId(), $rule);
So my problem is solved for the moment, the only question I'm still thinking about is how can I impersonate a user with service account credential? Well I'll think about it when it will be really useful

Google+ scope PLUS.LOGIN not asking for Google Circle Connection permission

I am trying to get Google+ connections that are visible.
by referring to documentation https://developers.google.com/+/web/samples/php,
it is clear that on adding 'plus.login' scope fetches G+ connections, age range and language.
But in my case this scope only asks permission for fetching age range and language. I am not able to fetch G+ connections.
I tried using google-api-php-client in my application. Also followed the quick start guide as mentioned in fresh application but access permission page does not include G+ connection in circle permission.
part of the code is below
define('SCOPES', implode(' ',array(
Google_Service_Plus::PLUS_ME, Google_Service_Plus::PLUS_LOGIN,Google_Service_Plus::USERINFO_EMAIL, Google_Service_People::CONTACTS
))
);
Class GoogleClient {
function getClient() {
$client = new Google_Client();
$client->setApplicationName(APPLICATION_NAME);
$client->setScopes(SCOPES);
$client->setAuthConfig(CLIENT_SECRET_PATH);
$client->setAccessType('offline');
$this->authUrl = $client->createAuthUrl();
redirecting to the above created AuthUrl results in asking permissions displayed in picture
$plusConnections = new \Google_Service_Plus($client);
$optParamsConnections = ['maxResults' => 99];
$_people = $plusConnections->people->listPeople('me', 'visible', $optParamsConnections);
$_people doesnt get any data. however for the same user when tried on Google API explorer, the connections are retrived
any suggestion why is this strange behaviour and how to resolve it
thanks
The ability of the plus.login scope to retrieve connections, and the People.list endpoint itself, has been deprecated:
The Google+ People API list endpoint has been deprecated. In the past, the https://www.googleapis.com/auth/plus.login scope allowed access to a list of people in the user's circles in addition to their name and profile information. Starting in September 2016, new grants of the plus.login scope will allow access to only the user's name and profile info; calls to the API return empty circle data for those new sign-ins. In 2017 Q1, you will get empty circle data back for all users.
https://developers.google.com/+/web/people/#retrieve-a-collection-of-people
The authentication permissions screen is just a standard screen. It does not specifically say which methods you have access to. You should check the documentation in this case
People.list
Authorization
This request requires authorization with at least one of the following scopes (read more about authentication and authorization).
Scope https://www.googleapis.com/auth/plus.login
As long as you have sent the plus.login scope and the user accepts it you are able to use the people.list method. I actually think the one "Basic profile info" is the one you are looking for, it gives you access to a lot of the general Google Plus info for a user.
Side Note: you should try sending email scope or profile. If memory services they both just state "offline Access" which IMO is even more misleading to the users.

EWS API 2013 Calendar: The specified folder could not be found in the store

With Exchange 2013 EWS API in C#, trying to create an appointment in the calendar of another user, as follows:
var mailbox = new Mailbox("xyz#xyz.com");
var folderId = new FolderId(WellKnownFolderName.Calendar, mailbox);
var appointment = new Appointment(service);
appointment....//etc
appointment.Save(folderId, SendInvitationsMode.SendToAllAndSaveCopy);
This works if we create the appointment via the administrators calendar, but not when we specify the account of another user that was created through the Exchange Admin Center (ECP). We get the error:
The specified folder could not be found in the store.
Apparently this is a permissions issue, but where is this permission set?
The user you authenticate with on the service object must have full access permission to the calendar you want to save the appointment on. This can be done via Exchange Management Console or PowerShell. There are alternatives, such as impersonation, but that requires slightly different coding.

Resources