Planner Application permissions - what does it mean?
Table of Contents
The why
Planner is one of those products that are really awesome, but it is also very hard to keep structured due to the lack of templating/automation around it, this leaves every Planner board at the mercy of users reproducing an existing setup again, and again … that’s not going to happen.
The what
So, what does application permissions for Planner mean? - well essentially it means that we can now access Planner from automated code, this makes things like provisioning Planner boards possible.
So, what can we use it for? - well essentially we can do anything you normally can do in Planner, but automated!
For instance, a thing I often meet in the market is people who’re used to Trello but want to migrate to Planner, not only can we now actually migrate their existing tasks to Planner without every task being created by a service account, we can also automate certain tasks, or pull data for better reporting, and all pretty simple.
Real life business cases
In the half a month or so this API has been available I’ve already used it a few times to do some cool stuff, here are some real-life ideas that can be implemented.
Provisioning tasks
Some business scenarios have us provisioning teams or sites for every project in the organization, this is nothing new, but what we’re now able to do that is new is provisioning and assigning tasks upon project creation - and even project phase changes, I’ve implemented this combined with a stage-gate model where users cannot change the project phase without having completed all the tasks in the current phase, and then when they move to the next phase new tasks are created fully automatically, also tasks are dynamically assigned based on your role in the project.
Connecting tasks to Outlook events
An other use case that I found really interesting was a client who has 600+ meetings a year, had a hard time keeping up on pre and post meeting tasks, they had tried Planner, but found it hard to keep things in sync when a meeting moved date suddenly you have to remember to move the tasks in Planner as well, otherwise your to to-do would remind you to “send out meeting summary” for a meeting you haven’t yet had.
So, I built a relatively simple job that’ll generate a few tasks in Planner for each meeting in a specific calendar and move them with the meeting in Outlook keeping it very simple to keep on top of your meetings and tasks that go along with them.
The how
Microsoft introduced a new permissions scope Tasks.ReadWrite.All unfortunately there’s currently no way to limit this down to a single group/board at this time, maybe we’ll see that down the line, just like we did with the SharePoint application permissions, maybe even a read-only permission for reporting reasons.
So, once you’ve granted yourself this magical new permission what’s next?
Well because this API has been supported for a while using delegated permissions it’s already in all the SDKs, so simply authenticate with your app-registration and start using the API
Here is an example using the GraphServiceClient in C#
PlannerTask plannerTask = new PlannerTask
{
PlanId = Desired_Plan_Id,
BucketId = Desired_Bucket_Id,
Title = "Create my first task via the API",
Assignments = new PlannerAssignments
{
AdditionalData = new Dictionary<string, object>()
{
{AAD_Object_Id_of_user_to_assign, "{\"@odata.type\":\"#microsoft.graph.plannerAssignment\",\"orderHint\":\" !\"}"}
}
}
};
await Graph.Planner.Tasks.Request().AddAsync(plannerTask);
Quirks
There were a few things that I had to wrap my head around, at least with the C# SDK, which is the main way I’ve been integrating with the new permissions.
Task assignments
First off, why are user assignments so hard! - Why do I need to remember the JSON parameter in order to assign a task! - this should really just be handled by the SDK where I just provide a list of user IDs, I get that it’s stored like this in the backend, but I don’t need to see it on the dev side.
{"@odata.type":"#microsoft.graph.plannerAssignment","orderHint":" !"}
The API structure
Another one of those where the Planner API is not structured hierarchically like (at least I) expected.
This means that you go.
await Graph.Planner.Buckets[BUCKET_ID].Tasks().Request().GetAsync();
and not hierarchically like we’re used to from other Graph endpoints, or SharePoint which would be more like:
await Graph.Planner.Plans[PLAN_ID].Buckets[BUCKET_ID].Tasks[TASK_ID].Request().GetAsync();
E-tag
Another thing I’ve found which feels like one of those growing pains where it becomes obvious that the C# SDK at least hasn’t been used widely for Planner compared to things like PnPjs which supports the delegated permissions and has been widely used for years is the E-tag property you need to grab when you’re updating the task you’ve just created.
Not only to you need to grab it from the AdditionalData you also need to strip off the first two characters, this hopefully will be handled by the SDK at some point.
PlannerTask PlannerTask = await Graph.Planner.Tasks.Request().AddAsync(plannerTask);
//We have to remove the 'W/' at the beginning of the E-Tag
//https://powerusers.microsoft.com/t5/Using-Connectors/Custom-Connector-Graph-The-If-Match-header-must-be-specified-for/m-p/144099#M3314
string ETAG = PlannerTask.AdditionalData.TryGet("@odata.etag") + "").Substring(2);
await Graph.Planner.Tasks[PlannerTask.Id].Request().Header("If-Match", ETAG).UpdateAsync(new PlannerTask() { Title = UPDATE_TITLE });
Other SDKs like PnPjs handles this smoother, that makes it obvious to the developer that you need to provide an etag
const UpdatedTask = await graph.planner.tasks.getById(TASK_ID).update({properties, eTag: ETAG});
TL;DR
The Application permissions have finally landed, and they’re awesome!
I’ve played with the C# Graph SDK and it works great, there are a few quirks that need some ironing out before it’s intuitive, Microsoft should really look towards the community and PnPjs for some inspiration on how to handle certain things more intuitively - but they’re here, and they work
Bonus tip: what does application permissions mean?
This is one of those places where we as dev sometimes take things for granted, and assume that everyone knows what things are, but the essence is that application permissions is the way our code can authenticate without a user being present - where as delegated permissions are the ones where we extend the currently signed in user.