/// <summary> /// Checks the access an account has with an organization.. /// </summary> /// <param name="name">The organization name.</param> /// <param name="accountId">The account identifier.</param> /// <param name="allowAdmin">if set to <c>true</c> allow admin.</param> /// <param name="allowWrite">if set to <c>true</c> allow write.</param> /// <param name="allowRead">if set to <c>true</c> allow read.</param> public void CheckAccess( DomainLabel name, EmailAddress accountId, out bool allowAdmin, out bool allowWrite, out bool allowRead) { allowAdmin = false; allowWrite = false; allowRead = false; if (name == null) { throw new ArgumentNullException("name"); } if (accountId == null) { throw new ArgumentNullException("accountId"); } CloudTable orgMemberTable = this.GetOrganizationMembershipTable(); TableOperation getOrgMember = TableOperation.Retrieve<OrganizationMembershipEntity>( name.ToString(), accountId.ToString()); TableResult result = orgMemberTable.Execute(getOrgMember); OrganizationMembershipEntity entity = result.Result as OrganizationMembershipEntity; if (entity != null) { allowRead = true; allowWrite = entity.AllowWrite; allowAdmin = entity.AllowAdmin; } }
/// <summary> /// Authorizes the application. /// </summary> /// <param name="accountId">The account identifier.</param> /// <param name="applicationName">Name of the application.</param> public void AuthorizeApplication(EmailAddress accountId, DomainLabel applicationName) { if (accountId == null) { throw new ArgumentNullException("accountId"); } if (applicationName == null) { throw new ArgumentNullException("applicationName"); } CloudTable authorizeTable = this.GetAuthorizedApplicationsTable(); AuthorizedApplicationEntity entity = new AuthorizedApplicationEntity( accountId.ToString(), applicationName.ToString()); TableOperation op = TableOperation.InsertOrMerge(entity); authorizeTable.Execute(op); }
/// <summary> /// Creates an application. /// </summary> /// <param name="name">The name of the application.</param> /// <param name="friendlyName">The friendly name of the application.</param> /// <param name="organizationName">The organization that owns the application.</param> /// <param name="clientId">the client id.</param> /// <param name="clientSecret">the client secret.</param> /// <param name="homePageUrl">The home page URL.</param> /// <param name="authorizationCallbackUrl">The authorization callback URL.</param> /// <param name="accountId">The user creating the application.</param> /// <remarks> /// This call assumes the user has been already authorized to create the application. /// </remarks> public void CreateApplication( DomainLabel name, string friendlyName, DomainLabel organizationName, string clientId, string clientSecret, Uri homePageUrl, Uri authorizationCallbackUrl, EmailAddress accountId) { if (!ValidateApplicationName(name)) { throw new ArgumentOutOfRangeException("name"); } if (string.IsNullOrWhiteSpace(friendlyName)) { throw new ArgumentOutOfRangeException("friendlyName"); } if (organizationName == null) { throw new ArgumentNullException("organizationName"); } if (accountId == null) { throw new ArgumentNullException("accountId"); } if (string.IsNullOrWhiteSpace(clientId)) { throw new ArgumentOutOfRangeException("clientId"); } if (string.IsNullOrWhiteSpace(clientSecret)) { throw new ArgumentOutOfRangeException("clientSecret"); } if (homePageUrl == null) { throw new ArgumentNullException("homePageUrl"); } if (authorizationCallbackUrl == null) { throw new ArgumentNullException("authorizationCallbackUrl"); } CloudTable appTable = this.GetApplicationTable(); CloudTable appByClientIdTable = this.GetApplicationNameByClientIdTable(); CloudTable orgAppsTable = this.GetOrganizationApplicationsTable(); if (FindExistingApplication(appTable, name.ToString()) != null) { throw new InvalidOperationException("Application already exists."); } ApplicationEntity appEntity = new ApplicationEntity(name.ToString()) { FriendlyName = friendlyName, OrganizationId = organizationName.ToString(), ClientId = clientId, ClientSecret = clientSecret, CreatedByAccountId = accountId.ToString(), CreatedTime = DateTime.UtcNow, HomePageUrl = homePageUrl.ToString(), AuthorizationCallbackUrl = authorizationCallbackUrl.ToString() }; appEntity.LastModifiedByAccountId = appEntity.CreatedByAccountId; appEntity.LastModifiedTime = appEntity.CreatedTime; OrganizationApplicationEntity orgAppEntity = new OrganizationApplicationEntity( organizationName.ToString(), name.ToString()); ApplicationNameByClientIdEntity appByClientIdEntity = new ApplicationNameByClientIdEntity( clientId) { ApplicationName = name.ToString() }; TableOperation insertAppByClientId = TableOperation.InsertOrMerge(appByClientIdEntity); appByClientIdTable.Execute(insertAppByClientId); TableOperation insertOrgApp = TableOperation.InsertOrMerge(orgAppEntity); orgAppsTable.Execute(insertOrgApp); TableOperation insertApp = TableOperation.Insert(appEntity); appTable.Execute(insertApp); }
/// <summary> /// Validates the format and length of the name. /// </summary> /// <param name="name">the name to validate.</param> /// <returns>whether or not the name is a valid name.</returns> private static bool ValidateApplicationName(DomainLabel name) { if (name == null) { return false; } if (name.ToString().Length > MaxNameLength) { return false; } return true; }
/// <summary> /// Determines whether is application authorized by the specified account identifier. /// </summary> /// <param name="accountId">The account identifier.</param> /// <param name="applicationName">Name of the application.</param> /// <returns>Whether the user has authorized the application.</returns> public bool IsApplicationAuthorized(EmailAddress accountId, DomainLabel applicationName) { if (accountId == null) { throw new ArgumentNullException("accountId"); } if (applicationName == null) { throw new ArgumentNullException("applicationName"); } CloudTable authorizeTable = this.GetAuthorizedApplicationsTable(); TableOperation op = TableOperation.Retrieve<AuthorizedApplicationEntity>( accountId.ToString(), applicationName.ToString()); TableResult result = authorizeTable.Execute(op); return (result.Result as AuthorizedApplicationEntity) != null; }
/// <summary> /// Gets the applications of the given organization. /// </summary> /// <param name="organizationName">Name of the organization.</param> /// <returns>List of application records.</returns> public IEnumerable<OrganizationApplicationInfo> GetApplicationsOfOrganization( DomainLabel organizationName) { if (organizationName == null) { throw new ArgumentNullException("organizationName"); } CloudTable appTable = this.GetApplicationTable(); CloudTable orgAppsTable = this.GetOrganizationApplicationsTable(); TableQuery<OrganizationApplicationEntity> orgAppsQuery = new TableQuery<OrganizationApplicationEntity>().Where( TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, organizationName.ToString())); List<string> appNames = new List<string>(); foreach (OrganizationApplicationEntity accountMember in orgAppsTable.ExecuteQuery(orgAppsQuery)) { appNames.Add(accountMember.RowKey); } List<OrganizationApplicationInfo> results = new List<OrganizationApplicationInfo>(); foreach (string appName in appNames) { TableOperation getApp = TableOperation.Retrieve<ApplicationEntity>(appName, string.Empty); TableResult getAppResult = appTable.Execute(getApp); ApplicationEntity app = getAppResult.Result as ApplicationEntity; if (app != null) { results.Add(new OrganizationApplicationInfo { ApplicationName = DomainLabel.Parse(app.PartitionKey), FriendlyName = app.FriendlyName }); } } return results; }
/// <summary> /// Gets the application. /// </summary> /// <param name="applicationName">Name of the application.</param> /// <returns>application info.</returns> /// <remarks> /// This assumes the caller will filter results for what a user is authorized to do. /// </remarks> public ApplicationInfo GetApplication(DomainLabel applicationName) { if (applicationName == null) { throw new ArgumentNullException("applicationName"); } CloudTable appTable = this.GetApplicationTable(); ApplicationEntity entity = FindExistingApplication(appTable, applicationName.ToString()); if (entity == null) { return null; } return new ApplicationInfo { Name = applicationName, FriendlyName = entity.FriendlyName, OrganizationName = DomainLabel.Parse(entity.OrganizationId), ClientId = entity.ClientId, ClientSecret = entity.ClientSecret, HomePageUrl = new Uri(entity.HomePageUrl), AuthorizationCallbackUrl = new Uri(entity.AuthorizationCallbackUrl) }; }
/// <summary> /// Computes the bytes. /// </summary> /// <param name="accountId">The account identifier.</param> /// <param name="applicationName">Name of the application.</param> /// <param name="expires">The expires.</param> /// <returns>the body of the token.</returns> private static byte[] ComputeBytes( EmailAddress accountId, DomainLabel applicationName, DateTime expires) { byte[] encodedAccountId = Encoding.UTF8.GetBytes(accountId.ToString()); byte[] encodedAppName = Encoding.UTF8.GetBytes(applicationName.ToString()); byte[] raw = new byte[encodedAccountId.Length + encodedAppName.Length + 2 + SizeOfLong]; Array.Copy(encodedAccountId, 0, raw, 0, encodedAccountId.Length); raw[encodedAccountId.Length] = 0; Array.Copy(encodedAppName, 0, raw, encodedAccountId.Length + 1, encodedAppName.Length); raw[encodedAccountId.Length + encodedAppName.Length + 1] = 0; long expiresBinary = expires.ToBinary(); for (int i = 0; i < SizeOfLong; i++) { byte value = unchecked((byte)(expiresBinary >> (8 * i))); raw[encodedAccountId.Length + encodedAppName.Length + 2 + i] = value; } return raw; }
/// <summary> /// Gets info about the members of an organization. /// </summary> /// <param name="name">the name of the organization.</param> /// <returns>A list of membership info.</returns> public IEnumerable<OrganizationMembershipInfo> GetOrganizationMemberships( DomainLabel name) { CloudTable orgMemberTable = this.GetOrganizationMembershipTable(); TableQuery<OrganizationMembershipEntity> accountMemberQuery = new TableQuery<OrganizationMembershipEntity>().Where( TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, name.ToString())); List<OrganizationMembershipInfo> result = new List<OrganizationMembershipInfo>(); foreach (OrganizationMembershipEntity entity in orgMemberTable.ExecuteQuery(accountMemberQuery)) { OrganizationMembershipInfo info = new OrganizationMembershipInfo { AccountId = EmailAddress.Parse(entity.RowKey), AllowAdmin = entity.AllowAdmin, AllowWrite = entity.AllowWrite }; result.Add(info); } return result; }
/// <summary> /// Gets information about an organization on behalf of a given account id. /// </summary> /// <param name="name">name of the organization.</param> /// <returns>organization info or null if the organization does not exist.</returns> public OrganizationInfo GetOrganization( DomainLabel name) { CloudTable orgTable = this.GetOrganizationTable(); OrganizationEntity orgEntity = FindExistingOrganization(orgTable, name.ToString()); if (orgEntity == null) { return null; } return new OrganizationInfo { Name = name, FriendlyName = orgEntity.FriendlyName, CreatedBy = EmailAddress.Parse(orgEntity.CreatedByAccountId), CreatedTime = orgEntity.CreatedTime, LastModifiedBy = EmailAddress.Parse(orgEntity.LastModifiedByAccountId), LastModifiedTime = orgEntity.LastModifiedTime }; }
/// <summary> /// Creates a new organization. /// </summary> /// <param name="name">The name of the organization.</param> /// <param name="friendlyName">the friendly name.</param> /// <param name="accountId">the account creating the organization who will be an admin.</param> public void CreateOrganization( DomainLabel name, string friendlyName, EmailAddress accountId) { if (!ValidateOrganizationName(name)) { throw new ArgumentOutOfRangeException("name"); } if (string.IsNullOrWhiteSpace(friendlyName)) { throw new ArgumentOutOfRangeException("friendlyName"); } if (accountId == null) { throw new ArgumentNullException("accountId"); } CloudTable orgTable = this.GetOrganizationTable(); CloudTable orgMemberTable = this.GetOrganizationMembershipTable(); CloudTable accountMemberTable = this.GetAccountMembershipTable(); OrganizationEntity existing = FindExistingOrganization(orgTable, name.ToString()); if (existing != null) { throw new InvalidOperationException("Organization already exists."); } AccountMembershipEntity accountMember = new AccountMembershipEntity() { PartitionKey = accountId.ToString(), RowKey = name.ToString() }; OrganizationMembershipEntity orgMember = new OrganizationMembershipEntity() { PartitionKey = name.ToString(), RowKey = accountId.ToString(), AllowAdmin = true, AllowWrite = true }; OrganizationEntity org = new OrganizationEntity() { PartitionKey = name.ToString(), RowKey = string.Empty, FriendlyName = friendlyName, CreatedByAccountId = accountId.ToString(), CreatedTime = DateTime.UtcNow }; org.LastModifiedByAccountId = org.CreatedByAccountId; org.LastModifiedTime = org.CreatedTime; TableOperation insertAccountMember = TableOperation.InsertOrReplace(accountMember); TableOperation insertOrgMember = TableOperation.InsertOrReplace(orgMember); TableOperation insertOrg = TableOperation.InsertOrReplace(org); accountMemberTable.Execute(insertAccountMember); orgMemberTable.Execute(insertOrgMember); orgTable.Execute(insertOrg); }