/// <summary> /// Retrieves the transaction service profile. /// </summary> /// <param name="context">The request context.</param> /// <returns>The transaction service profile.</returns> private static TransactionServiceProfile GetTransactionServiceProfile(Microsoft.Dynamics.Commerce.Runtime.RequestContext context) { GetTransactionServiceProfileDataRequest request = new GetTransactionServiceProfileDataRequest(); Microsoft.Dynamics.Commerce.Runtime.RequestContext getTransactionServiceProfileRequestContext; // Transaction service profile is associated with channel // Decide what context is to be used to retrieve it if (context.GetPrincipal().IsChannelAgnostic) { // If the context is channel agnostic (no channel information), then use any channel available to retrieve the profile GetChannelIdServiceRequest getChannelRequest = new GetChannelIdServiceRequest(); GetChannelIdServiceResponse getChannelResponse = context.Execute <GetChannelIdServiceResponse>(getChannelRequest); long anyChannelId = getChannelResponse.ChannelId; var anonymousIdentity = new CommerceIdentity() { ChannelId = anyChannelId }; getTransactionServiceProfileRequestContext = new Microsoft.Dynamics.Commerce.Runtime.RequestContext(context.Runtime); getTransactionServiceProfileRequestContext.SetPrincipal(new CommercePrincipal(anonymousIdentity)); } else { // If the request has channel information, then use current context to retrieve the transaction service profile getTransactionServiceProfileRequestContext = context; } return(getTransactionServiceProfileRequestContext.Execute <SingleEntityDataServiceResponse <TransactionServiceProfile> >(request).Entity); }
private GetConnectionStringResponse GetConnectionString(GetConnectionStringRequest request) { // Get current channel identifier. GetChannelIdServiceRequest channelIdRequest = new GetChannelIdServiceRequest(); ICommerceRuntime runtime = request.RequestContext.Runtime; long channelId = runtime.Execute <GetChannelIdServiceResponse>(channelIdRequest, request.RequestContext, skipRequestTriggers: true).ChannelId; // If connection string is overriden simply return connection string from configuration and skip lookup. string connectionStringFromConfig = runtime.Configuration.ConnectionString; if (runtime.Configuration.IsConnectionStringOverridden) { if (string.IsNullOrWhiteSpace(connectionStringFromConfig)) { throw new ConfigurationException( ConfigurationErrors.Microsoft_Dynamics_Commerce_Runtime_InvalidChannelConfiguration, string.Format("No connection string found for channel ({0}).", channelId)); } return(new GetConnectionStringResponse(connectionStringFromConfig)); } // For current channel identifier query storage lookup data. GetStorageLookupDataRequest storageLookupRequest = new GetStorageLookupDataRequest(connectionStringFromConfig); GetStorageLookupDataResponse storageLookupResponse = request.RequestContext.Runtime.Execute <GetStorageLookupDataResponse>(storageLookupRequest, request.RequestContext, skipRequestTriggers: true); if (!storageLookupResponse.LookupValues.ContainsKey(channelId)) { throw new ConfigurationException( ConfigurationErrors.Microsoft_Dynamics_Commerce_Runtime_InvalidChannelConfiguration, ExceptionSeverity.Warning, string.Format("The specified channel ({0}) was not found.", channelId)); } // Using storage identifier from storage lookup view lookup connection string in configuration. StorageLookup lookup = storageLookupResponse.LookupValues[channelId]; string connectionString; if (!runtime.Configuration.StorageLookupConnectionStrings.TryGetValue(lookup.StorageId, out connectionString)) { throw new ConfigurationException( ConfigurationErrors.Microsoft_Dynamics_Commerce_Runtime_InvalidChannelConfiguration, ExceptionSeverity.Warning, string.Format("The connection string is not found. StorageId: {0}. ChannelId: {1}.", lookup.StorageId, channelId)); } return(new GetConnectionStringResponse(connectionString)); }
private static GetChannelIdServiceResponse GetChannelId(GetChannelIdServiceRequest request) { long channelId = request.IsDefault ? GetDefaultChannelId(request.RequestContext) : GetCurrentChannelId(request); return(new GetChannelIdServiceResponse(channelId)); }
/// <summary> /// Logon the user on local store. /// </summary> /// <param name="request">The device activation request.</param> /// <param name="channelConfiguration">The channel configuration.</param> /// <returns>The device activation response.</returns> private static Employee EmployeeLogOnStore(StaffLogOnRealtimeRequest request, ChannelConfiguration channelConfiguration) { if (request == null) { throw new ArgumentNullException("request"); } Employee employee = null, localEmployee = null; string passwordHash = string.Empty; string staffId = request.StaffId; if (request.ChannelId.HasValue && request.RequestContext.GetPrincipal().ChannelId == request.ChannelId.Value) { // Get employee salt and password hash algorithm. GetEmployeePasswordCryptoInfoDataRequest employeePasswordCryptoInfoRequest = new GetEmployeePasswordCryptoInfoDataRequest(request.ChannelId.GetValueOrDefault(), staffId); var passwordCryptoInfo = request.RequestContext.Execute <SingleEntityDataServiceResponse <EmployeePasswordCryptoInfo> >(employeePasswordCryptoInfoRequest).Entity; string salt = passwordCryptoInfo.PasswordSalt ?? string.Empty; string passwordHashAlgorithm = passwordCryptoInfo.PasswordHashAlgorithm; if (!string.IsNullOrEmpty(request.StaffPassword)) { if (string.IsNullOrEmpty(passwordHashAlgorithm)) { // get hash algorithm from the transaction service profile. var getTransactionServiceProfileDataRequest = new GetTransactionServiceProfileDataRequest(); TransactionServiceProfile transactionServiceProfile = request.RequestContext.Execute <SingleEntityDataServiceResponse <TransactionServiceProfile> >( getTransactionServiceProfileDataRequest).Entity; passwordHashAlgorithm = transactionServiceProfile.StaffPasswordHash; } HashDataServiceRequest hashDataServiceRequest = new HashDataServiceRequest(request.StaffPassword, passwordHashAlgorithm, staffId, salt); passwordHash = request.RequestContext.Execute <HashDataServiceResponse>(hashDataServiceRequest).Data; } // Logon to the store EmployeeLogOnStoreDataRequest dataRequest = new EmployeeLogOnStoreDataRequest( request.ChannelId.Value, staffId, passwordHash, new ColumnSet()); localEmployee = request.RequestContext.Execute <SingleEntityDataServiceResponse <Employee> >(dataRequest).Entity; if (localEmployee == null || localEmployee.Permissions == null) { throw new UserAuthenticationException(SecurityErrors.Microsoft_Dynamics_Commerce_Runtime_AuthenticationFailed); } // Return new object for the logged-on employee with only the required fields to ensure not returning any sensitive data. employee = new Employee(); employee.Permissions = new EmployeePermissions(); employee.Name = localEmployee.Name; employee.StaffId = localEmployee.StaffId; employee.NameOnReceipt = localEmployee.NameOnReceipt; employee.Permissions = localEmployee.Permissions; employee.Images = localEmployee.Images; employee.PasswordLastChangedDateTime = localEmployee.PasswordLastChangedDateTime; // Lock the user if multiple logins are not allowed. if (!employee.Permissions.AllowMultipleLogins && channelConfiguration != null) { LockUserAtLogOnDataRequest lockDataRequest = new LockUserAtLogOnDataRequest( request.ChannelId.Value, request.RequestContext.GetTerminal().TerminalId, staffId, channelConfiguration.InventLocationDataAreaId); bool locked = request.RequestContext.Execute <SingleEntityDataServiceResponse <bool> >(lockDataRequest).Entity; if (!locked) { throw new UserAuthenticationException(SecurityErrors.Microsoft_Dynamics_Commerce_Runtime_UserLogonAnotherTerminal); } } } else { RequestContext getEmployeeRequestContext; // Employee record is associated with channel // Decide what context is to be used to retrieve it if (request.RequestContext.GetPrincipal().IsChannelAgnostic) { // If the context is channel agnostic (no channel information), then use current (first published channel in this case) GetChannelIdServiceRequest getChannelRequest = new GetChannelIdServiceRequest(); GetChannelIdServiceResponse getChannelResponse = request.RequestContext.Execute <GetChannelIdServiceResponse>(getChannelRequest); var anonymousIdentity = new CommerceIdentity() { ChannelId = getChannelResponse.ChannelId }; getEmployeeRequestContext = new RequestContext(request.RequestContext.Runtime); getEmployeeRequestContext.SetPrincipal(new CommercePrincipal(anonymousIdentity)); } else { // If the request has channel information, then use current context getEmployeeRequestContext = request.RequestContext; } GetEmployeeDataRequest dataRequest = new GetEmployeeDataRequest(staffId, QueryResultSettings.SingleRecord); employee = getEmployeeRequestContext.Execute <SingleEntityDataServiceResponse <Employee> >(dataRequest).Entity; if (employee == null) { string message = string.Format(CultureInfo.InvariantCulture, "The specified employee ({0}) was not found.", staffId); throw new UserAuthenticationException(SecurityErrors.Microsoft_Dynamics_Commerce_Runtime_AuthenticationFailed, message); } ICommercePrincipal principal = request.RequestContext.GetPrincipal(); RequestContext contextForOperationAuthorization; if (principal.IsAnonymous) { // create an authenticated context that can be used for specific operation authorization RequestContext authenticatedContext = new RequestContext(request.RequestContext.Runtime); CommerceIdentity identity = new CommerceIdentity( employee, new Device() { DeviceNumber = principal.DeviceNumber, Token = principal.DeviceToken, ChannelId = principal.ChannelId, TerminalRecordId = principal.TerminalId }); authenticatedContext.SetPrincipal(new CommercePrincipal(identity)); contextForOperationAuthorization = authenticatedContext; } else { contextForOperationAuthorization = request.RequestContext; } GetEmployeePermissionsDataRequest permissionsDataRequest = new GetEmployeePermissionsDataRequest(staffId, new ColumnSet()); employee.Permissions = contextForOperationAuthorization.Execute <SingleEntityDataServiceResponse <EmployeePermissions> >(permissionsDataRequest).Entity; } return(employee); }