Looping Through Content in a SharePoint 2013 Site Workflow – Part 2 – Setting Up App Permissions

Site Workflows are great, but if you want them to reach across into other sites you’ll probably have permission issues. By giving these workflows App Permissions, you’ll be able to let your workflow access content across your Site Collection.

Add XML

In part one of this series I described the basic task we’re trying to solve. We want to create a SharePoint 2013 site workflow that can iterate through subsites and then take some actions on each item that meets some criteria. At the end of that article, I said that the first step is that we’ll set up the workflow with proper permissions so it can traverse content across the Site Collection. So now you’re thinking, “Great. The problem is defined. Let’s pop over to SharePoint Designer and create a workflow.” Unfortunately, that isn’t the right thing to do. I know because I tried that, and I’m writing this series to pass on the lessons learned.

Before we can even think about writing the workflow, we should set up the authorization side of things. It wasn’t enough to get the digest token from the server for the REST calls. (More on this later.) When I tried to make the REST calls I needed from one subsite into the root of the Site Collection or another subsite, I got authorization errors.

Instead, there’s more heavy-duty permissions set up required to make the REST calls into other Webs (sites to normal people). We need to give our workflow App Permission, which isn’t obvious as you’re working on the workflow in SharePoint Designer (SPD), nor is it possible to do so in SPD.

Luckily I have good friends in the community. Matt Bramer (@ionline247) was the first person who replied to one of my tweets, and he gave me some good tips. Through him I found that Fabian Williams (@fabianwilliams) had written several blog posts about the trials and tribulations he went through so that I  wouldn’t have to. (I added links to Fabian’s blogs at the end of this article.) But setting up workflow App Permission is still confusing, in my opinion.

You’ll go through two two main steps to set these permissions. I found the steps generally documented in the MSDN article, Create a workflow with elevated permissions by using the SharePoint 2013 Workflow platform, but here’s my version.

Step 1 – Allow the workflow to use app permissions

Go to Site Settings in the site where you want the workflow to run and turn on the Workflows can use app permissions feature. You can do this by going to Site Settings and in the Site Actions section, choose Manage Site Features. Toward the bottom of the list of available features, you’ll see Workflows can use app permissions. To activate it, (figure 2) simply click the Activate button and wait for the activation to complete.

Workflows can use app permissions

Figure 2: In Site Settings / Site Actions / Manage Site Features you need to Activate the feature to allow workflows to read from and write to all items in the site.

Step 2 – Grant full control permission to a workflow

This step gets pretty weird. We have to give this workflow the permissions to run as if it’s an app add-in. (Though one might say that it’s an app add-in already – everything is an app add-in, right?)

In the site where you want the workflow to run, navigate to Site Settings and then under Users and Permissions, go to Site app permissions. If things have gone according to plan, you should see Workflow as one of the two or more items listed here.

What you want to grab is the yellow text in figure 3. It follows a bar character – “|” – and precedes an “@” character. I’m not sure exactly where this GUID comes from, but it’s what you need.

2016-01-12_11-05-44

Figure 3: Copy part of the Workflow App Identifier

Now you have to navigate to a hidden, super-secret page at:

http://yourtenant/sites/yoursitecollection/_layouts/15/appinv.aspx

In the example on MSDN, they send you off to the /sites/AppCatalog Site Collection for this. That’s only because they are showing an example interacting with a list there. You should go to the secret page in the Site Collection where you want the workflow to run. (Yes, I was down a rat hole on this for a while. Maybe I was just being stupid. It seemed like the good folks who wrote the MSDN article were telling me I needed to give permissions on the App Catalog site for this to work – but that wasn’t the case.)

The should look something like figure 4. The page doesn’t have a title like most SharePoint pages (hey, it’s super-secret), but the hover text for the info icon at the top of the page says “Grant permission to an app.”

Set the app permissions

Figure 4: You’ll paste the Workflow App Identifier into the Add Id field on the secret page.

Now as you can see in figure 5, you paste in the yellow text from above, and click the Lookup button. The next three fields will be filled in. You shouldn’t need to change anything in those fields.

Paste in the App ID

Figure 5: Paste in the App Id that you copied from the workflow in Site app permissions (figure 3).

Next, you need to paste some XML into the last field called Permission Request XML. Don’t try to get all smart about it like I did: paste in EXACTLY this XML— don’t make any changes.

You have two options here (the first option adds /web in line three) and I’ll explain the difference below the XML snippet:

<AppPermissionRequests>
  <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web" Right="FullControl" />
</AppPermissionRequests>

…or…

<AppPermissionRequests>
  <AppPermissionRequest Scope="http://sharepoint/content/sitecollection" Right="FullControl" />
</AppPermissionRequests>

In this case, I went with the latter; I want my workflow to have permissions on the entire Site Collection. The former would give my workflow permissions only in the subsites of the Site Collection; I needed permission on the root of the Site Collection because I wanted to iterate through the subwebs (subsites) from there. So with both the App Id and the XML pasted, the app identity and permission look like figure 6.

