public async Task <InvokeResult> UpdateUserAsync(UserInfo user, EntityHeader org, EntityHeader updatedByUser) { var appUser = await _appUserRepo.FindByIdAsync(user.Id); appUser.FirstName = user.FirstName; appUser.LastName = user.LastName; appUser.ProfileImageUrl = user.ProfileImageUrl; appUser.LastUpdatedBy = updatedByUser; appUser.LastUpdatedDate = DateTime.UtcNow.ToJSONString(); if (appUser.IsSystemAdmin != user.IsSystemAdmin) { var updateByAppUser = await GetUserByIdAsync(updatedByUser.Id, org, updatedByUser); if (!updateByAppUser.IsSystemAdmin) { _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "UserServicesController_UpdateUserAsync", UserAdminErrorCodes.AuthNotSysAdmin.Message); return(InvokeResult.FromErrors(UserAdminErrorCodes.AuthNotSysAdmin.ToErrorMessage())); } appUser.IsSystemAdmin = user.IsSystemAdmin; } ValidationCheck(appUser, Actions.Update); await AuthorizeAsync(appUser, AuthorizeResult.AuthorizeActions.Update, updatedByUser, org); await _appUserRepo.UpdateAsync(appUser); return(InvokeResult.Success); }
protected async Task <ResourceResponse <Document> > CreateDocumentAsync(TEntity item) { if (item is IValidateable) { var result = Validator.Validate(item as IValidateable); if (!result.Successful) { throw new ValidationException("Invalid Data.", result.Errors); } } item.DatabaseName = _dbName; item.EntityType = typeof(TEntity).Name; var response = await Client.CreateDocumentAsync(await GetCollectionDocumentsLinkAsync(), item); if (response.StatusCode != System.Net.HttpStatusCode.Created) { _logger.AddCustomEvent(LogLevel.Error, $"DocuementDbRepo<{_dbName}>_CreateDocumentAsync", "Error return code: " + response.StatusCode, new KeyValuePair <string, string>("EntityType", typeof(TEntity).Name), new KeyValuePair <string, string>("Id", item.Id) ); throw new Exception("Could not insert entity"); } if (_cacheProvider != null) { await _cacheProvider.AddAsync(GetCacheKey(item.Id), JsonConvert.SerializeObject(item)); } return(response); }
/// <summary> /// Validate the core properties of the request. /// </summary> /// <param name="authRequest"></param> /// <returns></returns> public async Task <InvokeResult <AuthResponse> > AccessTokenGrantAsync(AuthRequest authRequest) { var requestValidationResult = _authRequestValidators.ValidateAuthRequest(authRequest); if (!requestValidationResult.Successful) { return(InvokeResult <AuthResponse> .FromInvokeResult(requestValidationResult)); } var accessTokenRequestValidationResult = _authRequestValidators.ValidateAccessTokenGrant(authRequest); if (!accessTokenRequestValidationResult.Successful) { return(InvokeResult <AuthResponse> .FromInvokeResult(accessTokenRequestValidationResult)); } var signInRequest = await _signInManager.PasswordSignInAsync(authRequest.UserName, authRequest.Password, true, false); if (!signInRequest.Successful) { return(InvokeResult <AuthResponse> .FromInvokeResult(signInRequest)); } _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Message, "AuthTokenManager_AccessTokenGrantAsync", "UserLoggedIn", new KeyValuePair <string, string>("email", authRequest.UserName)); var appUser = await _userManager.FindByNameAsync(authRequest.UserName); if (appUser == null) { /* Should really never, ever happen, but well...let's track it */ _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "AuthTokenManager_AccessTokenGrantAsync", UserAdminErrorCodes.AuthCouldNotFindUserAccount.Message, new KeyValuePair <string, string>("email", authRequest.UserName)); return(InvokeResult <AuthResponse> .FromErrors(UserAdminErrorCodes.AuthCouldNotFindUserAccount.ToErrorMessage())); } if (String.IsNullOrEmpty(authRequest.AppInstanceId)) { /* This generally happens for the first time the app is logged in on a new device, if it is logged in again future times it will resend the app id */ var appInstanceResult = await _appInstanceManager.CreateForUserAsync(appUser.Id, authRequest); authRequest.AppInstanceId = appInstanceResult.Result.RowKey; } else { var updateLastLoginResult = (await _appInstanceManager.UpdateLastLoginAsync(appUser.Id, authRequest)); if (updateLastLoginResult.Successful) { authRequest.AppInstanceId = updateLastLoginResult.Result.RowKey; } else { return(InvokeResult <AuthResponse> .FromInvokeResult(updateLastLoginResult.ToInvokeResult())); } } var refreshTokenResponse = await _refreshTokenManager.GenerateRefreshTokenAsync(authRequest.AppId, authRequest.AppInstanceId, appUser.Id); return(_tokenHelper.GenerateAuthResponse(appUser, authRequest, refreshTokenResponse)); }
public async Task <InvokeResult> UpdateUserAsync(UserInfo user, EntityHeader org, EntityHeader updatedByUser) { var appUser = await _appUserRepo.FindByIdAsync(user.Id); if (!String.IsNullOrEmpty(user.FirstName)) { appUser.FirstName = user.FirstName; } if (!String.IsNullOrEmpty(user.LastName)) { appUser.LastName = user.LastName; } if (!String.IsNullOrEmpty(user.PhoneNumber)) { appUser.PhoneNumber = user.PhoneNumber; appUser.PhoneNumberConfirmed = true; } if ((user.ProfileImageUrl != null)) { appUser.ProfileImageUrl = user.ProfileImageUrl; } appUser.LastUpdatedBy = updatedByUser; appUser.LastUpdatedDate = DateTime.UtcNow.ToJSONString(); if (appUser.IsSystemAdmin != user.IsSystemAdmin) { var updateByAppUser = await GetUserByIdAsync(updatedByUser.Id, org, updatedByUser); if (updateByAppUser == null) { return(InvokeResult.FromError($"Could not find updating user with id: {updateByAppUser.Id}.")); } if (!updateByAppUser.IsSystemAdmin) { _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "UserServicesController_UpdateUserAsync", UserAdminErrorCodes.AuthNotSysAdmin.Message); return(InvokeResult.FromErrors(UserAdminErrorCodes.AuthNotSysAdmin.ToErrorMessage())); } appUser.IsSystemAdmin = user.IsSystemAdmin; appUser.IsAppBuilder = user.IsAppBuilder; appUser.IsOrgAdmin = user.IsOrgAdmin; appUser.IsRuntimeuser = user.IsRuntimeUser; appUser.IsUserDevice = user.IsUserDevice; } ValidationCheck(appUser, Actions.Update); await AuthorizeAsync(appUser, AuthorizeResult.AuthorizeActions.Update, updatedByUser, org); await _appUserRepo.UpdateAsync(appUser); return(InvokeResult.Success); }
public async Task <InvokeResult> SendResetPasswordLinkAsync(SendResetPasswordLink sendResetPasswordLink) { var validationResult = _authRequestValidators.ValidateSendPasswordLinkRequest(sendResetPasswordLink); if (!validationResult.Successful) { return(validationResult); } var appUser = await _userManager.FindByEmailAsync(sendResetPasswordLink.Email); if (appUser == null) { _adminLogger.AddError("PasswordManager_SendResetPasswordLinkAsync", "CouldNotFindUser", new System.Collections.Generic.KeyValuePair <string, string>("email", sendResetPasswordLink.Email)); return(InvokeResult.FromErrors(new ErrorMessage(UserAdminResources.Err_ResetPwd_CouldNotFindUser))); } var token = await _userManager.GeneratePasswordResetTokenAsync(appUser); var encodedToken = System.Net.WebUtility.UrlEncode(token); var callbackUrl = $"{_appConfig.WebAddress}{ACTION_RESET_PASSWORD}?code={encodedToken}"; var mobileCallbackUrl = $"nuviot://resetpassword?code={token}"; #if DIAG _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Message, "PasswordManager_SendResetPasswordLinkAsync", "SentToken", token.ToKVP("token"), appUser.Id.ToKVP("appUserId"), encodedToken.ToKVP("encodedToken"), appUser.Email.ToKVP("toEmailAddress")); #endif var subject = UserAdminResources.Email_ResetPassword_Subject.Replace("[APP_NAME]", _appConfig.AppName); var body = UserAdminResources.Email_ResetPassword_Body.Replace("[CALLBACK_URL]", callbackUrl).Replace("[MOBILE_CALLBACK_URL]", mobileCallbackUrl); var result = await _emailSender.SendAsync(sendResetPasswordLink.Email, subject, body); if (result.Successful) { _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Message, "PasswordManager_SendResetPasswordLinkAsync", "SentLink", appUser.Id.ToKVP("appUserId"), appUser.Email.ToKVP("toEmailAddress")); var org = appUser.CurrentOrganization == null?EntityHeader.Create(Guid.Empty.ToId(), "????") : appUser.CurrentOrganization; await LogEntityActionAsync(appUser.Id, typeof(AppUser).Name, "SentResetPasswordLink", org, appUser.ToEntityHeader()); } else { _adminLogger.AddError("PasswordManager_SendResetPasswordLinkAsync", "Could Not Send Password Link", result.ErrorsToKVPArray()); } return(result); }
public async Task DeleteAsync <TEntity>(string id, IEntityHeader org) where TEntity : class, IIDEntity, INoSQLEntity, IKeyedEntity, IOwnedEntity { var documentLink = await GetCollectionDocumentsLinkAsync(); var docClient = GetDocumentClient(); var collectionName = _dbName + "_Collections"; var docUri = UriFactory.CreateDocumentUri(_dbName, collectionName, id); var response = await docClient.ReadDocumentAsync(docUri); if (response.StatusCode == System.Net.HttpStatusCode.OK) { var json = response.Resource.ToString(); if (String.IsNullOrEmpty(json)) { _logger.AddCustomEvent(LogLevel.Error, "DocumentDBRepoBase_GetDocumentAsync", $"Empty Response Content", new KeyValuePair <string, string>("entityType", typeof(TEntity).Name), new KeyValuePair <string, string>("id", id)); throw new RecordNotFoundException(typeof(TEntity).Name, id); } var entity = JsonConvert.DeserializeObject <TEntity>(json); if (org.Id != entity.OwnerOrganization.Id) { throw new NotAuthorizedException($"Attempt to delete record of type {typeof(TEntity).Name} owned by org {entity.OwnerOrganization.Text} by org {org.Text}"); } await docClient.DeleteDocumentAsync(docUri); } }
public async Task <InvokeResult> AddBinAsync(byte[] data, string fileName) { var result = await GetStorageContainerAsync("firmware"); if (!result.Successful) { return(result.ToInvokeResult()); } var container = result.Result; var blob = container.GetBlockBlobReference(fileName); blob.Properties.ContentType = "application/octet-stream"; //TODO: Should really encapsulate the idea of retry of an action w/ error reporting var numberRetries = 5; var retryCount = 0; var completed = false; var stream = new MemoryStream(data); while (retryCount++ < numberRetries && !completed) { try { stream.Seek(0, SeekOrigin.Begin); await blob.UploadFromStreamAsync(stream); } catch (Exception ex) { if (retryCount == numberRetries) { _logger.AddException("FirmwareBinRepo_AddItemAsync", ex); return(InvokeResult.FromException("FirmwareBinRepo_AddItemAsync", ex)); } else { _logger.AddCustomEvent(LagoVista.Core.PlatformSupport.LogLevel.Warning, "FirmwareBinRepo_AddItemAsync", "", ex.Message.ToKVP("exceptionMessage"), ex.GetType().Name.ToKVP("exceptionType"), retryCount.ToString().ToKVP("retryCount")); } await Task.Delay(retryCount * 250); } } return(InvokeResult.Success); }
public async Task <InvokeResult <RefreshToken> > GenerateRefreshTokenAsync(string appId, string appInstanceId, string userId) { var refreshToken = new RefreshToken(userId); refreshToken.RowKey = DateTime.UtcNow.ToInverseTicksRowKey(); refreshToken.AppId = appId; refreshToken.AppInstanceId = appInstanceId; refreshToken.IssuedUtc = DateTime.UtcNow.ToJSONString(); refreshToken.ExpiresUtc = (DateTime.UtcNow + _tokenOptions.RefreshExpiration).ToJSONString(); await _refreshTokenRepo.SaveRefreshTokenAsync(refreshToken); _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Verbose, "RefreshTokenManager_GenerateRefreshTokenAsync", "RefreshTokenGenerated", new KeyValuePair <string, string>("authAppId", appId), new KeyValuePair <string, string>("authAppInstanceId", appInstanceId), new KeyValuePair <string, string>("authUserId", userId)); return(InvokeResult <RefreshToken> .Create(refreshToken)); }
public async Task <InvokeResult> PasswordSignInAsync(string userName, string password, bool isPersistent, bool lockoutOnFailure) { var signInResult = await _signinManager.PasswordSignInAsync(userName, password, isPersistent, lockoutOnFailure); var appUser = await _userManager.FindByEmailAsync(userName); if (appUser != null && appUser.CurrentOrganization != null) { var isOrgAdmin = await _orgManager.IsUserOrgAdminAsync(appUser.CurrentOrganization.Id, appUser.Id); if (isOrgAdmin != appUser.IsOrgAdmin) { appUser.IsOrgAdmin = isOrgAdmin; await _userManager.UpdateAsync(appUser); } } if (signInResult.Succeeded) { await LogEntityActionAsync(appUser.Id, typeof(AppUser).Name, "UserLogin", appUser.CurrentOrganization, appUser.ToEntityHeader()); return(InvokeResult.Success); } if (signInResult.IsLockedOut) { if (appUser != null) { await LogEntityActionAsync(appUser.Id, typeof(AppUser).Name, "UserLogin Failed - Locked Out", appUser.CurrentOrganization, appUser.ToEntityHeader()); } _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "AuthTokenManager_AccessTokenGrantAsync", UserAdminErrorCodes.AuthUserLockedOut.Message, new KeyValuePair <string, string>("email", userName)); return(InvokeResult.FromErrors(UserAdminErrorCodes.AuthUserLockedOut.ToErrorMessage())); } if (appUser != null) { await LogEntityActionAsync(appUser.Id, typeof(AppUser).Name, "UserLogin Failed", appUser.CurrentOrganization, appUser.ToEntityHeader()); } _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "AuthTokenManager_AccessTokenGrantAsync", UserAdminErrorCodes.AuthInvalidCredentials.Message, new KeyValuePair <string, string>("email", userName)); return(InvokeResult.FromErrors(UserAdminErrorCodes.AuthInvalidCredentials.ToErrorMessage())); }
protected virtual async Task <TableResult> Execute(TableOperation op) { var result = await _table.ExecuteAsync(op); if (result == null) { _logger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "TableStorageBase_Execute", "Null Response Code"); throw new Exception($"Null response code from table operation"); } else if (result.HttpStatusCode < 200 || result.HttpStatusCode > 299) { _logger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "TableStorageBase_Execute", "Non-Success Status Code", new System.Collections.Generic.KeyValuePair <string, string>("StatusCode", result.HttpStatusCode.ToString())); throw new Exception($"Error response code from table operation"); } else { return(result); } }
public async Task <InvokeResult> CheckConfirmedAsync(EntityHeader orgHeader, EntityHeader userHeader) { /* This will only take the current user id so we don't have to do any security checks, not really confidential info anyways */ var user = await _userManager.FindByIdAsync(userHeader.Id); if (user == null) { _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "UserVerifyController_SendConfirmationEmailAsync", "Could not get current user."); return(InvokeResult.FromErrors(UserAdminErrorCodes.AuthCouldNotFindUserAccount.ToErrorMessage())); } if (user.EmailConfirmed) { return(InvokeResult.Success); } else { return(InvokeResult.FromErrors(new ErrorMessage() { Message = "Email Not Confirmed" })); } }
public async Task <InvokeResult> SendAsync(string email, string subject, string body) { try { body = $@"<body> <img src=""{_appConfig.AppLogo}"" /> <h1>{_appConfig.AppName}</h1> <h2>{subject}</h2> {body} <img src=""{_appConfig.CompanyLogo}"" /> <p>Please do not reply to this email as it is an unmonitored address</p> <a href=""mailto:[email protected]"">Contact Support</a> </body>"; var msg = new MimeMessage() { Subject = subject, Body = new TextPart("html", body), }; msg.To.Add(new MailboxAddress(email)); msg.From.Add(new MailboxAddress(_settings.SmtpFrom)); using (var client = new SmtpClient()) { await client.ConnectAsync(_settings.SmtpServer.Uri.ToString(), 587, false); await client.AuthenticateAsync(_settings.SmtpServer.UserName, _settings.SmtpServer.Password); await client.SendAsync(msg); await client.DisconnectAsync(true); } _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Verbose, "SendGridEmailServices_SendAsync", "EmailSent", new System.Collections.Generic.KeyValuePair <string, string>("Subject", subject), new System.Collections.Generic.KeyValuePair <string, string>("to", email)); return(InvokeResult.Success); } catch (Exception ex) { _adminLogger.AddException("SendGridEmailServices_SendAsync", ex, new System.Collections.Generic.KeyValuePair <string, string>("Subject", subject), new System.Collections.Generic.KeyValuePair <string, string>("to", email)); return(InvokeResult.FromException("SendGridEmailServices_SendAsync", ex)); } }
public async Task <InvokeResult <AppInstance> > UpdateLastLoginAsync(string appUserId, AuthRequest existingAppInstance) { var appInstance = await _appInstanceRepo.GetAppInstanceAsync(appUserId, existingAppInstance.AppInstanceId); if (appInstance == null) { _adminLogger.AddError("AppInstanceManager_UpdateLastLoginAsync", "Could not load, possible user id change", new KeyValuePair <string, string>("appUserId", appUserId), new KeyValuePair <string, string>("appInstanceId", existingAppInstance.AppInstanceId)); return(await CreateForUserAsync(appUserId, existingAppInstance)); } else { _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Message, "AppInstanceManager_UpdateLastLoginAsync", "Update Last Login Information", new KeyValuePair <string, string>("appUserId", appUserId), new KeyValuePair <string, string>("appInstanceId", existingAppInstance.AppInstanceId)); appInstance.LastLogin = DateTime.UtcNow.ToJSONString(); await _appInstanceRepo.UpdateAppInstanceAsync(appInstance); return(InvokeResult <AppInstance> .Create(appInstance)); } }
public async Task <InvokeResult> SendAsync(string number, string contents) { try { TwilioClient.Init(_settings.SmsServer.AccountId, _settings.SmsServer.AccessKey); var restClient = new TwilioRestClient(_settings.SmsServer.AccountId, _settings.SmsServer.AccessKey); await MessageResource.CreateAsync(to : new PhoneNumber(number), from : new PhoneNumber(_settings.FromPhoneNumber), body : contents); _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Verbose, "TwilioSMSSender_SendAsync", "EmailSent", new System.Collections.Generic.KeyValuePair <string, string>("Subject", number), new System.Collections.Generic.KeyValuePair <string, string>("to", contents)); return(InvokeResult.Success); } catch (Exception ex) { _adminLogger.AddException("SendGridEmailServices_SendAsync", ex, new System.Collections.Generic.KeyValuePair <string, string>("number", number), new System.Collections.Generic.KeyValuePair <string, string>("contents", contents)); return(InvokeResult.FromException("TwilioSMSSender_SendAsync", ex)); } }
private async Task LoadAsync() { var rootUri = "https://api.nuviot.com/api/simulator/network/runtime"; switch (_environment) { case Environments.Development: rootUri = "https://dev.nuviot.com/api/simulator/network/runtime"; break; case Environments.Testing: rootUri = "https://test.nuviot.com/api/simulator/network/runtime"; break; case Environments.LocalDevelopment: rootUri = "http://localhost:5001/api/simulator/network/runtime"; break; default: break; } var requestId = Guid.NewGuid().ToId(); var dateStamp = DateTime.UtcNow.ToJSONString(); var version = "1.0.0"; var bldr = new StringBuilder(); //Adding the \r\n manualy ensures that the we don't have any //platform specific code messing with our signature. bldr.Append($"{requestId}\r\n"); bldr.Append($"{dateStamp}\r\n"); bldr.Append($"{version}\r\n"); bldr.Append($"{_org.Id}\r\n"); bldr.Append($"{_user.Id}\r\n"); bldr.Append($"{_simulatorNetworkId}\r\n"); var sasKey = GetSignature(requestId, _simAccessKey, bldr.ToString()); _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Message, "SimulatorRuntimeManager_InitAsync", $"Requesting configuration from: {rootUri} "); Console.WriteLine($"Requesting configuration from: {rootUri}"); var client = new HttpClient(); client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("SAS", sasKey); client.DefaultRequestHeaders.Add(REQUEST_ID, requestId); client.DefaultRequestHeaders.Add(ORG_ID, _org.Id); client.DefaultRequestHeaders.Add(ORG, _org.Text); client.DefaultRequestHeaders.Add(USER_ID, _user.Id); client.DefaultRequestHeaders.Add(USER, _user.Text); client.DefaultRequestHeaders.Add(NETWORK_ID, _simulatorNetworkId); client.DefaultRequestHeaders.Add(DATE, dateStamp); client.DefaultRequestHeaders.Add(VERSION, version); try { var json = await client.GetStringAsync(rootUri); Runtimes.Clear(); var network = JsonConvert.DeserializeObject <SimulatorNetwork>(json); Console.WriteLine($"Loaded simulator network {network.Name}"); foreach (var sim in network.Simulators) { var services = _factory.GetServices(); var runtime = new SimulatorRuntime(services, Publisher, _adminLogger, sim); await runtime.StartAsync(); Runtimes.Add(runtime); } } catch (Exception ex) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Error loading runtime."); Console.WriteLine(ex.Message); Console.ResetColor(); } }
public async Task <InvokeResult> SetUserOrgAsync(AuthRequest authRequest, AppUser appUser) { // Synthesize the org and user from request and app user var org = new EntityHeader() { Id = authRequest.OrgId, Text = authRequest.OrgName }; var user = new EntityHeader() { Id = appUser.Id, Text = $"{appUser.FirstName} {appUser.LastName}" }; authRequest.OrgId = org.Id; authRequest.OrgName = org.Text; // 1) Ensure user has access to the requested org. var orgs = await _orgManager.GetOrganizationsForUserAsync(appUser.Id, org, user); var switchToOrg = orgs.Where(o => o.OrgId == authRequest.OrgId).FirstOrDefault(); if (switchToOrg == null) { _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "AuthTokenManager_SetOrg", UserAdminErrorCodes.AuthOrgNotAuthorized.Message, new KeyValuePair <string, string>("userid", appUser.Id), new KeyValuePair <string, string>("requestedOrgId", authRequest.OrgId)); return(InvokeResult.FromErrors(UserAdminErrorCodes.AuthOrgNotAuthorized.ToErrorMessage())); } var oldOrgId = EntityHeader.IsNullOrEmpty(appUser.CurrentOrganization) ? "none" : appUser.CurrentOrganization.Id; var oldOrgName = EntityHeader.IsNullOrEmpty(appUser.CurrentOrganization) ? "none" : appUser.CurrentOrganization.Text; // 2) Change the org on the user object appUser.CurrentOrganization = new EntityHeader() { Id = authRequest.OrgId, Text = switchToOrg.OrganizationName, }; appUser.IsOrgAdmin = switchToOrg.IsOrgAdmin; // 3) Add the roles to the user for the org. var orgRoles = await _orgManager.GetUsersRolesInOrgAsync(authRequest.OrgId, appUser.Id, appUser.CurrentOrganization, appUser.ToEntityHeader()); appUser.CurrentOrganizationRoles = new List <EntityHeader>(); foreach (var orgRole in orgRoles) { appUser.CurrentOrganizationRoles.Add(orgRole.ToEntityHeader()); } // 4) Write the updated user back to storage. var updateResult = await _userManager.UpdateAsync(appUser); if (!updateResult.Successful) { var invokeResult = updateResult.ToInvokeResult(); _adminLogger.LogInvokeResult("OrgHelper_SetUserOrgAsync", invokeResult, new KeyValuePair <string, string>("userId", appUser.Id), new KeyValuePair <string, string>("userName", appUser.UserName)); return(invokeResult); } // 5) Write this change to logger. _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Message, "AuthTokenManager_SetOrg", "UserSwitchedOrg", new KeyValuePair <string, string>("userId", appUser.Id), new KeyValuePair <string, string>("userName", appUser.UserName), new KeyValuePair <string, string>("oldOrgId", oldOrgId), new KeyValuePair <string, string>("oldOrgName", oldOrgName), new KeyValuePair <string, string>("newOrgId", appUser.CurrentOrganization.Id), new KeyValuePair <string, string>("newOrgName", appUser.CurrentOrganization.Text)); // 6) Return success, no response data necessary, app user is by reference so it should already be updated. return(InvokeResult.Success); }
public InvokeResult ValidateAuthRequest(AuthRequest authRequest) { if (authRequest == null) { _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "AuthRequestValidators_ValidateAuthRequest", UserAdminErrorCodes.AuthRequestNull.Message); return(InvokeResult.FromErrors(UserAdminErrorCodes.AuthRequestNull.ToErrorMessage())); } if (String.IsNullOrEmpty(authRequest.AppId)) { _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "AuthRequestValidators_ValidateAuthRequest", UserAdminErrorCodes.AuthMissingAppId.Message); return(InvokeResult.FromErrors(UserAdminErrorCodes.AuthMissingAppId.ToErrorMessage())); } if (String.IsNullOrEmpty(authRequest.DeviceId)) { _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "AuthRequestValidators_ValidateAuthRequest", UserAdminErrorCodes.AuthMissingDeviceId.Message); return(InvokeResult.FromErrors(UserAdminErrorCodes.AuthMissingDeviceId.ToErrorMessage())); } if (String.IsNullOrEmpty(authRequest.ClientType)) { _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "AuthRequestValidators_ValidateAuthRequest", UserAdminErrorCodes.AuthMissingClientType.Message); return(InvokeResult.FromErrors(UserAdminErrorCodes.AuthMissingClientType.ToErrorMessage())); } if (String.IsNullOrEmpty(authRequest.Email)) { _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "AuthRequestValidators_ValidateAccessTokenGrant", UserAdminErrorCodes.AuthMissingEmail.Message); return(InvokeResult.FromErrors(UserAdminErrorCodes.AuthMissingEmail.ToErrorMessage())); } return(InvokeResult.Success); }
public async Task <InvokeResult <Invitation> > InviteUserAsync(Models.DTOs.InviteUser inviteViewModel, EntityHeader org, EntityHeader user) { ValidateAuthParams(org, user); if (inviteViewModel == null) { _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "OrgManager_InviteUserAsync", UserAdminErrorCodes.InviteIsNull.Message); return(InvokeResult <Invitation> .FromErrors(UserAdminErrorCodes.InviteIsNull.ToErrorMessage())); } if (String.IsNullOrEmpty(inviteViewModel.Email)) { _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "OrgManager_InviteUserAsync", UserAdminErrorCodes.InviteEmailIsEmpty.Message); return(InvokeResult <Invitation> .FromErrors(UserAdminErrorCodes.InviteEmailIsEmpty.ToErrorMessage())); } var emailRegEx = new Regex(@"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$"); if (!emailRegEx.Match(inviteViewModel.Email).Success) { _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "OrgManager_InviteUserAsync", UserAdminErrorCodes.InviteEmailIsInvalid.Message); return(InvokeResult <Invitation> .FromErrors(UserAdminErrorCodes.InviteEmailIsInvalid.ToErrorMessage())); } if (String.IsNullOrEmpty(inviteViewModel.Name)) { _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "OrgManager_InviteUserAsync", UserAdminErrorCodes.InviteNameIsEmpty.Message); return(InvokeResult <Invitation> .FromErrors(UserAdminErrorCodes.InviteNameIsEmpty.ToErrorMessage())); } if (await _orgUserRepo.QueryOrgHasUserByEmailAsync(org.Id, inviteViewModel.Email)) { var existingUser = await _appUserRepo.FindByEmailAsync(inviteViewModel.Email); if (existingUser != null) { var msg = UserAdminResources.InviteUser_AlreadyPartOfOrg.Replace(Tokens.USERS_FULL_NAME, existingUser.Name).Replace(Tokens.EMAIL_ADDR, inviteViewModel.Email); return(InvokeResult <Invitation> .FromErrors(new ErrorMessage(msg))); } else { _adminLogger.AddError("OrgManager_InviteUserAsync", "User Found in Org Unit XRef Table Storage, but not in User, bad data", new KeyValuePair <string, string>("OrgId", org.Id), new KeyValuePair <string, string>("Email", inviteViewModel.Email)); } } var existingInvite = await _inviteUserRepo.GetInviteByOrgIdAndEmailAsync(org.Id, inviteViewModel.Email); if (existingInvite != null) { existingInvite.Status = Invitation.StatusTypes.Replaced; await _inviteUserRepo.UpdateInvitationAsync(existingInvite); } Organization organization; organization = await _organizationRepo.GetOrganizationAsync(org.Id); if (organization == null) { /* Quick and Dirty Error Checking, should Never Happen */ return(InvokeResult <Invitation> .FromError("Could not Load Org")); } var inviteModel = new Invitation() { RowKey = Guid.NewGuid().ToId(), PartitionKey = org.Id, OrganizationId = org.Id, OrganizationName = org.Text, InvitedById = user.Id, InvitedByName = user.Text, Message = inviteViewModel.Message, Name = inviteViewModel.Name, Email = inviteViewModel.Email, DateSent = DateTime.Now.ToJSONString(), Status = Invitation.StatusTypes.New, }; await AuthorizeAsync(user, org, "InviteUser", inviteModel.RowKey); inviteModel.OrganizationName = organization.Name; await _inviteUserRepo.InsertInvitationAsync(inviteModel); inviteModel = await _inviteUserRepo.GetInvitationAsync(inviteModel.RowKey); await SendInvitationAsync(inviteModel, organization.Name, user); inviteModel.DateSent = DateTime.Now.ToJSONString(); inviteModel.Status = Invitation.StatusTypes.Sent; await _inviteUserRepo.UpdateInvitationAsync(inviteModel); return(InvokeResult <Invitation> .Create(inviteModel)); }
public async Task <InvokeResult> PasswordSignInAsync(string userName, string password, bool isPersistent, bool lockoutOnFailure) { if (string.IsNullOrEmpty(userName)) { return(InvokeResult.FromError($"User name is a required field [{userName}].")); } if (string.IsNullOrEmpty(password)) { return(InvokeResult.FromError($"Password is a required field [{userName}].")); } var signInResult = await _signinManager.PasswordSignInAsync(userName, password, isPersistent, lockoutOnFailure); var appUser = await _userManager.FindByEmailAsync(userName); if (appUser == null) { await LogEntityActionAsync(userName, typeof(AppUser).Name, $"Could not find user with account [{userName}].", EntityHeader.Create("unkonwn", "unknown"), EntityHeader.Create(userName, userName)); return(InvokeResult.FromError($"Could not find user [{userName}].")); } if (appUser.IsAccountDisabled) { await LogEntityActionAsync(appUser.Id, typeof(AppUser).Name, "UserLogin Failed - Account Disabled", appUser.CurrentOrganization, appUser.ToEntityHeader()); return(InvokeResult.FromError($"Account [{userName}] is disabled.")); } if (appUser.CurrentOrganization != null) { var isOrgAdmin = await _orgManager.IsUserOrgAdminAsync(appUser.CurrentOrganization.Id, appUser.Id); if (isOrgAdmin != appUser.IsOrgAdmin) { appUser.IsOrgAdmin = isOrgAdmin; await _userManager.UpdateAsync(appUser); } } if (signInResult.Succeeded) { await LogEntityActionAsync(appUser.Id, typeof(AppUser).Name, "UserLogin", appUser.CurrentOrganization, appUser.ToEntityHeader()); return(InvokeResult.Success); } if (signInResult.IsLockedOut) { await LogEntityActionAsync(appUser.Id, typeof(AppUser).Name, "UserLogin Failed - Locked Out", appUser.CurrentOrganization, appUser.ToEntityHeader()); _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "AuthTokenManager_AccessTokenGrantAsync", UserAdminErrorCodes.AuthUserLockedOut.Message, new KeyValuePair <string, string>("email", userName)); return(InvokeResult.FromErrors(UserAdminErrorCodes.AuthUserLockedOut.ToErrorMessage())); } await LogEntityActionAsync(appUser.Id, typeof(AppUser).Name, "UserLogin Failed", appUser.CurrentOrganization, appUser.ToEntityHeader()); _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "AuthTokenManager_AccessTokenGrantAsync", UserAdminErrorCodes.AuthInvalidCredentials.Message, new KeyValuePair <string, string>("email", userName)); return(InvokeResult.FromErrors(UserAdminErrorCodes.AuthInvalidCredentials.ToErrorMessage())); }
public async Task <InvokeResult <Uri> > AddFileAsync(string fileName, byte[] data, string contentType = "application/octet-stream") { if (string.IsNullOrEmpty(fileName)) { throw new ArgumentNullException(nameof(fileName)); } if (data == null) { throw new ArgumentNullException(nameof(data)); } var result = await GetStorageContainerAsync(_containerName); if (!result.Successful) { return(InvokeResult <Uri> .FromInvokeResult(result.ToInvokeResult())); } var container = result.Result; if (fileName.StartsWith("/")) { fileName = fileName.TrimStart('/'); } var blob = container.GetBlockBlobReference(fileName); blob.Properties.ContentType = contentType; //TODO: Should really encapsulate the idea of retry of an action w/ error reporting var numberRetries = 5; var retryCount = 0; var completed = false; var stream = new MemoryStream(data); while (retryCount++ < numberRetries && !completed) { try { stream.Seek(0, SeekOrigin.Begin); await blob.UploadFromStreamAsync(stream); } catch (Exception ex) { if (retryCount == numberRetries) { _logger.AddException("CloudFileStorage_AddFileAsync", ex, _containerName.ToKVP("containerName")); var exceptionResult = InvokeResult.FromException("CloudFileStorage_AddFileAsync", ex); return(InvokeResult <Uri> .FromInvokeResult(exceptionResult)); } else { _logger.AddCustomEvent(LagoVista.Core.PlatformSupport.LogLevel.Warning, "CloudFileStorage_AddFileAsync", "", ex.Message.ToKVP("exceptionMessage"), ex.GetType().Name.ToKVP("exceptionType"), retryCount.ToString().ToKVP("retryCount")); } await Task.Delay(retryCount * 250); } } return(InvokeResult <Uri> .Create(blob.Uri)); }
public InvokeResult ValidateAuthRequest(AuthRequest authRequest) { if (authRequest == null) { _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "AuthRequestValidators_ValidateAuthRequest", UserAdminErrorCodes.AuthRequestNull.Message); return(InvokeResult.FromErrors(UserAdminErrorCodes.AuthRequestNull.ToErrorMessage())); } if (String.IsNullOrEmpty(authRequest.AppId)) { _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "AuthRequestValidators_ValidateAuthRequest", UserAdminErrorCodes.AuthMissingAppId.Message); return(InvokeResult.FromErrors(UserAdminErrorCodes.AuthMissingAppId.ToErrorMessage())); } if (String.IsNullOrEmpty(authRequest.DeviceId)) { _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "AuthRequestValidators_ValidateAuthRequest", UserAdminErrorCodes.AuthMissingDeviceId.Message); return(InvokeResult.FromErrors(UserAdminErrorCodes.AuthMissingDeviceId.ToErrorMessage())); } if (String.IsNullOrEmpty(authRequest.ClientType)) { _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "AuthRequestValidators_ValidateAuthRequest", UserAdminErrorCodes.AuthMissingClientType.Message); return(InvokeResult.FromErrors(UserAdminErrorCodes.AuthMissingClientType.ToErrorMessage())); } if (String.IsNullOrEmpty(authRequest.Email)) { _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "AuthRequestValidators_ValidateAccessTokenGrant", UserAdminErrorCodes.AuthMissingEmail.Message); return(InvokeResult.FromErrors(UserAdminErrorCodes.AuthMissingEmail.ToErrorMessage())); } if (String.IsNullOrEmpty(authRequest.UserName)) { authRequest.UserName = authRequest.Email; } switch (authRequest.AuthType) { case AuthTypes.ClientApp: break; case AuthTypes.DeviceUser: if (String.IsNullOrEmpty(authRequest.DeviceRepoId)) { _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "AuthRequestValidators_ValidateAccessTokenGrant", UserAdminErrorCodes.AuthMissingRepoIdForDeviceUser.Message); return(InvokeResult.FromErrors(UserAdminErrorCodes.AuthMissingRepoIdForDeviceUser.ToErrorMessage())); } break; case AuthTypes.Runtime: break; case AuthTypes.User: break; } return(InvokeResult.Success); }
protected async Task <InvokeResult <T> > GetAsync <T>(string path, DeploymentHost host, EntityHeader org, EntityHeader user) { using (var request = GetHttpClient(host, org, user, "GET", path)) { try { var uri = new Uri($"{host.AdminAPIUri}{path}"); var response = await request.GetAsync(uri); if (response.IsSuccessStatusCode) { var json = await response.Content.ReadAsStringAsync(); return(JsonConvert.DeserializeObject <InvokeResult <T> >(json)); } else { _logger.AddCustomEvent(LogLevel.Error, "DeploymentConnectorService", $"{response.StatusCode} - {response.ReasonPhrase}", new KeyValuePair <string, string>("hostid", host.Id), new KeyValuePair <string, string>("path", path), new KeyValuePair <string, string>("orgid", org.Id), new KeyValuePair <string, string>("userid", user.Id)); return(DeploymentErrorCodes.ErrorCommunicatingWithhost.ToFailedInvocation <T>($"{response.StatusCode} - {response.ReasonPhrase}")); } } catch (Exception ex) { _logger.AddCustomEvent(LogLevel.Error, "DeploymentConnectorService", ex.Message, new KeyValuePair <string, string>("hostid", host.Id), new KeyValuePair <string, string>("path", path), new KeyValuePair <string, string>("orgid", org.Id), new KeyValuePair <string, string>("userid", user.Id)); return(DeploymentErrorCodes.ErrorCommunicatingWithhost.ToFailedInvocation <T>(ex.Message)); } } }
public async Task <InvokeResult> SendAsync(string email, string subject, string body) { try { body = $@" <!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Strict//EN"" ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd""><html xmlns=""http://www.w3.org/1999/xhtml""><head> <meta name=""viewport"" content=""width=device-width, initial-scale=1, minium-scale=1, maxium-scale=1""> <title>NuvIoT - IoT Eneablement Platform</title> <style type=""text/css""> body {{ width: 100% !important; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; margin: 0; padding: 0; }} .ExternalClass {{ width: 100%; }} #backgroundTable {{ margin: 0; padding: 0; width: 100% !important; line-height: 100% !important; }} img {{ outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; }} a img {{ border: none; }} .image-fix {{ display: block; }} Bring inline: Yes. */ p {{ margin: 1em 0; }} /* Hotmail header color reset Bring inline: Yes. */ h1, h2, h3, h4, h5 {{ color: #333333 !important; font-weight:400; }} h6 {{ color: #666666 !important; }} h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {{ color: #2172ba !important; }} h1 a:active, h2 a:active, h3 a:active, h4 a:active, h5 a:active, h6 a:active {{ color: #2172ba !important; }} h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited {{ color: #2172ba !important; }} /* Outlook 07, 10 Padding issue fix */ table td {{ border - collapse: collapse; }} .ssrContent{{ font - size: 12px; }} /* Remove spacing around Outlook 07, 10 tables */ table {{ /*border-collapse:collapse;*/ mso - table - lspace: 0pt; mso-table-rspace: 0pt; }} a {{ color: #2172ba; text-decoration: none; }} a:hover {{ color: #2172ba; text-decoration: underline; }} .ad-width{{ width: 275px !important; }} /*.non-mobile-image, .non-mobile-email{{ display:block !important; }}*/ td[class=""mobile-email""], td[class=""mobile-image""] {{ display: none !important; max - height: 0 !important; width: 0 !important; font - size: 0 !important; line - height: 0 !important; padding: 0 !important; mso - hide: all; /* hide elements in Outlook 2007-2013 */ }} /*div[class=""mobile-mp-card-info""] {{ margin:0 !important; padding:90px 0 0 0 !important; }}*/ /* Apple Mail to limit that table's size on desktop*/ @media screen and(min - width: 600px) {{ .container {{ width: 601px!important; }} }} @media only screen and(max-width: 525px) {{ div[class= ""mobile - mp - card - section""] {{ padding:0 !important; margin:-25px 0 0 -150px !important; }} }} /* More Specific Targeting */ /* MOBILE TARGETING 480px */ @media only screen and(min-width: 480px) {{ /*table[class=""table""], td[class=""cell""] {{ width: 304px !important; }}*/ td[class= ""mobile - ad - spacing""] {{ padding-bottom: 15px !important; }} td[class=""mobile-image""] {{ display: inline-block !important; }} td[class=""non-mobile-image""] /*, .non-mobile-email*/ {{ display: none !important; max-height: 0 !important; width: 0 !important; font-size: 0 !important; line-height: 0 !important; padding: 0 !important; /*mso-hide: all; hide elements in Outlook 2007-2013 */ }} /*.mobile-email{{ display:block !important; }}*/ tr[class=""mobile-footer""] {{ background-color: #ffffff !important; }} body[class=""mobile-body""] {{ background-color: #ffffff !important; }} div[class=""navigation""] {{ width:100% !important; }} div[class=""navigation""] a {{ display:block !important; text-decoration:none !important; text-align:center !important; font-size:16px !important; }} /*Controlling phone number linking for mobile. */ a[href ^= ""tel""], a[href ^= ""sms""] {{ text-decoration: none; color: #2172ba; pointer-events: none; cursor: default; }} .mobile_link a[href ^= ""telephone""], .mobile_link a[href ^= ""sms""] {{ text-decoration: none; color: #2172ba !important; pointer-events: auto; cursor: default; }} a[class=""mobile-show""], a[class=""mobile-hide""] {{ display: block !important; color: #2172ba !important; border-radius: 20px; padding: 0 8px; text-decoration: none; font-weight: bold; font-family: ""Helvetica Neue"", Helvetica, sans-serif; font-size: 11px; position: absolute; top: 25px; right: 10px; text-align: center; width: 40px; }} div[class=""ad-width""]{{ width:300px !important; }} }} @media only screen and(min-device-width: 768px) and(max-device-width: 1024px) {{ /*ipad (tablets, smaller screens, etc) */ a[href ^= ""tel""],a[href ^= ""sms""] {{ text-decoration: none; color: #2172ba; pointer-events: none; cursor: default; }} .mobile_link a[href ^= ""tel""], .mobile_link a[href ^= ""sms""] {{ text - decoration: default; color: #2172ba !important; pointer - events: auto; cursor: default; }} }} @media only screen and(-webkit-min-device-pixel-ratio: 2) {{ /*iPhone 4g styles */ tr[class= ""non-mobile-image""],img[class= ""non - mobile - image""], table[class=""non-mobile-email""] {{ display: none !important; max-height: 0; width: 0; font-size: 0; line-height: 0; padding: 0; mso-hide: all; /* hide elements in Outlook 2007-2013 */ }} </style> <body style=""padding: 0; margin: 0; -webkit-text-size-adjust: none; -ms-text-size-adjust: 100%; background-color: #e6e6e6;"" class=""mobile-body""> <!--[if (gte mso 9)|(IE)]> <![endif]--> <table width=""100%"" cellpadding=""20"" cellspacing=""0"" border=""0"" style=""max-width:600px; background-color:white""><div> <tr> <td> <img src=""{_appConfig.AppLogo}"" /> <h1>{_appConfig.AppName}</h1> <h2>{subject}</h2> <div style=""width:550px""> {body} </div> </td> </tr> </table> <p>Please do not reply to this email as it is an unmonitored address.</p> <a href=""mailto:[email protected]"">Contact Support</a> </div> </body> </html>"; var msg = new MimeMessage() { Subject = subject, Body = new TextPart("html", body), }; msg.To.Add(new MailboxAddress(email)); msg.From.Add(new MailboxAddress(_settings.SmtpFrom)); using (var client = new SmtpClient()) { await client.ConnectAsync(_settings.SmtpServer.Uri.ToString(), 587, false); await client.AuthenticateAsync(_settings.SmtpServer.UserName, _settings.SmtpServer.Password); await client.SendAsync(msg); await client.DisconnectAsync(true); } _adminLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Verbose, "SendGridEmailServices_SendAsync", "EmailSent", new System.Collections.Generic.KeyValuePair <string, string>("Subject", subject), new System.Collections.Generic.KeyValuePair <string, string>("to", email)); return(InvokeResult.Success); } catch (Exception ex) { _adminLogger.AddException("SendGridEmailServices_SendAsync", ex, new System.Collections.Generic.KeyValuePair <string, string>("Subject", subject), new System.Collections.Generic.KeyValuePair <string, string>("to", email)); return(InvokeResult.FromException("SendGridEmailServices_SendAsync", ex)); } }