Using streaming notifications with delegate access - exchange-server

So far all information that I read about streaming notifications says that you are expected to use impersonation with streaming subscriptions when you want to subscribe to not your mailboxes. This sounds reasonable when you have service application that accesses user mailboxes. In my case I need to subscribe to calendars of room mailboxes.
Based on this answer: Getting notification from Resource calendar in EWS room mailboxes usually have their account disabled and I need to use delegation.
So what is proper way to subscribe and maintain affinity when using delegation? Should I just ignore setting the impersonation header and do everything else as described in How to: Maintain affinity between a group of subscriptions and the Mailbox server in Exchange?

When you creating folder object, pass the other user email address which shared his calendar with you. AS below
folders[0] = new FolderId(WellKnownFolderName.Calendar, new Mailbox("OtherUserEmail"));
And then subscribe.
service.SubscribeToStreamingNotifications

For resource rooms I use impersonation as the preferred access. I know that in general the AD userids for room resources are disabled for login in AD, but my guess is that affects only Windows login. Technically when you impersonate, you don't really login as the room user. You log in as the service account with those credentials, and then indicate with the impersonation id that you want Exchange to pretend it's actually the room making all the requests you are about to make.

Related

Google API Authentication for App That Only Accesses One Account

Should I use a Service Account or an OAuth 2.0 Client ID?
I'm struggling to understand Google's documentation on authenticating for their APIs. I'm creating a basic application that will help users add and modify Google Calendar events for a single Google account (the account is shared between all users). I only need the application to access that one account, it'll never need to access any others.
It seems to me that Service Account would be best for this, but Google's documentation suggests Service Accounts should only be used for automated processes (unless I'm misunderstanding). For instance this page contains the following, describing when to use Service Accounts.
Would my application qualify as acting on the users behalf?
If so, I would want to use OAuth Client ID credentials, which will ask the user to sign in to a google account. In this case, is there a way I can guarantee they only sign in to the one account I want modified?
I can't find any decent documentation on the OAuth authentication requests to figure this out myself. If there is any could you point me there?
I'm sure I'm misunderstanding something basic here, but thank you for any help!
First off you should know that you can only use service accounts with Google aclendar api if you have a google workspace domain account.
You can then set up a calendar and a domain user that the service account can act on behalf of to control the access of that calendar.
Assuming that your application is going to preform all actions on this calendar then yes i would say that you could use a service account for this. If your app bacly has a ui with a calendar on it your just using google calendar to store the data.
However if you intend to share this calendar with the users themselves, this way they could see it within their own google Calendar account. Im not sure a service account would be the way to go.
If you want the users to be able to see it and make changes then you may want to just use Oauth2. Grant them access to the calendar and then request access to their calendar account.
Drawback to that option is going to be the verification process. You will get access to all the users calendars and your going to need write access.
If you can go with a service account you really should consider it it will save you a lot of hassle with verification.

How to send service emails via Gmail (machine-2-machine) with secure restrictions?