Add XML

Figure 6: We’ve identified the workflow’s app’s identity and indicated where it has permissions to be used.

Click Create.

Next you’ll be asked if you trust the workflow. One would think this would be a given, but click Trust It.

 Site App Permissions

At this point, you have the permissions set up that give you the possibility of looping through the subsites off the root, even though you haven’t created an actual workflow yet. (Or, if you’re like me, you beat your head against the workflow first and then realized you had to figure this part out.)

In the next article, we’ll talk through what the workflow needs to do on a high level to be useful.

References for this step

This article was also published on IT Unity on 1/25/2016. Visit the post there to read additional comments.

Looping Through Content in a SharePoint 2013 Site Workflow – Part 1 – Introduction

Site Workflows let us run logic independent of lists and libraries. By combining them with REST calls, we can traverse a Site Collection and process multiple lists and their contents by looping though them when we want. In this article, part 1 of the series, we’ll describe the problem we are trying to solve, but the solution can apply to many SharePoint scenarios.

SharePoint 2013 Site Workflow

As with most things SharePoint, setting up a workflow to loop through items across subsites seems like it should be easier. What I was trying to do seemed like a common requirement: get some data from lists in SharePoint subsites and loop through it, taking some actions on each item that meets some criteria.

I’ll warn you that this series of articles is not for the faint of heart, the new-to-workflow initiate, or the person without a lot of permissions. My solution involves reaching into Office 365’s workflow guts a bit here.

In my current case, I’m building an opportunity management solution for a sales organization. Each sales partner – these are outside companies – will have a subsite only they can access where they will enter sales opportunities as they arise. The sales folks for the host company want to be able to manage that “basket” of opportunities as well as send out emails to the partners as the opportunities move through various stages in a process. We won’t cover all of the possible permutations here as I want to focus more on the chassis of the workflow.

I need to check a specific list in a bunch of subsites for new items and send an email about each. I don’t want to create a separate List Workflow that sits in each of the lists because it would be an administrative nightmare to change the workflow down the road (we have over a dozen subsites, and the number will grow). Instead, I want to create one central SharePoint 2013 Site Workflow that finds all the subsites, finds the list in each subsite (if it exists), and iterates through the items in the list, taking different actions based on the data in each item. We’ll set this workflow to run every x minutes (probably once an hour or once a day) by adding a wait state at the end of processing.

You could accomplish this with “code” or Powershell, but that takes it out of the hands of the Site Admin who might want to change things down the road. By using a workflow, we can give them some control over things like the text of the emails without making them learn how to code to change them. As a consultant, I want to be able to leave my client with a solution they can maintain on their own as much as possible. They can still call me for the heavy lifting, but most changes should be something they can handle themselves.

On Office 365 in SharePoint Online, this feels a LOT trickier than it may have been in the past because of the complexity (nay, swamp) of authorization we must navigate. I expect that similar authentication issues may apply on premises, too, but Office 365 is more of a moving target.

In this series of articles, I’ll show you the steps I went through and let you know where I got stuck, waylaid, and confused. I believe that only one of us should have to suffer through this stuff so that everyone else can avoid it.

We’ll go through the overall concept of how the process works, as well as:

  • Setting up the workflow with the proper permissions so it can traverse content across the Site Collection
  • Initializing the workflow based on values stored in a user-maintainable list
  • Making the REST calls to discover all of the existing subsites without having to hard-wire where they are
  • Parsing the data returned from each REST call
  • Discovering whether each subsite contains the list we are looking for
  • Processing the items in each list based on a set of criteria that can change over time
  • Sending out emails appropriate for each set of criteria

This isn’t totally new ground; there are many blog posts out there that cover bits and pieces of this, and I’ll provide the links I found helpful and give credit where credit is due. I didn’t find anything that showed me how it all worked together, though.

Thanks right off the bat to Matt Bramer (@ionline247) and Fabian Williams (@fabianwilliams) for getting me up and rolling when I first start whining about this on Twitter.

This article was also published on IT Unity on 1/19/2016. Visit the post there to read additional comments.

SPServices into 2016!

SPServicesOver the break, I managed to get SPServices up and running on GitHub. You may wonder what that means and why it matters.

When I started moving SPServices away from Codeplex, it was due to several things:

  • Codeplex seems to be dying a whimpering death. Microsoft is clearly not maintaining it anymore, and its tech is falling behind – when it works.
  • I wanted to understand GitHub better. I’ve had to get too much help from my friends in the SharePoint community even just to push changes to cdnjs. Thanks Josh McCarty (@joshmcrty)!

So, mission accomplished on those goals – but it took me an embarrassingly long time to get here!

