"run as" for AddUserToRole

I have a widget that posts to a web service, and if the web service call succeeds, I want to then call $core_v2_roleUsers.AddUserToRole to add the user to the role returned by the web service. The problem is that the user making the call doesn't have the ability to add themselves (it returns a permission error).

If I call the equivalent from my C# code, will that work? (Phrased another way, does my widget extension run with elevated privileges or does it run as the accessing user)

Is there a better, more idiomatic way to allow users to self-add to a role?

Parents
  • You can't execute widget code as another user, you could do it on the server side using the in-process API, but you need to wrap that call in Apis.Get<IUsers>.RunAsUser(...)

    community.telligent.com/.../users-in-process-api-service

  • I'm assuming this hasn't changed in v11 or v12? I.e. we can't run any script APIs as a different user & need to do a widget extension in C#?

  • From what I've seen this is correct.  Only possible workaround is via the use of Automations...you can execute the script as the user that triggers the automation or the service account which could bypass some security.  So if you can extract your logic from a traditional widget and make it work within an automation which is triggered by a platform event or on an interval it might work.

    For a work-around you could maybe make your web service call and if it is successful, update a bit on the user profile extended attributes.  Create an automation that runs on a user update event and check that flag - if it exists, you can add them to the group if you execute the automation as the service account then reset the flag.

  • Thanks for the ideas Slight smile (and confirming that there's no way to do this in Velocity).

    I've been having a go coding this up as a widget extension in C# and have had some luck. Here's some code in case anyone else is trying to do this & wants a head start;

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Diagnostics;
    using System.Linq;
    using Telligent.Evolution.Caching.Services;
    using Telligent.Evolution.Components;
    using Telligent.Evolution.Extensibility;
    using Telligent.Evolution.Extensibility.Api;
    using Telligent.Evolution.Extensibility.Api.Version1;
    using Telligent.Evolution.Extensibility.Version1;
    
    namespace My.Utilities
    {
    	[Documentation(Category = "MyStuff")]
    
    	public class UtilsAPI : IApi
    	{
    		public Telligent.Evolution.Extensibility.Api.Entities.Version1.SearchResults searchResultsList(IDictionary options)
            {
    			Telligent.Evolution.Extensibility.Api.Entities.Version1.SearchResults results = null;
    
    			Apis.Get<IUsers>().RunAsUser("admin", () =>
    			{
    				SearchResultsListOptions searchOptions = new SearchResultsListOptions();
    				
    				// Ideally need a nice way to covert 'IDictionary options' (coming in from Velocity) into 'SearchResultsListOptions searchOptions'..
    				// This gets to be a long messy list the more options you want to expose. Is there a better way to do this?
    				searchOptions.Query = (string)options["Query"];
    				searchOptions.ContainerId = (Guid)options["ContainerId"];
    				// ..... There are loads more options you could set!! :(
    
    				results = Apis.Get<ISearchResults>().List(searchOptions);
    			});
    
    			return results;
    		}
    	}
    }

    This seems to work, but the way it deals with all the options for the List operation isn't ideal. Is there a better way to do this?

  • Why do you need to search as an admin?  I thought your question was about adding someone to a role? 

    On a side note,
    You probably will want to check for nulls or if your key exists before trying to access the IDictionary option - those parameters are optional and no guarantee they will be passed to your method which could result in null reference exceptions.

  • Oh, no.. my use case is different from the OP that gregg made Slight smile I need to surface some results in a widget from a non-public group.

    Yeah, using IDictionary is a pain for retrieving the options. Especially since there are potentially loads of them for .List.. is there a better way to do this?

  • Oh, I see.  I have not found an easier way to do this and I usually end up checking each option that I need to access...

  • Okay, cool. Thanks for confirming Slight smile It'd be nice if there was an easier way to do this from Velocity.. maybe I'll post that as an idea in the customer area. It's a tricky one; I guess it would allow anyone with widget authoring access to run anything with escalated privs, which might not be good for some communities.

  • Maybe if the logic was contained in a .vm file, there could be a setting on the .vm file itself to change the RunAs/Executed as User

Reply Children