/// <summary> /// Retrieves an authorization token from the server /// </summary> /// <param name="portalUrl">URL of the Cireson Portal</param> /// <param name="userName">User name</param> /// <param name="password">User's password</param> /// <param name="languageCode">Portal language code</param> /// <exception cref="System.Security.Authentication.InvalidCredentialException">Thrown when user credentials are invalid.</exception> /// <exception cref="CiresonPortalAPI.CiresonApiException">Thrown when an error occurs in the API.</exception> /// <returns></returns> public static async Task<AuthorizationToken> GetAuthorizationToken(string portalUrl, string userName, SecureString password, string domain, string languageCode = "ENU") { try { // First check to see if we have Windows Authentication enabled bool windowsAuthEnabled = await DetectWindowsAuthentication(portalUrl); // Set up credentials PortalCredentials credentials = new PortalCredentials(); credentials.Username = userName; credentials.SecurePassword = password; credentials.Domain = domain; // Initialize the HTTP helper and do the heavy lifting PortalHttpHelper helper = new PortalHttpHelper(portalUrl, credentials, windowsAuthEnabled); string result = await helper.PostAsync(AUTHORIZATION_ENDPOINT, JsonConvert.SerializeObject(new { UserName = credentials.Username, Password = credentials.Password, LanguageCode = languageCode })); // Strip off beginning and ending quotes result = result.TrimStart('\"').TrimEnd('\"'); // Create a new authorization token AuthorizationToken token = new AuthorizationToken(portalUrl, credentials, languageCode, result, windowsAuthEnabled); // Fetch this user's properties ConsoleUser user = await AuthorizationController.GetUserRights(token, userName, domain); token.User = user; return token; } catch { throw; // Rethrow exceptions } }
/// <summary> /// Fetches a list of enumerations from the server /// </summary> /// <param name="authToken">Authorization token</param> /// <param name="enumList">Enumeration list to fetch</param> /// <param name="flatten">If true, flatten the entire enumeration tree into one list; if false, only return the first-level items</param> /// <param name="sort">If true, sorts the list before returning it</param> /// <param name="insertNullItem">If true, add a null item to the list as the first item</param> /// <returns></returns> /// public static async Task<List<Enumeration>> GetEnumerationList(AuthorizationToken authToken, Guid enumList, bool flatten, bool sort, bool insertNullItem) { if (!authToken.IsValid) { throw new InvalidCredentialException("AuthorizationToken is not valid."); } string endpoint = (flatten ? LIST_ENDPOINT_FLAT : LIST_ENDPOINT_TREE); endpoint += "/" + enumList.ToString() + "/" + (flatten ? "?itemFilter=" : ""); try { // Initialize the HTTP helper and get going PortalHttpHelper helper = new PortalHttpHelper(authToken); string result = await helper.GetAsync(endpoint); List<Enumeration> returnList = new List<Enumeration>(); if (flatten) { // A flat enumeration list has null Ordinals, so we use the base EnumJson class List<EnumJson> jEnumList = JsonConvert.DeserializeObject<List<EnumJson>>(result); foreach (var jEnum in jEnumList) { // Skip empty enumerations if (jEnum.ID != Guid.Empty.ToString()) returnList.Add(new Enumeration(new Guid(jEnum.ID), jEnum.Text, jEnum.Name, flatten, jEnum.HasChildren)); } } else { // A non-flat enumeration list has non-null Ordinals, so we have to use a different conversion class List<EnumJsonOrdinal> jEnumList = JsonConvert.DeserializeObject<List<EnumJsonOrdinal>>(result); foreach (var jEnum in jEnumList) { // Skip empty enumerations if (jEnum.ID != Guid.Empty.ToString()) returnList.Add(new Enumeration(new Guid(jEnum.ID), jEnum.Text, jEnum.Name, flatten, jEnum.HasChildren, jEnum.Ordinal)); } } if (sort) { returnList.Sort(new EnumerationComparer()); } if (insertNullItem) { returnList.Insert(0, new Enumeration(Guid.Empty, string.Empty, string.Empty, true, false)); } return returnList; } catch (Exception e) { throw; // Rethrow exceptions } }
/// <summary> /// Overloaded constructor with an Authorization header; suitable for connecting to endpoints other than /Authorization/GetToken /// </summary> /// <param name="authToken">AuthorizationToken object</param> /// <exception cref="CiresonPortalAPI.CiresonApiException"></exception> public PortalHttpHelper(AuthorizationToken authToken) : this(authToken.PortalUrl, authToken.Credentials, authToken.WindowsAuthEnabled) { if (!authToken.IsValid) { throw new CiresonApiException("Authorization token is not valid."); } _oHttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Token", authToken.Token); }
/// <summary> /// Attempts to commit the type projection to the portal. Throws an exception if not successful. /// </summary> /// <param name="authToken">AuthorizationToken to use</param> public async virtual Task <bool> Commit(AuthorizationToken authToken) { if (this.ReadOnly) { throw new CiresonApiException("Cannot commit a read-only type projection."); } if (!authToken.IsValid) { throw new InvalidCredentialException("AuthorizationToken is not valid."); } if (!this.IsDirty) { throw new CiresonApiException("Object is not dirty, Commit() aborted."); } // Every object needs a DisplayName set if (string.IsNullOrEmpty(this.DisplayName)) { this.DisplayName = this.DefaultDisplayName; } try { string jsonObj = this.Serialize(); // Initialize the HTTP helper and get going PortalHttpHelper helper = new PortalHttpHelper(authToken); string result = await helper.PostAsync(COMMIT_ENDPOINT, jsonObj); // Retrieve the result ExpandoObjectConverter converter = new ExpandoObjectConverter(); dynamic resultObj = JsonConvert.DeserializeObject <ExpandoObject>(result, converter); // Throw an exception if we didn't succeed if (!resultObj.success) { throw new CiresonApiException(resultObj.exception); } // Refresh object data from the server await this.Refresh(authToken); } catch (Exception) { throw; // Rethrow exceptions } return(true); }
/// <summary> /// Creates a new TypeProjection of derived type T and returns it /// </summary> /// <typeparam name="T">TypeProjection derived type</typeparam> /// <param name="authToken">AuthorizationToken to use</param> /// <returns></returns> internal static async Task <T> CreateBlankObject <T>(AuthorizationToken authToken, string name, string displayName, dynamic objProps = null) where T : TypeProjection { // See if we have a CI matching this name first T item = await GetByFullName <T>(authToken, name); if (item != null) { string fullName = ClassConstants.GetClassNameByType <T>() + ":" + name; throw new CiresonDuplicateItemException("An object by the name " + fullName + " already exists."); } // Setup the CI dynamic ci = new ExpandoObject(); ci.formJson = new ExpandoObject(); ci.formJson.isDirty = true; ci.formJson.original = null; ci.formJson.current = new ExpandoObject(); ci.formJson.current.BaseId = null; ci.formJson.current.ClassTypeId = ClassConstants.GetClassIdByType <T>(); ci.formJson.current.ClassName = ClassConstants.GetClassNameByType <T>(); ci.formJson.current.Name = name; ci.formJson.current.DisplayName = displayName; ci.formJson.current.TimeAdded = "0001-01-01T00:00:00"; //ci.formJson.current.ObjectStatus = new ExpandoObject(); //ci.formJson.current.ObjectStatus.Id = EnumerationConstants.TypeProjection.BuiltinValues.ObjectStatus.Active; // Merge another property object in if (objProps != null) { IDictionary <string, object> ciDict = (IDictionary <string, object>)ci.formJson.current; foreach (var property in objProps.GetType().GetProperties()) { if (property.CanRead) { ciDict[property.Name] = property.GetValue(objProps); } } } // Create the new TypeProjection, then return the full-property object T newCI = await CreateObjectFromData <T>(authToken, ci); return(await GetByBaseId <T>(authToken, newCI.BaseId)); }
/// <summary> /// Refreshes a TypeProjection from the database /// </summary> /// <typeparam name="T">TypeProjection derived type to refresh</typeparam> /// <param name="authToken">AuthorizationToken to use</param> /// <returns></returns> protected async Task <bool> RefreshType <T>(AuthorizationToken authToken) where T : TypeProjection { TypeProjection p = await TypeProjectionController.GetByBaseId <T>(authToken, this.BaseId); if (p == null) { return(false); } this.CurrentObject = (p.CurrentObject as ExpandoObject).DeepCopy(); this.OriginalObject = p.OriginalObject; this.ReadOnly = p.ReadOnly; this.IsDirty = false; return(true); }
/// <summary> /// Creates an object projection using the specified data. /// </summary> /// <typeparam name="T">Type of projection to create</typeparam> /// <param name="authToken">AuthorizationToken to use</param> /// <param name="data">Data object to specify for creation</param> /// <param name="readOnly">Should this projection be read only?</param> /// <returns></returns> private static async Task <T> CreateObjectFromData <T>(AuthorizationToken authToken, dynamic data, bool readOnly = false) where T : TypeProjection { if (!authToken.IsValid) { throw new InvalidCredentialException("AuthorizationToken is not valid."); } try { string jsonObj = JsonConvert.SerializeObject(data); // Initialize the HTTP helper and get going PortalHttpHelper helper = new PortalHttpHelper(authToken); string result = await helper.PostAsync(CREATE_PROJECTION_BY_DATA_ENDPOINT, jsonObj); // Retrieve the result ExpandoObjectConverter converter = new ExpandoObjectConverter(); dynamic resultObj = JsonConvert.DeserializeObject <ExpandoObject>(result, converter); // Throw an exception if we didn't succeed if (!resultObj.success) { throw new CiresonApiException(resultObj.exception); } // Fetch the BaseId of the new object and create the projection data.formJson.current.BaseId = new Guid(resultObj.BaseId); // Instantiate BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; CultureInfo culture = null; T instanceType = (T)Activator.CreateInstance(typeof(T), flags, null, null, culture); instanceType.CurrentObject = (data.formJson.current as ExpandoObject).DeepCopy(); instanceType.OriginalObject = data.formJson.current; instanceType.ReadOnly = readOnly; return(instanceType); } catch (Exception) { throw; // Rethrow exceptions } }
/// <summary> /// Queries the Cireson Portal for objects using specified criteria. /// </summary> /// <param name="authToken">AuthenticationToken to use</param> /// <param name="criteria">QueryCriteria rules</param> /// <returns>List of TypeProjections</returns> internal static async Task <List <T> > GetByCriteria <T>(AuthorizationToken authToken, QueryCriteria criteria) where T : TypeProjection { if (!authToken.IsValid) { throw new InvalidCredentialException("AuthorizationToken is not valid."); } try { // Initialize the HTTP helper and get going PortalHttpHelper helper = new PortalHttpHelper(authToken); string result = await helper.PostAsync(GET_BY_CRITERIA_ENDPOINT, criteria.ToString()); // TypeProjections have no set properties, so we deserialize to a list of ExpandoObjects ExpandoObjectConverter converter = new ExpandoObjectConverter(); dynamic objectList = JsonConvert.DeserializeObject <List <ExpandoObject> >(result, converter); // Convert the ExpandoObjects into proper TypeProjection objects List <T> returnList = new List <T>(); foreach (ExpandoObject obj in objectList) { // Instantiate and add to the list BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; CultureInfo culture = null; T instanceType = (T)Activator.CreateInstance(typeof(T), flags, null, null, culture); instanceType.CurrentObject = obj.DeepCopy(); instanceType.OriginalObject = obj; instanceType.ReadOnly = false; returnList.Add(instanceType); } return(returnList); } catch (Exception) { throw; // Rethrow exceptions } }
/// <summary> /// Fetches a list of enumerations from the server /// </summary> /// <param name="authToken">Authorization token</param> /// <param name="enumList">Enumeration list to fetch</param> /// <param name="flatten">If true, flatten the entire enumeration tree into one list; if false, only return the first-level items</param> /// <param name="sort">If true, sorts the list before returning it</param> /// <param name="insertNullItem">If true, add a null item to the list as the first item</param> /// <returns></returns> /// public static async Task <List <Enumeration> > GetEnumerationList(AuthorizationToken authToken, Guid enumList, bool flatten, bool sort, bool insertNullItem) { if (!authToken.IsValid) { throw new InvalidCredentialException("AuthorizationToken is not valid."); } string endpoint = (flatten ? LIST_ENDPOINT_FLAT : LIST_ENDPOINT_TREE); endpoint += "?id=" + enumList.ToString() + (flatten ? "&itemFilter=" : ""); try { // Initialize the HTTP helper and get going PortalHttpHelper helper = new PortalHttpHelper(authToken); string result = await helper.GetAsync(endpoint); List <Enumeration> returnList = new List <Enumeration>(); if (flatten) { // A flat enumeration list has null Ordinals, so we use the base EnumJson class List <EnumJson> jEnumList = JsonConvert.DeserializeObject <List <EnumJson> >(result); foreach (var jEnum in jEnumList) { // Skip empty enumerations if (jEnum.ID != Guid.Empty.ToString()) { returnList.Add(new Enumeration(new Guid(jEnum.ID), jEnum.Text, jEnum.Name, flatten, jEnum.HasChildren)); } } } else { // A non-flat enumeration list has non-null Ordinals, so we have to use a different conversion class List <EnumJsonOrdinal> jEnumList = JsonConvert.DeserializeObject <List <EnumJsonOrdinal> >(result); foreach (var jEnum in jEnumList) { // Skip empty enumerations if (jEnum.ID != Guid.Empty.ToString()) { returnList.Add(new Enumeration(new Guid(jEnum.ID), jEnum.Text, jEnum.Name, flatten, jEnum.HasChildren, jEnum.Ordinal)); } } } if (sort) { returnList.Sort(new EnumerationComparer()); } if (insertNullItem) { returnList.Insert(0, new Enumeration(Guid.Empty, string.Empty, string.Empty, true, false)); } return(returnList); } catch (Exception) { throw; // Rethrow exceptions } }
/// <summary> /// Returns a list of tier queue (support group) enumerations that the specified ConsoleUser is a member of /// </summary> /// <param name="authToken">AuthorizationToken to use</param> /// <param name="user">ConsoleUser token</param> /// <returns></returns> internal static async Task <List <Enumeration> > GetUsersTierQueueEnumerations(AuthorizationToken authToken, ConsoleUser user) { if (!authToken.IsValid) { throw new InvalidCredentialException("AuthorizationToken is not valid."); } string endpointUrl = GET_TIER_QUEUES_ENDPOINT + "?id=" + user.Id.ToString("D"); try { PortalHttpHelper helper = new PortalHttpHelper(authToken); string result = await helper.GetAsync(endpointUrl); dynamic obj = JsonConvert.DeserializeObject <List <ExpandoObject> >(result, new ExpandoObjectConverter()); List <Enumeration> returnList = new List <Enumeration>(); foreach (var enumJson in obj) { returnList.Add(new Enumeration(enumJson.Id, enumJson.Text, enumJson.Name, true, false)); } return(returnList); } catch (Exception) { throw; // Rethrow exceptions } }
/// <summary> /// Convenience method to query the Cireson Portal for the authenticated user's security rights. /// </summary> /// <param name="authToken">AuthorizationToken to use</param> /// <returns></returns> public static async Task <ConsoleUser> GetUserRights(AuthorizationToken authToken) { return(await GetUserRights(authToken, authToken.User.UserName, authToken.User.Domain)); }
/// <summary> /// Queries the Cireson Portal for the specified user's security rights /// </summary> /// <param name="authToken">AuthorizationToken to use</param> /// <param name="userName">User name to query</param> /// <param name="domain">Domain of the user</param> /// <returns></returns> public static async Task<ConsoleUser> GetUserRights(AuthorizationToken authToken, string userName, string domain) { if (!authToken.IsValid) { throw new InvalidCredentialException("AuthorizationToken is not valid."); } string endpointUrl = IS_USER_AUTHORIZED_ENDPOINT + "?userName="******"&domain=" + domain; try { // Initialize the HTTP helper and get going PortalHttpHelper helper = new PortalHttpHelper(authToken); string result = await helper.PostAsync(endpointUrl, String.Empty); // Deserialize the object to an ExpandoObject and return a ConsoleUser ExpandoObjectConverter converter = new ExpandoObjectConverter(); dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(result, converter); ConsoleUser returnObj = new ConsoleUser(obj); returnObj.IncidentSupportGroups = await GetUsersTierQueueEnumerations(authToken, returnObj); return returnObj; } catch (Exception e) { throw; // Rethrow exceptions } }
/// <summary> /// Returns a list of tier queue (support group) enumerations that the specified ConsoleUser is a member of /// </summary> /// <param name="authToken">AuthorizationToken to use</param> /// <param name="user">ConsoleUser token</param> /// <returns></returns> internal static async Task<List<Enumeration>> GetUsersTierQueueEnumerations(AuthorizationToken authToken, ConsoleUser user) { if (!authToken.IsValid) { throw new InvalidCredentialException("AuthorizationToken is not valid."); } string endpointUrl = GET_TIER_QUEUES_ENDPOINT + "/" + user.Id.ToString("D"); try { PortalHttpHelper helper = new PortalHttpHelper(authToken); string result = await helper.GetAsync(endpointUrl); dynamic obj = JsonConvert.DeserializeObject<List<ExpandoObject>>(result, new ExpandoObjectConverter()); List<Enumeration> returnList = new List<Enumeration>(); foreach (var enumJson in obj) { returnList.Add(new Enumeration(enumJson.Id, enumJson.Text, enumJson.Name, true, false)); } return returnList; } catch (Exception e) { throw; // Rethrow exceptions } }
/// <summary> /// Convenience method to query the Cireson Portal for the authenticated user's security rights. /// </summary> /// <param name="authToken">AuthorizationToken to use</param> /// <returns></returns> public static async Task<ConsoleUser> GetUserRights(AuthorizationToken authToken) { return await GetUserRights(authToken, authToken.UserName, authToken.Domain); }
/// <summary> /// Refreshes an object, discarding any changes that may have been made. /// This method must be called before accessing properties of children in relationship collections in order to populate all properties. /// </summary> /// <param name="authToken">AuthorizationToken to use</param> /// <returns></returns> public abstract Task <bool> Refresh(AuthorizationToken authToken);