Of course, in the process I also wanted to improve SPServices. Here is what I am/was aiming at:

  • The next version will be SPServices 2.0 – This is just a number, and the current builds have this number already.
  • Make it (already is!) AMD-enabled using RequireJS
  • Convert from a monolithic file to modules (done, though perhaps more to do)
  • Enabled to take advantage of SharePoint’s REST APIs – where available – for internal calls to get list data in the value-added functions (still to do)

As you can see, I’m well on the way to meet my self-imposed goals; I think the hard work is behind me.

There are some other goals and here’s where you can help:

  • Test the “pre-alpha” builds of SPServices 2.0. If you’re familiar enough with the library to drop builds into your test environments, that would be a great help. I’ve tested using the same lists and pages I always use, but more real-world testing would be good. Report any issues you find using GitHub issues.
  • Write some tests. I’ve started writing tests with QUnit, but I’ve only scratched the surface. Writing good tests here is difficult, as we have to be sitting on top of SharePoint; in greenfield development, we can test anywhere. You’ll find some instructions for how to use the existing tests on the GitHub pages.
  • Migrate the documentation from Codeplex to GitHub – Since Codeplex is falling apart, there’s no reason to leave the documentation there, either. There are a few dozen pages (I can’t actually count the pages on Codeplex easily) of documentation, and it’s probably easiest just to move the over to GitHub manually.
  • Move the discussions off Codeplex – This one is hardest, I think. IMO, one of the big values to SPServices is the historical discussions about how to use it. But those discussions have covered many other things as well, and I’d hate to lose any of it. I’m not sure how to go about this, so if anyone has some experience moving forums like this, I’m all ears.
  • Propose improvements – I ask the community for suggestions all the time, but I don’t get a lot of them. If you’ve solved some gnarly SharePoint UI problem and would be willing to submit your code or just wish that someone would fix the darn _____, then let me know in the GitHub issues. Consider the issues our own UserVoice for SPServices.

A HUGE thank you goes out to Paul Tavares (@paul_tavares) for guiding me along this move to GitHub. He’s written most of the build code, the test chassis, etc. I couldn’t have done it without him. If you don’t know Paul, he’s one of the sharper tacks in the SharePoint community, and he only does SharePoint work on the side these days. Take a look at his SPWidgets project. I promise you – you’ll be impressed.

Thanks also to the folks over at BitHound for their code tools. If you check out the dashboard for SPServices, you’ll see that I’m doing OK, but there’s always room for improvement.

Happy 2016 to all of you, and happy coding!

An Unpleasant Refiner Bug in SharePoint Online

As always, I don’t know where to report issues with Office 365. So here I am carping in a public channel in the hopes that the right person sees it. This also may happen with SharePoint 2013 on premises, but I can’t recall.

Unpleasant SharePoint search refinerWhen I use a refiner that is based on a Lookup column, I’ll often see something like the attached image. As you can see, there are two clients listed: Anchor Glass and 29. Anchor Glass is the title of the item in the Clients list with the ID of 29, but it still doesn’t make sense (especially to those poor users). It’s as if the indexer isn’t smart enough to handle Lookup columns properly – but only some of the time.

This happens on multiple tenants, with different Lookup columns to different lists, but not consistently, or in any pattern I’ve been able to discern. Generally it’s the Title column we’re looking up into. Using a Lookup column into a list is almost always preferable to using Managed Metadata (IMO) because we can store additional data about the values in the list. For instance, in the Clients list above, we have the client contact info, who works with the client, when we started working with them, what the billings are, etc. Managed Metadata is worthless for that.

But the bug.

Has anyone else seen this? Any ideas on how to work around it?

SharePoint Online Search: Add a Refiner for Content Type

2015-12-21_14-00-52This is yet another in the “Things that Make You Go Hmm…” category. If I only had a nickel…

I would think that one of the most common needs on a search results page would be to add a refiner by Content Type. After all, we all have robust, sensical information architectures in place to improve performance in our organizations, right?

When we create a new search results page in a Search Center, we get a few refiners out of the box that look oh-so-promising.

First there’s ContentTypeId. We all know that Microsoft uses big, ugly ids and GUIDs under the covers all the time. Sometimes they translate easily into whatever they represent. This isn’t one of those times.

2015-12-21_13-37-48

Well, what about contentclass? That looks sort of almost useful. But it isn’t. Values like STS_ListItem_DocumentLibrary won’t really help anyone.

2015-12-21_13-37-35

Oh, I know. Let’s add the ContentType Managed Property. That’s what works almost everywhere else. Well, except here, as the values don’t make sense to humans, as they are things like application/pdf Document or application/vnd.openxmlformats-officedocument.presentationml.pres… Yes, the ellipses are appropriate here. Who know what that means?

2015-12-21_13-38-05

Finally, I found a blog post from Henri Merkesdal that retrieved my sanity. There’s a property way down the list called SPContentType that does exactly what we want.
2015-12-21_13-38-20

Ahhh. That’s much better. Thanks, Henri!

2015-12-21_14-00-52