How to send service emails
from my backend with smtp.google.com or Gmail API while making sure
the secret stored on the backend server can only be used to send emails from a specific sender?
Goal
send user account activation emails from my backend
use smtp.google.com or Gmail API (i.e. no own SMTP server)
authenticate with OAuth2.0 (i.e. don't enable "less secure apps")
Current state
implemented the email sending part
for testing, I created a noreply#**.** Google Suite account
for testing, I generated an accessToken via OAuth2 Playground
using the accessToken I can send emails via smtp.googl.com
Problem
Google suggests to use a service account for this
But to send emails from no-reply#x.y I have to enable Domain-wide Delegation
Domain-wide delegation allows to impersonate every domain account
the secret stored on the backend should only allow to send mails from no-reply#**.**
Lets start with send user account activation emails from my server I am gong to assume that you have a web app. This web app allows users to register with your system. Now when a user registers with your system you want to automatically send them an account creation email. Your idea is to use Google rather than setting up your own smtp server and sending these emails from your own system. Not a bad idea really.
Lets think about this for a minute the emails would need to be sent automatically so you need some kind of service sending them. To do that you want to use a service account. Again this is a great idea using a pre authorized service account that you will not need to have a user to authorize the app.
The only issue is that service accounts do not work with normal gmail accounts. To use a service account with Gmail api you need to use a google workspace domain account. The workspace domain admin would then be able to add permissions to the service account letting it act like a user on the domain. In this case your idea of no-reply.
So your workspace domain account would have a user called no-reply. The domain admin would then configure domain wide delegation to the service account allowing it to pretend that it is the user called no-reply. For all intents and purposes the service account is the no-reply user. It will be able to send mails as if they are coming from that user.
For all this to work you will need the workspace account with that user.
Have a look at the following link, it's actually one of Google's better examples it shows how to set up the delegation.
Perform Google Workspace Domain-Wide Delegation of Authority
Here you create a service account with credentials, allow this account to impersonate other users (e.g. the no-reply user), to only use the Gmail API and to only use it to send emails.
the documentation is a bit outdated, you can skip the step Grant users access to this service account and create the service account key afterwards via the service account edit function: Manage keys
in the step Domain wide delegation you need Google Admin not the Google Cloud Platform Admin Console as in the previous step
Just remember to swap out the lines about
https://www.googleapis.com/auth/admin.directory.user,
https://www.googleapis.com/auth/admin.directory.group
and use
https://www.googleapis.com/auth/gmail.send
instead as you want to access the Gmail API and only allow the service account to send (not read) emails
tip
in the sample code in that link
.setServiceAccountUser(userEmail)
userEmail is the email address of the user you want to impersonate in this case no-reply#x.y
So I guess what I am saying is that what you want to do is definitely possible, however, it may be easier just to set up your own SMTP server.

Is there a way to pull all exchange events for a specific room using graphAPI

Reviewing this, but not clear. Not looking to do this for just my user and can run with elevated application rights with access to all calendars.
https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/calendar_list_events
Yes you just need to make sure you give your application the following permission
Calendars.Read.Shared Read user and shared calendars Allows the app to read events in all calendars that the user can access, including delegate and shared calendars.
ref https://developer.microsoft.com/en-us/graph/docs/concepts/permissions_reference
So as long as the calling account then has access to the Room Mailbox (eg via Delegation so they can access the same thing in Outlook etc) you just use the following endpoint
https://graph.microsoft.com/v1.0/users('room#domain.com')/calendar/events

Create Calendar Events Without User Authentication

I'm writing an application that needs to create Calendar events on a user's Outlook Calendar. However, I will not have access to their passwords, and they will most likely not be involved in the workflow to enter them at any point.
Is it possible to create these events with the user being authenticated? If not, are there alternatives?
This is for an on-premise Exchange Server, not Exchange Online.
You can use app impersonation, as long as the admin can add a service account and grant app impersonation. See https://msdn.microsoft.com/en-us/library/office/dd633680(v=exchg.80).aspx for more details.
If the user can use his Windows Login to login to the Exchange Server, you can simply use that - if your application runs on the users machine under his account. EWS-managed-API does that out-of-the-box.
If not, you could create an additional user on the Exchange Server, who creates the appointments on his own account and invites everyone per email.

How do you get Yammer to treat registered app as a user

In messaging platforms like Slack and HipChat you can integrate apps that can post messages to groups without them being sent from a user e.g.
Defect Management System: A new defect was logged at 12pm
Instead of:
John Smith: A new defect was logged at 12pm
Is it possible to do the same thing in Yammer?
There are two options available for you:
1 - You can create a new user on Yammer, name it however you want (e.g., "Defect Management System" with a snazzy avatar), then take the user's OAUTH token and use it to impersonate that user programmatically. This is fine for quick development.
2 - You can create a new user on Yammer, name it however you want, then register a new app on Yammer to get a permanent token and client ID, then use those to impersonate that user programmatically. This is the right way to do it. You can read more about how to do this on https://developer.yammer.com/introduction/#gs-registerapp.
This is an example of a user that we impersonate. It is a bot on our network. It is a separate account in AD and is registered as an app in Yammer and interacts with Yammer automatically.
You are always impersonating a user in Yammer via the API, there isn't a way to impersonate a group, in the way that Slack does (i.e. being able to override the username displayed and replace it with a bot for example in your payload)
If this app is for internal use, you could consider creating a dummy user as a bot to post defects, and then using Custom Object Types & Actions in Open Graph to further customize the messages. Obviously there are some business & administration considerations in doing that, not just development ones.

Resources