/// <summary> /// Validate method to attempt to connect to CRM with supplied username/password and then execute a whoami request /// </summary> /// <param name="username">crm username</param> /// <param name="password">crm password</param> public override void Validate(string username, string password) { //get the httpcontext so we can store the user guid for impersonation later HttpContext context = HttpContext.Current; //if username or password are null, obvs we can't continue if (null == username || null == password) { throw new ArgumentNullException(); } //get the crm connection Microsoft.Xrm.Client.CrmConnection connection = CrmUtils.GetCrmConnection(username, password); //try the whoami request //if it fails (user can't be authenticated, is disabled, etc.), the client will get a soap fault message using (OrganizationService service = new OrganizationService(connection)) { try { WhoAmIRequest req = new WhoAmIRequest(); WhoAmIResponse resp = (WhoAmIResponse)service.Execute(req); Entity systemuser = CrmUtils.GetSystemUser(resp.UserId, service); CrmIdentity crmIdentity = new CrmIdentity(); crmIdentity.Name = (string)systemuser["fullname"]; crmIdentity.FirstName = (string)systemuser["firstname"]; crmIdentity.LastName = (string)systemuser["lastname"]; crmIdentity.Email = (string)systemuser["internalemailaddress"]; crmIdentity.UserId = resp.UserId; crmIdentity.SetAuthenticated(true); List <string> roles = CrmUtils.GetUserRoles(resp.UserId, service); foreach (string role in roles) { crmIdentity.AddRole(role); } context.User = new GenericPrincipal(crmIdentity, roles.ToArray()); } catch (System.ServiceModel.Security.MessageSecurityException ex) { throw new FaultException(ex.Message); } catch (Exception ex) { throw new FaultException(ex.Message); } } }
/// <summary> /// This method runs the query and returns the results to the client /// </summary> /// <param name="query">Name of the query. Corresponding file will be named "query".xml</param> /// <param name="inputParameters">Array of parameters for substitution in the query.</param> /// <returns></returns> public List <List <ParameterItem> > Retrieve(string query, List <ParameterItem> inputParameters) { //need to get the id of the user to impersonate from the HttpContext.User object HttpContext context = HttpContext.Current; Guid runasuser = Guid.Empty; //get a reference to the custom CRM identity object CrmIdentity crmIdentity = (CrmIdentity)context.User.Identity; if (context != null) { //if we're to this point, this value should be populated. if not, we'll see an error later when we try to use a blank id runasuser = crmIdentity.UserId; } //instantiate the output object List <List <ParameterItem> > output = new List <List <ParameterItem> >(); //get a connection to crm Microsoft.Xrm.Client.CrmConnection connection = CrmUtils.GetCrmConnection(); //set callerid for impersonation connection.CallerId = runasuser; //execute the query, loop through results, format output, etc. using (OrganizationService service = new OrganizationService(connection)) { //code to show impersonated user details - can leave commented out in prod //List<ParameterItem> runasitem = new List<ParameterItem>(); //runasitem.Add(new ParameterItem { Name = "runasuser", Value = runasuser }); //runasitem.Add(new ParameterItem { Name = "roles", Value = context.User.IsInRole("sales manager").ToString() }); //output.Add(runasitem); //prepare a query to retrieve the wrapper query record from crm string wrapperQueryFetch = @"<fetch distinct='false' mapping='logical' output-format='xml-platform' version='1.0'> <entity name='la_wrapperquery'> <attribute name='la_wrapperqueryid'/> <attribute name='la_name'/> <attribute name='la_query'/> <order descending='false' attribute='la_name'/> <filter type='and'> <condition attribute='statuscode' value='1' operator='eq'/> <condition attribute='la_name' value='{$queryname}' operator='eq'/> </filter> </entity> </fetch>"; wrapperQueryFetch = wrapperQueryFetch.Replace("{$queryname}", query); //retrieve the wrapper query record EntityCollection wrapperQueryCollection = service.RetrieveMultiple(new FetchExpression(wrapperQueryFetch)); if (wrapperQueryCollection.Entities.Count == 1) { Entity wrapperQuery = wrapperQueryCollection.Entities[0]; //prepare the wrapper query by doing any necessary parameter substitutions string fetchXml = PrepareFetchQuery((string)wrapperQuery["la_query"], inputParameters); //execute the actual query EntityCollection results = service.RetrieveMultiple(new FetchExpression(fetchXml)); foreach (Entity entity in results.Entities) { //loop through the mapping key-value pairs List <ParameterItem> item = new List <ParameterItem>(); foreach (var attribute in entity.Attributes) { item.Add(new ParameterItem { Name = attribute.Key, Value = CrmUtils.GetAttributeValue(attribute.Value) }); //the _name and _type fields do some user-friendly formatting string attributelabel = (string)CrmUtils.GetAttributeName(attribute.Value); if (attributelabel != "") { item.Add(new ParameterItem { Name = attribute.Key + "_name", Value = attributelabel }); } string attributeentitytype = (string)CrmUtils.GetAttributeEntityType(attribute.Value); if (attributeentitytype != "") { item.Add(new ParameterItem { Name = attribute.Key + "_type", Value = attributeentitytype }); } } //optionset labels and formatted currency values are available in the formattedvalues collection foreach (var fv in entity.FormattedValues) { item.Add(new ParameterItem { Name = fv.Key + "_formattedvalue", Value = fv.Value }); } output.Add(item); } } else { throw new Exception("Could not find active query with the supplied name."); } return(output); } }