[TestMethod]// [3] Create Tenant public void PostTenantCreatesTenant() { //arrange var Tcrtl = new TenantsController(); //Act var newTenant = new TenantModel { FirstName = "Test", LastName = "LastNameTest", Telephone = "12223334444", EmailAddress = "*****@*****.**" }; //Result of the post request IHttpActionResult result = Tcrtl.PostTenant(newTenant); //Assert Assert.IsInstanceOfType(result, typeof(CreatedAtRouteNegotiatedContentResult <TenantModel>)); }
public static void UpdateTenant(TenantModel tenantModel) { using (ctaDBEntities entities = new ctaDBEntities()) { Tenant tenant = entities.Tenants.Where(s => s.Id == tenantModel.Id).FirstOrDefault(); if (tenant != null) { tenant.activationId = String.IsNullOrEmpty(tenantModel.activationId) ? "" : tenantModel.activationId; tenant.email = tenantModel.email; tenant.type = tenantModel.type; tenant.typeExpiration = tenantModel.typeExpiration; entities.SaveChanges(); } if (!(entities.Database.Connection.State == ConnectionState.Closed)) { entities.Database.Connection.Close(); } } }
public async Task <IActionResult> Register([FromBody] AuthenticationModel authenticationModel) { if (!ModelState.IsValid) { return(BadRequest()); } var tenantModel = new TenantModel { Description = authenticationModel.UserIdentification, TenantGuid = new Guid() }; var register = await _userRepository.RegisterAsync(authenticationModel, tenantModel); if (!register) { return(new JsonResult(UserAlreadyExists)); } await _tenantRepository.AddAsync(tenantModel); return(new OkObjectResult(UserCreatedSuccessfully)); }
public HttpResponseMessage GetRequest(string functionApi, TenantModel tenant) { var client = _clientFactory.CreateClient(_appSettings.UrlClientName); client.Timeout = new TimeSpan(0, 0, _appSettings.APITimeout); SetupClient(client); var requestUrl = GetFunctionWithSubUrl(functionApi); var json = JsonConvert.SerializeObject(tenant); var request = new HttpRequestMessage { Method = HttpMethod.Get, RequestUri = new Uri(requestUrl), Content = new StringContent(json, Encoding.UTF8, "application/json") }; var response = client.SendAsync(request).ConfigureAwait(false); var responseInfo = response.GetAwaiter().GetResult(); return(responseInfo); }
public static TModel TryGroupPrincipalCatchWithLogger <TModel>(Func <string, GroupPrincipal, TModel> func, ILogger logger, IParameterEnvService parameterEnvService, string groupName, ConcurrentDictionary <string, TModel> cache_result, IEnumerable <LogCategory> logCategories) { TModel result = default(TModel); try { if (cache_result.ContainsKey(groupName) && cache_result.TryGetValue(groupName, out result)) { return(result); } TenantModel tenantModel = parameterEnvService.CurrentTenantModel; GroupPrincipal group; using (PrincipalContext context = new PrincipalContext((ContextType)(int)tenantModel.SecurityContext, tenantModel.DomainAddress, tenantModel.DomainUser, tenantModel.DomainPassword)) using (GroupPrincipal groupPrincipal = new GroupPrincipal(context)) { groupPrincipal.SamAccountName = groupName; using (PrincipalSearcher searcher = new PrincipalSearcher(groupPrincipal)) { group = searcher.FindOne() as GroupPrincipal; if (group == null) { throw new DSWException($"Group {groupName} not found in domain controller {tenantModel.DomainName}", null, DSWExceptionCode.SC_NotFoundAccount); } result = func(tenantModel.DomainName, group); cache_result.TryAdd(groupName, result); return(result); } } } catch (Exception ex) { if (ex is DSWException) { throw; } logger.WriteWarning(ex, logCategories); } return(result); }
public IHttpActionResult PutTenant(int id, TenantModel tenant) { if (!ModelState.IsValid) { return(BadRequest(ModelState)); } if (id != tenant.TenantId) { return(BadRequest()); } // var dbTenant = db.Tenants.Find(id); Tenant dbTenant = db.Tenants.FirstOrDefault(t => t.User.UserName == User.Identity.Name && t.TenantId == id); if (dbTenant == null) { return(BadRequest()); } dbTenant.Update(tenant); db.Entry(dbTenant).State = EntityState.Modified; try { db.SaveChanges(); } catch (DbUpdateConcurrencyException) { if (!TenantExists(id)) { return(NotFound()); } else { throw; } } return(StatusCode(HttpStatusCode.NoContent)); }
public ActionResult Login(string returnUrl, string ssocode = "") { var context = new Context(); var log = new SysLogModel(context: context); if (context.Authenticated) { if (context.QueryStrings.Bool("new")) { Authentications.SignOut(); } log.Finish(context: context); return(base.Redirect(Locations.Top(context: context))); } if ((Parameters.Authentication.Provider == "SAML") && (ssocode != string.Empty)) { var tenant = new TenantModel().Get( context: context, ss: SiteSettingsUtilities.TenantsSiteSettings(context), where : Rds.TenantsWhere().Comments(ssocode)); if (tenant.AccessStatus == Databases.AccessStatuses.Selected) { var redirectUrl = Saml.SetIdpConfiguration(context, tenant.TenantId); if (redirectUrl != null) { return(new RedirectResult(redirectUrl)); } } return(new RedirectResult(Locations.InvalidSsoCode(context))); } var html = UserUtilities.HtmlLogin( context: context, returnUrl: returnUrl, message: Request.QueryString["expired"] == "1" && !Request.IsAjaxRequest() ? Messages.Expired(context: context).Text : string.Empty); ViewBag.HtmlBody = html; log.Finish(context: context, responseSize: html.Length); return(View()); }
public ActionResult Create(LeaseApplicationCreateViewModel model) { if (ModelState.IsValid) { var tenant = new TenantModel { Name = model.TenantFullName, DateOfBirth = model.TenantDateOfBirth.Value }; var result = Service.CreateLeaseApplication(tenant, model.LeaseTermsId, ((OwnerModel)Session["SelectedAccount"]).Id, User.Identity.Name); if (result) { return(RedirectToAction("Details", "LeaseTerms", new { tId = model.LeaseTermsId })); } else { ModelState.AddModelError("", "Error creating application."); } } return(View(model)); }
public IActionResult CheckExistingNamePortal(TenantModel model) { if (model == null) { return BadRequest(new { error = "portalNameEmpty", message = "PortalName is required" }); } if (!CheckExistingNamePortal((model.PortalName ?? "").Trim(), out var error)) { return BadRequest(error); } return Ok(new { message = "portalNameReadyToRegister" }); }
public IHttpActionResult PostTenant(TenantModel tenant) { if (!ModelState.IsValid) { return(BadRequest(ModelState)); } var dbTenant = new Tenant(); //Update Tenant in DB dbTenant.Update(tenant); db.Tenants.Add(dbTenant); db.SaveChanges(); tenant.TenantId = dbTenant.TenantId; return(CreatedAtRoute("DefaultApi", new { id = tenant.TenantId }, tenant)); }
/// <summary> /// 启用/禁用 /// </summary> /// <param name="accountStatus"></param> /// <returns></returns> public JsonRsp SetStatus(long[] Ids, int status) { if (Ids == null) { return(new JsonRsp { success = false, retmsg = "请选择要操作的数据" }); } TenantModel user = new TenantModel(); user.Status = status; OQL q = OQL.From(user) .Update(user.Status) .Where(cmp => cmp.Comparer(user.ID, "IN", Ids)) //为了安全,不带Where条件是不会全部删除数据的 .END; int returnvalue = EntityQuery <TenantModel> .Instance.ExecuteOql(q); return(new JsonRsp { success = returnvalue > 0, code = returnvalue }); }
public static TModel TryGenericCatchWithLogger <TModel>(Func <string, PrincipalContext, TModel> func, ILogger logger, IParameterEnvService parameterEnvService, IEnumerable <LogCategory> logCategories) { try { TenantModel tenantModel = parameterEnvService.CurrentTenantModel; using (PrincipalContext context = new PrincipalContext((ContextType)(int)tenantModel.SecurityContext, tenantModel.DomainAddress, tenantModel.DomainUser, tenantModel.DomainPassword)) { return(func(tenantModel.DomainName, context)); } } catch (Exception ex) { if (ex is DSWException) { throw; } logger.WriteWarning(ex, logCategories); } return(default(TModel)); }
public IHttpActionResult PostTenant(TenantModel tenant) { if (!ModelState.IsValid) { return(BadRequest(ModelState)); } var dbTenant = new Tenant(tenant); dbTenant.User = db.Users.FirstOrDefault(u => u.UserName == User.Identity.Name); db.Tenants.Add(dbTenant); db.SaveChanges(); tenant.TenantId = dbTenant.TenantId; return(CreatedAtRoute("DefaultApi", new { id = tenant.TenantId }, tenant)); }
public TenantModel FetchById(int tenantId) { // Build up the parameters var parameters = new List <SqlParameter>() { CreateParameter("@TenantId", SqlDbType.Int, tenantId) }; var dataSet = FetchFilteredData("Sp_Fetch_Tenant_ById", parameters); // Check if any data if (dataSet.Tables.Count <= 0 || dataSet.Tables[0].Rows.Count <= 0) { return(null); } // Return the first row var tenant = dataSet.Tables[0].Rows[0]; var domainModel = new TenantModel() { TenantId = Cast <int>(tenant["TenantId"]), ProvisioningOptionId = Cast <int?>(tenant["ProvisioningOptionId"]), ThemeId = Cast <int?>(tenant["ThemeId"]), SiteName = tenant["SiteName"].ToString(), DataCenter = tenant["DataCenter"].ToString(), AzureServicesProvisioned = Cast <bool>(tenant["AzureServicesProvisioned"]), ProvisioningOption = tenant["ProvisioningOption"].ToString(), ProvisioningOptionCode = tenant["ProvisioningOptionCode"].ToString(), Theme = tenant["Theme"].ToString(), ThemeCode = tenant["ThemeCode"].ToString(), OrganizationId = tenant["OrganizationId"].ToString(), SubscriptionId = tenant["SubscriptionId"].ToString(), Username = tenant["Username"].ToString(), }; return(domainModel); }
public ActionResult Create(TenantModel model) { if (model.TenantName.Contains(' ')) { ModelState.AddModelError("TenantName", "The Tenant name cannot contain a space"); return(View(model)); } if (_tenantRepository.TenantNameExists(model.TenantName)) { ModelState.AddModelError("TenantName", "A tenant with this name already exists"); return(View(model)); } model.Id = Guid.NewGuid(); model.CompanyId = Guid.NewGuid(); model.BankDetailsId = Guid.NewGuid(); model.TenantName = model.TenantName.ToLower(); _defaultBankDetailsId = model.BankDetailsId; var databaseService = new JobSystemDatabaseCreationService(model.TenantName); try { databaseService.CreateDatabase(true); databaseService.CreateJobSystemSchemaFromMigrations(Server.MapPath("~/bin/JobSystem.Migrations.dll")); databaseService.InitHibernate(Server.MapPath("~/bin/JobSystem.DataAccess.NHibernate.dll")); databaseService.BeginHibernateTransaction(); databaseService.InsertDefaultData(BuildDefaultData(model)); databaseService.InsertCompanyDetails(GetCompanyDetails(databaseService, model)); databaseService.InsertAdminUser( model.AdminUserEmailAddress, model.AdminName, model.AdminJobTitle, model.AdminPassword); databaseService.CommitHibernateTransaction(); _tenantRepository.InsertTenant(model.Id, model.TenantName, model.CompanyName); _tenantRepository.InsertTenantConnectionString(model.TenantName, databaseService.GetTenantConnectionString()); _connectionStringRepository.Put(model.TenantName, databaseService.GetTenantConnectionString()); } catch (Exception) { return(RedirectToAction("Error")); } return(RedirectToAction("Success")); }
public IActionResult ChangeStatus(TenantModel model) { if (!CommonMethods.GetTenant(model, out var tenant)) { Log.Error("Model without tenant"); return BadRequest(new { error = "portalNameEmpty", message = "PortalName is required" }); } if (tenant == null) { Log.Error("Tenant not found"); return BadRequest(new { error = "portalNameNotFound", message = "Portal not found" }); } var active = model.Status; if (active != TenantStatus.Active) { active = TenantStatus.Suspended; } tenant.SetStatus(active); HostedSolution.SaveTenant(tenant); return Ok(new { tenant = CommonMethods.ToTenantWrapper(tenant) }); }
private void ValidateViewModel(TenantModel model, bool newTenant) { if (string.IsNullOrWhiteSpace(model.Name)) { ModelState.AddModelError(nameof(TenantModel.Name), "名称不可为空"); } var allEngines = GetEngines(); if (newTenant && allEngines.Any(tenant => string.Equals(tenant.Settings.Name, model.Name, StringComparison.OrdinalIgnoreCase))) { ModelState.AddModelError(nameof(TenantModel.Name), "名称重复"); } if (!string.IsNullOrEmpty(model.Name) && !Regex.IsMatch(model.Name, @"^\w+$")) { ModelState.AddModelError(nameof(TenantModel.Name), "名称只能是字母切不包含空格"); } if (!IsDefault() && string.IsNullOrWhiteSpace(model.RequestUrlHost) && string.IsNullOrWhiteSpace(model.RequestUrlPrefix)) { ModelState.AddModelError(nameof(TenantModel.RequestUrlPrefix), "Url前缀和主机不可同时为空"); } var allOtherEngine = allEngines.Where(tenant => !string.Equals(tenant.Settings.Name, model.Name, StringComparison.OrdinalIgnoreCase)); if (allOtherEngine.Any(tenant => string.Equals(tenant.Settings.RequestUrlPrefix, model.RequestUrlPrefix?.Trim(), StringComparison.OrdinalIgnoreCase) && string.Equals(tenant.Settings.RequestUrlHost, model.RequestUrlHost, StringComparison.OrdinalIgnoreCase))) { ModelState.AddModelError(nameof(TenantModel.RequestUrlPrefix), "主机名和前缀已经存在"); } if (!string.IsNullOrWhiteSpace(model.RequestUrlPrefix)) { if (model.RequestUrlPrefix.Contains('/')) { ModelState.AddModelError(nameof(TenantModel.RequestUrlPrefix), "Url前缀不能包含 '/' "); } } }
public async Task <IActionResult> CreateAndRegisterTenant([FromBody] TenantModel model) { if (!ModelState.IsValid) { return(BadRequest(ModelState)); } try { var tenantData = JobAssistantMapper.Map <Tenant>(model); await _repo.Create(tenantData); _logger.LogDebug("Self-registered the new tenant: " + tenantData.DomainId); } catch (Exception e) { _logger.LogError(1, e, "Failed to create tenant in DB repository"); throw; } return(Ok()); }
/// <summary> /// Add tenant to the corresponding property /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void btnAdd_Click(object sender, EventArgs e) { try { string fileName = string.Concat(Guid.NewGuid(), "_", fileUploadControl.FileName); TenantModel tntModel = new TenantModel(); tntModel.Firstname = txttenantFirstName.Text; tntModel.Lastname = txttenantLastName.Text; tntModel.Amount = Convert.ToDecimal(txtRentAmount.Text); tntModel.StartDate = Convert.ToDateTime(txtStartDate.Text); tntModel.EndDate = Convert.ToDateTime(txtEndDate.Text); tntModel.PropertyID = Convert.ToInt32(Request.QueryString["Id"]); tntModel.TenantID = Convert.ToInt32(hdnTenantId.Value); if (fileUploadControl.HasFile) { tntModel.FileName = fileName; } else { tntModel.FileName = hdnFileName.Value; } var tenantBusiness = new TenantBusiness(); var result = tenantBusiness.SaveTenant(tntModel); if (!result.Success) { litMsg.Text = result.Message; } else { SaveFile(fileUploadControl, fileName); LoadPropertyDetails(); } } catch (Exception ex) { litMsg.Text = ex.Message; } }
public async Task <IEnumerable <TenantModel> > Get(TenantFilterModel filterModel) { var serviceProvidersList = (await _serviceProviderRepository.GetAsync(x => filterModel.TenantIds.Contains(x.Id))).ToList(); var companyIds = serviceProvidersList.SelectMany(x => x.Companies.Select(c => c.CompanyId)).Distinct().ToList(); var companies = (await _companyManager.GetCompanies(new CompanyFilter { CompanyIds = companyIds })).Data.ToHashSet(); var result = new List <TenantModel>(); foreach (var serviceProvider in serviceProvidersList) { var model = new TenantModel { Id = serviceProvider.Id, Name = serviceProvider.TenantName, Phone = serviceProvider.Phone, Companies = companies.Where(x => serviceProvider.Companies.Select(c => c.CompanyId).Contains(x.Id)).ToList() }; result.Add(model); } return(result); }
/// <summary> /// Fixed: /// </summary> public (string redirectUrl, string redirectResultUrl, string html) Login(Context context, string returnUrl, string ssocode = "") { var log = new SysLogModel(context: context); if (context.Authenticated) { if (context.QueryStrings.Bool("new")) { Authentications.SignOut(context: context); } log.Finish(context: context); return(Locations.Top(context: context), null, null); } if ((Parameters.Authentication.Provider == "SAML") && (ssocode != string.Empty)) { var tenant = new TenantModel().Get( context: context, ss: SiteSettingsUtilities.TenantsSiteSettings(context), where : Rds.TenantsWhere().Comments(ssocode)); if (tenant.AccessStatus == Databases.AccessStatuses.Selected) { var redirectUrl = Saml.SetIdpConfiguration(context, tenant.TenantId); if (redirectUrl != null) { return(null, redirectUrl, null); } } return(null, Locations.InvalidSsoCode(context), null); } var html = UserUtilities.HtmlLogin( context: context, returnUrl: returnUrl, message: context.QueryStrings.ContainsKey("expired") && context.QueryStrings["expired"] == "1" && !context.Ajax ? Messages.Expired(context: context).Text : string.Empty); log.Finish(context: context, responseSize: html.Length); return(null, null, html); }
public static ICollection <WebAPIServiceDto> GetServiceDto(this TenantModel source) { ICollection <WebAPIServiceDto> dtos = new List <WebAPIServiceDto>(); IBaseAddress address = null; foreach (IWebApiControllerEndpoint endpoint in source.WebApiClientConfig.EndPoints) { address = source.WebApiClientConfig.Addresses.Single(s => s.AddressName.Equals(endpoint.AddressName, StringComparison.InvariantCultureIgnoreCase)); WebAPIServiceDto serviceDto = new WebAPIServiceDto() { Name = endpoint.EndpointName, WebAPIUrl = Path.Combine(address.Address.AbsoluteUri, endpoint.ControllerName) }; dtos.Add(serviceDto); } foreach (KeyValuePair <string, TenantEntityConfiguration> entity in source.Entities.Where(x => x.Value.IsActive)) { WebAPIServiceDto serviceDto = dtos.FirstOrDefault(x => x.Name.Equals(entity.Key, StringComparison.InvariantCultureIgnoreCase)); if (serviceDto == null) { serviceDto = new WebAPIServiceDto() { Name = entity.Key } } ; serviceDto.ODATAUrl = Path.Combine(source.ODATAUrl, entity.Value.ODATAControllerName); if (!dtos.Any(x => x.Name.Equals(entity.Key, StringComparison.InvariantCultureIgnoreCase))) { dtos.Add(serviceDto); } } return(dtos); } }
public async Task <IActionResult> GetAsync([FromRoute] Guid code) { var repoTenant = _uow.GetRepository <ITenantRepository>(); var tenant = await repoTenant.GetByCodeAsync(code); if (tenant == null) { return(NotFound()); } var info = await repoTenant.GetInfoByCodeAsync(code); if (info == null) { return(NotFound()); } var hosts = await repoTenant.GetHostByCodeAsync(code); if (hosts.Count == 0) { return(NotFound()); } var model = new TenantModel { Code = tenant.Code, HostName = string.Join(';', hosts.Select(x => x.HostName)), Info = new TenantInfoModel { TaxCode = info.TaxCode, FullNameVi = info.FullNameVi, Address = info.Address } }; return(Ok(model)); }
async Task HandleValidSubmitAsync() { if (EditContext.Name != null && !string.IsNullOrEmpty(EditContext.Name)) { EditContext.Name = EditContext.Name.Trim(); if (EditContext.Name.Length > 50 || string.IsNullOrEmpty(EditContext.Name)) { return; } var result = EditContext.Id == 0 ? await _apiWrapper.Tenants.CreateAsync(EditContext) : await _apiWrapper.Tenants.UpdateAsync(EditContext); if (result.IsSuccess && result.Error == null) { if (result.Data != null) { await grid.CancelRowEdit(); EditContext = null; await SearchAsync(); } else { message = _localizer[result.Error.Message]; _toastAppService.ShowWarning(message); } } else { message = _localizer[(result.Error.Message)]; _toastAppService.ShowWarning(message); } } }
[TestMethod] // [4] Delete Tenant public void DeletePropertyDeleteProperty() { //Arrange var tctrl = new TenantsController(); //Act var newTenant = new TenantModel { FirstName = "Test", LastName = "LastNameTest", Telephone = "12223334444", EmailAddress = "*****@*****.**" }; //Add 'new tenant' to database using post //save returned value as result IHttpActionResult result = tctrl.PostTenant(newTenant); //Cast result as content result so I can gather intel on it CreatedAtRouteNegotiatedContentResult <TenantModel> contentResult = (CreatedAtRouteNegotiatedContentResult <TenantModel>)result; //Result contains the property I had just created result = tctrl.GetTenant(contentResult.Content.TenantId); //get tenantmodel from result OkNegotiatedContentResult <TenantModel> tenantResult = (OkNegotiatedContentResult <TenantModel>)result; //Act result = tctrl.DeleteTenant(contentResult.Content.TenantId); //Assert //If action returns not found Assert.IsNotInstanceOfType(result, typeof(NotFoundResult)); //If action retruns OK() Assert.IsInstanceOfType(result, typeof(OkNegotiatedContentResult <TenantModel>)); }
public static List <_ACAG_AbacusCalendarConnector> GetReportData(TenantModel tenant, AbacusSettingModel abacusSetting) { List <_ACAG_AbacusCalendarConnector> result; ConnectionParameters connectionParameters = new ConnectionParameters( abacusSetting.ServiceServerName, abacusSetting.ServicePort, abacusSetting.UseSsl, abacusSetting.ServiceUser, abacusSetting.ServicePasswordCrypted, tenant.Number); LoginHandler loginHandlerInstance = new LoginHandler(connectionParameters); AbaReportAccessorNew abaReportAccessorNew = new AbaReportAccessorNew(loginHandlerInstance); result = abaReportAccessorNew.GetListFromMatrixReport <_ACAG_AbacusCalendarConnector>( "_ACAG_AbacusCalendarConnector", string.Empty, string.Empty, false).ToList(); return(result); }
/// <summary> /// 获取管理员列表(分页) /// </summary> /// <param name="pageIndex"></param> /// <param name="pageSize"></param> /// <returns></returns> public JsonRsp <TenantViewModel> GetPageList(int pageIndex, int pageSize) { JsonRsp <TenantViewModel> rsp = new JsonRsp <TenantViewModel>(); TenantModel m = new TenantModel(); OQL q = OQL.From(m) .Select() .OrderBy(m.ID, "asc") .END; //分页 q.Limit(pageSize, pageIndex, true); //q.PageWithAllRecordCount = allCount; //List<Employee> list= EntityQuery<Employee>.QueryList(q); List <TenantModel> list = q.ToList <TenantModel>();//使用OQL扩展 rsp.data = list.ConvertAll <TenantViewModel>(o => { return(new TenantViewModel() { ID = o.ID, TenantName = o.TenantName, TenantDomain = o.TenantDomain, Sort = o.Sort, Status = o.Status, CreateBy = o.CreateUser, CreateIP = o.CreateIP, CreateTime = o.CreateTime, }); } ); rsp.success = true; rsp.code = 0; rsp.count = q.PageWithAllRecordCount; return(rsp); }
public IHttpActionResult PutTenant(int id, TenantModel tenant) { if (!ModelState.IsValid) { return(BadRequest(ModelState)); } if (id != tenant.TenantId) { return(BadRequest()); } var dbTentant = db.Tenants.Find(id); dbTentant.Update(tenant); db.Entry(dbTentant).State = EntityState.Modified; try { db.SaveChanges(); } catch (DbUpdateConcurrencyException) { if (!TenantExists(id)) { return(NotFound()); } else { throw; } } return(StatusCode(HttpStatusCode.NoContent)); }
public async Task <CreateTenantModel> CreateTenantAsync(string tenantId, string userId) { /* Creates a new tenant */ string iotHubName = this.FormatResourceName(this.iotHubNameFormat, tenantId); string dpsName = this.FormatResourceName(this.dpsNameFormat, tenantId); // Create a new tenant and save it to table storage var tenant = new TenantModel(tenantId); await this.tableStorageClient.InsertAsync <TenantModel>(TenantTableId, tenant); // kick off provisioning runbooks await this.runbookHelper.CreateIotHub(tenantId, iotHubName, dpsName); // Give the requesting user an admin role to the new tenant try { await this.identityGatewayClient.AddTenantForUserAsync(userId, tenantId, CreatedRole); } catch (Exception e) { throw new Exception("Unable to add user to tenant.", e); } // Update the userSettings table with the lastUsedTenant if there isn't already a lastUsedTenant IdentityGatewayApiSettingModel userSettings = null; try { userSettings = await this.identityGatewayClient.GetSettingsForUserAsync(userId, LastUsedSettingKey); } catch (Exception e) { throw new Exception("Could not access user settings for LastUsedTenant.", e); } if (userSettings == null) { // Set the last used tenant to be this new tenant try { await this.identityGatewayClient.AddSettingsForUserAsync(userId, LastUsedSettingKey, tenantId); } catch (Exception e) { throw new Exception("Could not set user settings for LastUsedTenant.", e); } } // Write tenant info cosmos db collection name to app config try { foreach (string collection in this.tenantCollections.Keys) { string collectionKey = string.Format(this.appConfigCollectionKeyFormat, tenantId, collection); string collectionId = $"{collection}-{tenantId}"; await this.appConfigClient.SetValueAsync(collectionKey, collectionId); } } catch (Exception e) { // In order for a complete tenant creation, all app config keys must be created. throw an error if not throw new Exception($"Unable to add required collection ids to App Config for tenant {tenantId}", e); } try { await this.deviceGroupClient.CreateDefaultDeviceGroupAsync(tenantId); } catch (Exception e) { throw new Exception("Unable to create the default device group for the new tenant.", e); } return(new CreateTenantModel(tenantId)); }
public async Task <DeleteTenantModel> DeleteTenantAsync(string tenantId, string userId, bool ensureFullyDeployed = true) { Dictionary <string, bool> deletionRecord = new Dictionary <string, bool> { }; // Load the tenant from table storage string partitionKey = tenantId.Substring(0, 1); TenantModel tenant = await this.tableStorageClient.RetrieveAsync <TenantModel>(TenantTableId, partitionKey, tenantId); if (tenant != null && !tenant.IsIotHubDeployed && ensureFullyDeployed) { // If the tenant iothub is not deployed, we should not be able to start the delete process // this will mean the tenant is not fully deployed, so some resources could be deployed after // the delete process has begun throw new Exception("The tenant exists but it has not been fully deployed. Please wait for the tenant to fully deploy before trying to delete."); } else if (tenant == null) { this.logger.LogInformation("The tenant {tenantId} could not be deleted from Table Storage because it does not exist or was not fully created.", tenantId); deletionRecord["tenantTableStorage"] = true; } else { try { await this.tableStorageClient.DeleteAsync <TenantModel>(TenantTableId, tenant); deletionRecord["tenantTableStorage"] = true; } catch (Exception e) { this.logger.LogInformation(e, "Unable to delete info from table storage for tenant {tenantId}", tenantId); deletionRecord["tableStorage"] = false; } } // delete the tenant from the user try { await this.identityGatewayClient.DeleteTenantForAllUsersAsync(tenantId); deletionRecord["userTableStorage"] = true; } catch (Exception e) { this.logger.LogInformation(e, "Unable to delete user-tenant relationships for tenant {tenantId} in the user table.", tenantId); deletionRecord["userTableStorage"] = false; } // update userSettings table LastUsedTenant if necessary try { IdentityGatewayApiSettingModel lastUsedTenant = await this.identityGatewayClient.GetSettingsForUserAsync(userId, "LastUsedTenant"); if (lastUsedTenant.Value == tenantId) { // update the LastUsedTenant to some null await this.identityGatewayClient.UpdateSettingsForUserAsync(userId, "LastUsedTenant", string.Empty); } } catch (Exception e) { this.logger.LogInformation(e, "Unable to get the user {userId} LastUsedTenant setting, the setting will not be updated.", userId); } // Gather tenant information string iotHubName = this.FormatResourceName(this.iotHubNameFormat, tenantId); string dpsName = this.FormatResourceName(this.dpsNameFormat, tenantId); // trigger delete iothub runbook try { await this.runbookHelper.DeleteIotHub(tenantId, iotHubName, dpsName); deletionRecord["iotHub"] = true; } catch (Exception e) { this.logger.LogInformation(e, "Unable to successfully trigger Delete IoTHub Runbook for tenant {tenantId}", tenantId); deletionRecord["iotHub"] = false; } string saJobName = this.FormatResourceName(this.streamAnalyticsNameFormat, tenantId); // trigger delete SA runbook try { await this.runbookHelper.DeleteAlerting(tenantId, saJobName); deletionRecord["alerting"] = true; } catch (Exception e) { this.logger.LogInformation(e, "Unable to successfully trigger Delete Alerting runbook for tenant {tenantId}", tenantId); deletionRecord["alerting"] = false; } // Delete collections foreach (KeyValuePair <string, string> collectionInfo in this.tenantCollections) { string collection = collectionInfo.Key; string databaseId = collectionInfo.Value; string collectionAppConfigKey = string.Format(this.appConfigCollectionKeyFormat, tenantId, collection); string collectionId = string.Empty; try { collectionId = this.appConfigClient.GetValue(collectionAppConfigKey); } catch (Exception e) { this.logger.LogInformation(e, "Unable to retrieve the key {collectionKey} for a collection id in App Config for tenant {tenantId}", collectionAppConfigKey, tenantId); } if (string.IsNullOrEmpty(collectionId)) { this.logger.LogInformation("The collectionId was not set properly for tenant {tenantId} while attempting to delete the {collection} collection", collectionAppConfigKey, tenantId); // Currently, the assumption for an unknown collection id is that it has been deleted. // We can come to this conclusion by assuming that the app config key containing the collection id was already deleted. // TODO: Determine a more explicit outcome for this scenario - jrb deletionRecord[$"{collection}Collection"] = true; // If the collectionId could not be properly retrieved, go on to the next colleciton, do not attempt to delete. continue; } try { await this.cosmosClient.DeleteCollectionAsync(databaseId, collectionId); deletionRecord[$"{collection}Collection"] = true; } catch (ResourceNotFoundException e) { this.logger.LogInformation(e, "The {collection} collection for tenant {tenantId} does exist and cannot be deleted.", collectionId, tenantId); deletionRecord[$"{collection}Collection"] = true; } catch (Exception e) { deletionRecord[$"{collection}Collection"] = false; this.logger.LogInformation(e, "An error occurred while deleting the {collection} collection for tenant {tenantId}", collectionId, tenantId); } try { // now that we have the collection Id, delete the key from app config await this.appConfigClient.DeleteKeyAsync(collectionAppConfigKey); } catch (Exception e) { this.logger.LogInformation(e, "Unable to delete {collectionKey} from App Config", collectionAppConfigKey, tenantId); } } foreach (string blobContainer in this.tenantBlobContainers) { string containerName = $"{tenantId}{blobContainer}"; string deletionRecordValue = $"{containerName}BlobContainer"; try { await this.blobStorageClient.DeleteBlobContainerAsync(containerName); deletionRecord[deletionRecordValue] = true; } catch (ResourceNotFoundException e) { this.logger.LogInformation(e, $"Unable to delete blob container {containerName} for tenant {tenantId}. The blob container does not exist."); deletionRecord[deletionRecordValue] = true; } catch (Exception e) { this.logger.LogInformation(e, $"Unable to delete blob container {containerName} for tenant {tenantId}."); deletionRecord[deletionRecordValue] = false; } } return(new DeleteTenantModel(tenantId, deletionRecord, ensureFullyDeployed)); }