Esempio n. 1
0
        public IActionResult GetActionType([FromQuery] string actionInfo)
        {
            ulong           accountId       = ulong.Parse(User.Identity.Name, CultureInfo.InvariantCulture);
            UtxoPersistency utxoPersistency = _executionContextManager.ResolveUtxoExecutionServices(accountId);

            byte[] b             = Convert.FromBase64String(actionInfo);
            string actionDecoded = Encoding.UTF8.GetString(b);

            if (actionDecoded.StartsWith("addr://"))
            {
                return(GetProofActionType(actionDecoded));
            }
            else if (actionDecoded.StartsWith("sig://"))
            {
                return(GetSignatureValidationActionType(actionDecoded));
            }
            else
            {
                if (actionDecoded.Contains("ProcessRootIdentityRequest", StringComparison.InvariantCultureIgnoreCase))
                {
                    return(Ok(new { Action = "1", ActionInfo = actionInfo }));
                }
                else
                {
                    return(GetServiceProviderActionType(utxoPersistency.ClientCryptoService, actionDecoded));
                }
            }
        }
Esempio n. 2
0
        public void UnregisterExecutionServices(long accountId)
        {
            _logger.Info($"[{accountId}]: Stopping services for account");

            if (_statePersistencyItems.ContainsKey(accountId))
            {
                StatePersistency persistency = _statePersistencyItems[accountId];
                persistency.CancellationTokenSource.Cancel();
                persistency.WalletSynchronizer.Dispose();

                _statePersistencyItems.Remove(accountId);
                persistency.TransactionsService = null;
                persistency.WalletSynchronizer  = null;
                persistency.ClientCryptoService = null;
            }
            else if (_utxoPersistencyItems.ContainsKey(accountId))
            {
                UtxoPersistency persistency = _utxoPersistencyItems[accountId];
                persistency.CancellationTokenSource.Cancel();
                persistency.WalletSynchronizer.Dispose();

                _utxoPersistencyItems.Remove(accountId);
                persistency.TransactionsService = null;
                persistency.WalletSynchronizer  = null;
                persistency.ClientCryptoService = null;
            }

            Clean(accountId);
        }
Esempio n. 3
0
        public IActionResult SendAuthenticationRequest([FromBody] UserAttributeTransferDto userAttributeTransfer)
        {
            bool  res       = false;
            ulong accountId = ulong.Parse(User.Identity.Name, CultureInfo.InvariantCulture);

            UtxoPersistency utxoPersistency = _executionContextManager.ResolveUtxoExecutionServices(accountId);

            byte[] target  = userAttributeTransfer.Target.HexStringToByteArray();
            byte[] issuer  = userAttributeTransfer.Source.HexStringToByteArray();
            byte[] payload = userAttributeTransfer.Payload.HexStringToByteArray();
            byte[] assetId = userAttributeTransfer.AssetId.HexStringToByteArray();
            byte[] originalBlindingFactor = userAttributeTransfer.OriginalBlindingFactor.HexStringToByteArray();
            byte[] originalCommitment     = userAttributeTransfer.OriginalCommitment.HexStringToByteArray();
            byte[] lastTransactionKey     = userAttributeTransfer.LastTransactionKey.HexStringToByteArray();
            byte[] lastBlindingFactor     = userAttributeTransfer.LastBlindingFactor.HexStringToByteArray();
            byte[] lastCommitment         = userAttributeTransfer.LastCommitment.HexStringToByteArray();
            byte[] lastDestinationKey     = userAttributeTransfer.LastDestinationKey.HexStringToByteArray();


            RequestInput requestInput = new RequestInput {
                AssetId = assetId, EligibilityBlindingFactor = originalBlindingFactor, EligibilityCommitment = originalCommitment, Issuer = issuer, PrevAssetCommitment = lastCommitment, PrevBlindingFactor = lastBlindingFactor, PrevDestinationKey = lastDestinationKey, PrevTransactionKey = lastTransactionKey, Target = target, Payload = payload
            };

            OutputModel[] outputModels        = _gatewayService.GetOutputs(_portalConfiguration.RingSize + 1);
            byte[][]      issuanceCommitments = _gatewayService.GetIssuanceCommitments(issuer, _portalConfiguration.RingSize + 1);
            RequestResult requestResult       = utxoPersistency.TransactionsService.SendAuthenticationRequest(requestInput, outputModels, issuanceCommitments).Result;

            res = true;
            return(Ok(res));
        }
Esempio n. 4
0
        public ConsentManagementService(IDataAccessService dataAccessService, IAccountsService accountsService,
                                        IRelationsProofsValidationService relationsProofsValidationService, IConfigurationService configurationService,
                                        IHashCalculationsRepository hashCalculationsRepository, ILoggerService loggerService, IHubContext <ConsentManagementHub> hubContext)
        {
            _logger            = loggerService.GetLogger(nameof(ConsentManagementService));
            _dataAccessService = dataAccessService;
            _accountsService   = accountsService;
            _relationsProofsValidationService = relationsProofsValidationService;
            _hubContext         = hubContext;
            _azureConfiguration = configurationService.Get <IAzureConfiguration>();
            _hashCalculation    = hashCalculationsRepository.Create(Globals.DEFAULT_HASH);

            PipeIn = new ActionBlock <PacketBase>(async p =>
            {
                try
                {
                    if (p is GroupsRelationsProofs relationsProofs)
                    {
                        _logger.LogIfDebug(() => $"[{_accountId}]: checking relation proofs {JsonConvert.SerializeObject(relationsProofs, new ByteArrayJsonConverter())}");

                        UtxoPersistency utxoPersistency = _executionContextManager.ResolveUtxoExecutionServices(_accountId);
                        utxoPersistency.ClientCryptoService.DecodeEcdhTuple(relationsProofs.EcdhTuple, relationsProofs.TransactionPublicKey, out byte[] blindingFactor, out byte[] imageHash, out byte[] issuer, out byte[] sessionKey);
                        string keyImage = relationsProofs.KeyImage.ToString();

                        _proofsSessions.AddOrUpdate(keyImage, new ProofsSession {
                            SessionKey = sessionKey.ToHexString(), CreationTime = DateTime.UtcNow
                        }, (k, v) => v);

                        RelationProofsSession relationProofsSession = PopRelationProofSession(sessionKey.ToHexString());

                        _logger.LogIfDebug(() => $"{nameof(relationProofsSession)}={JsonConvert.SerializeObject(relationProofsSession, new ByteArrayJsonConverter())}");

                        RelationProofsValidationResults validationResults
                            = await _relationsProofsValidationService
                              .VerifyRelationProofs(relationsProofs, _clientCryptoService, relationProofsSession)
                              .ConfigureAwait(false);

                        await _hubContext.Clients.Group(sessionKey.ToHexString()).SendAsync("ValidationResults", validationResults).ConfigureAwait(false);
                    }
                    else if (p is TransitionCompromisedProofs compromisedProofs)
                    {
                        if (_proofsSessions.TryGetValue(compromisedProofs.CompromisedKeyImage.ToHexString(), out ProofsSession proofsSession))
                        {
                            await _hubContext.Clients.Group(proofsSession.SessionKey).SendAsync("ProofsCompromised", proofsSession).ConfigureAwait(false);
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.Error($"[{_accountId}]: failure during processing {p.GetType().Name}", ex);
                }
            });

            PipInNotifications = new ActionBlock <SynchronizerNotificationBase>(n =>
            {
            });
        }
Esempio n. 5
0
        public IActionResult SendOnboardingWithValidationsRequest([FromBody] UserAttributeTransferWithValidationsDto userAttributeTransferWithValidations)
        {
            ulong accountId = ulong.Parse(User.Identity.Name, CultureInfo.InvariantCulture);
            bool  res       = false;

            UtxoPersistency utxoPersistency = _executionContextManager.ResolveUtxoExecutionServices(accountId);

            var rootAttribute = _dataAccessService.GetUserAttributes(accountId).FirstOrDefault(u => !u.IsOverriden && u.AttributeType == _identityAttributesService.GetRootAttributeType().Item1);

            string blindingFactorSeedString = $"{rootAttribute.Content}{userAttributeTransferWithValidations.Password}";

            byte[] blindingFactorSeed        = ConfidentialAssetsHelper.FastHash256(Encoding.ASCII.GetBytes(blindingFactorSeedString));
            byte[] blindingFactor            = ConfidentialAssetsHelper.ReduceScalar32(blindingFactorSeed);
            byte[] blindingPoint             = ConfidentialAssetsHelper.GetPublicKey(blindingFactor);
            byte[] rootNonBlindedCommitment  = ConfidentialAssetsHelper.GetNonblindedAssetCommitment(rootAttribute.AssetId);
            byte[] rootOriginatingCommitment = ConfidentialAssetsHelper.SumCommitments(rootNonBlindedCommitment, blindingPoint);

            byte[] target = userAttributeTransferWithValidations.UserAttributeTransfer.Target.HexStringToByteArray();
            _dataAccessService.GetAccountId(target, out ulong spAccountId);

            AssociatedProofPreparation[] associatedProofPreparations = null;

            IEnumerable <SpIdenitityValidation> spIdenitityValidations = _dataAccessService.GetSpIdenitityValidations(spAccountId);

            if (spIdenitityValidations != null && spIdenitityValidations.Count() > 0)
            {
                associatedProofPreparations = new AssociatedProofPreparation[spIdenitityValidations.Count()];

                var associatedAttributes = _dataAccessService.GetUserAssociatedAttributes(accountId);

                int index = 0;
                foreach (var validation in spIdenitityValidations)
                {
                    string attrContent = associatedAttributes.FirstOrDefault(a => a.Item1 == validation.AttributeType)?.Item2 ?? string.Empty;
                    byte[] groupId     = _identityAttributesService.GetGroupId(validation.AttributeType);
                    byte[] assetId     = validation.AttributeType != AttributeType.DateOfBirth ? _assetsService.GenerateAssetId(validation.AttributeType, attrContent) : rootAttribute.AssetId;
                    byte[] associatedBlindingFactor        = validation.AttributeType != AttributeType.DateOfBirth ? ConfidentialAssetsHelper.GetRandomSeed() : null;
                    byte[] associatedCommitment            = validation.AttributeType != AttributeType.DateOfBirth ? ConfidentialAssetsHelper.GetAssetCommitment(assetId, associatedBlindingFactor) : null;
                    byte[] associatedNonBlindedCommitment  = ConfidentialAssetsHelper.GetNonblindedAssetCommitment(assetId);
                    byte[] associatedOriginatingCommitment = ConfidentialAssetsHelper.SumCommitments(associatedNonBlindedCommitment, blindingPoint);

                    AssociatedProofPreparation associatedProofPreparation = new AssociatedProofPreparation {
                        GroupId = groupId, Commitment = associatedCommitment, CommitmentBlindingFactor = associatedBlindingFactor, OriginatingAssociatedCommitment = associatedOriginatingCommitment, OriginatingBlindingFactor = blindingFactor, OriginatingRootCommitment = rootOriginatingCommitment
                    };

                    associatedProofPreparations[index++] = associatedProofPreparation;
                }
            }

            SendOnboardingRequest(userAttributeTransferWithValidations.UserAttributeTransfer, utxoPersistency.TransactionsService, associatedProofPreparations);

            return(Ok(res));
        }
Esempio n. 6
0
        public IActionResult SendRelationsProofs([FromBody] RelationsProofsDto relationsProofs)
        {
            ulong           accountId       = ulong.Parse(User.Identity.Name, CultureInfo.InvariantCulture);
            UtxoPersistency utxoPersistency = _executionContextManager.ResolveUtxoExecutionServices(accountId);

            byte[] target                 = relationsProofs.Target.HexStringToByteArray();
            byte[] targetViewKey          = relationsProofs.TargetViewKey.HexStringToByteArray();
            byte[] issuer                 = relationsProofs.Source.HexStringToByteArray();
            byte[] assetId                = relationsProofs.AssetId.HexStringToByteArray();
            byte[] originalBlindingFactor = relationsProofs.OriginalBlindingFactor.HexStringToByteArray();
            byte[] originalCommitment     = relationsProofs.OriginalCommitment.HexStringToByteArray();
            byte[] lastTransactionKey     = relationsProofs.LastTransactionKey.HexStringToByteArray();
            byte[] lastBlindingFactor     = relationsProofs.LastBlindingFactor.HexStringToByteArray();
            byte[] lastCommitment         = relationsProofs.LastCommitment.HexStringToByteArray();
            byte[] lastDestinationKey     = relationsProofs.LastDestinationKey.HexStringToByteArray();
            byte[] imageContent           = Convert.FromBase64String(relationsProofs.ImageContent);

            string sessionKey = _gatewayService.PushRelationProofSession(
                new RelationProofSession
            {
                ImageContent    = relationsProofs.ImageContent,
                RelationEntries = relationsProofs.Relations.Select(r => new RelationEntry {
                    RelatedAssetOwnerName = r.GroupOwnerName, RelatedAssetOwnerKey = r.GroupOwnerKey, RelatedAssetName = r.GroupName
                }).ToArray()
            });

            RelationsProofsInput requestInput = new RelationsProofsInput
            {
                AssetId = assetId,
                EligibilityBlindingFactor = originalBlindingFactor,
                EligibilityCommitment     = originalCommitment,
                Issuer = issuer,
                PrevAssetCommitment = lastCommitment,
                PrevBlindingFactor  = lastBlindingFactor,
                PrevDestinationKey  = lastDestinationKey,
                PrevTransactionKey  = lastTransactionKey,
                Target        = target,
                TargetViewKey = targetViewKey,
                Payload       = sessionKey.HexStringToByteArray(),
                ImageHash     = ConfidentialAssetsHelper.FastHash256(imageContent),
                Relations     = relationsProofs.Relations.Select(r => new Relation {
                    RelatedAssetOwner = r.GroupOwnerKey.HexStringToByteArray(), RelatedAssetId = _assetsService.GenerateAssetId(AttributeType.EmployeeGroup, r.GroupOwnerKey + r.GroupName)
                }).ToArray()
            };

            OutputModel[] outputModels        = _gatewayService.GetOutputs(_portalConfiguration.RingSize + 1);
            byte[][]      issuanceCommitments = _gatewayService.GetIssuanceCommitments(issuer, _portalConfiguration.RingSize + 1);

            utxoPersistency.TransactionsService.SendRelationsProofs(requestInput, outputModels, issuanceCommitments);

            return(Ok());
        }
Esempio n. 7
0
        public IActionResult SendOnboardingRequest([FromBody] UserAttributeTransferDto userAttributeTransfer)
        {
            ulong           accountId       = ulong.Parse(User.Identity.Name, CultureInfo.InvariantCulture);
            UtxoPersistency utxoPersistency = _executionContextManager.ResolveUtxoExecutionServices(accountId);

            bool proceed = true;

            if (!string.IsNullOrEmpty(userAttributeTransfer.ImageContent) && !string.IsNullOrEmpty(userAttributeTransfer.Content))
            {
                string sourceImage = _dataAccessService.GetUserAssociatedAttributes(accountId).FirstOrDefault(t => t.Item1 == AttributeType.PassportPhoto)?.Item2;
                BiometricPersonDataForSignatureDto biometricPersonDataForSignature = new BiometricPersonDataForSignatureDto
                {
                    ImageSource = sourceImage,
                    ImageTarget = userAttributeTransfer.ImageContent
                };

                try
                {
                    BiometricSignedVerificationDto biometricSignedVerification = $"{Request.Scheme}://{Request.Host.ToUriComponent()}/biometric/".AppendPathSegment("SignPersonFaceVerification").PostJsonAsync(biometricPersonDataForSignature).ReceiveJson <BiometricSignedVerificationDto>().Result;
                }
                catch (FlurlHttpException)
                {
                    proceed = false;
                }
                //Tuple<bool, bool> faceRes = VerifyFaceImage(userAttributeTransfer.ImageContent, userAttributeTransfer.Content);

                proceed = true;                 // faceRes.Item1;
            }

            if (proceed)
            {
                SendOnboardingRequest(userAttributeTransfer, utxoPersistency.TransactionsService);

                return(Ok(true));
            }

            return(Ok(false));
        }
Esempio n. 8
0
        public IActionResult SendCompromisedProofs([FromBody] UnauthorizedUseDto unauthorizedUse)
        {
            ulong accountId = ulong.Parse(User.Identity.Name, CultureInfo.InvariantCulture);

            UserRootAttribute rootAttribute = _dataAccessService.GetUserAttributes(accountId).FirstOrDefault();

            UtxoPersistency utxoPersistency = _executionContextManager.ResolveUtxoExecutionServices(accountId);

            byte[] target = unauthorizedUse.Target.HexStringToByteArray();
            byte[] compromisedKeyImage = unauthorizedUse.KeyImage.HexStringToByteArray();
            byte[] issuer  = rootAttribute.Source.HexStringToByteArray();
            byte[] assetId = rootAttribute.AssetId;
            byte[] originalBlindingFactor = rootAttribute.OriginalBlindingFactor;
            byte[] originalCommitment     = rootAttribute.OriginalCommitment;
            byte[] lastTransactionKey     = rootAttribute.LastTransactionKey;
            byte[] lastBlindingFactor     = rootAttribute.LastBlindingFactor;
            byte[] lastCommitment         = rootAttribute.LastCommitment;
            byte[] lastDestinationKey     = rootAttribute.LastDestinationKey;

            RequestInput requestInput = new RequestInput
            {
                AssetId = assetId,
                EligibilityBlindingFactor = originalBlindingFactor,
                EligibilityCommitment     = originalCommitment,
                Issuer = issuer,
                PrevAssetCommitment = lastCommitment,
                PrevBlindingFactor  = lastBlindingFactor,
                PrevDestinationKey  = lastDestinationKey,
                PrevTransactionKey  = lastTransactionKey,
                Target = target
            };

            OutputModel[] outputModels        = _gatewayService.GetOutputs(_portalConfiguration.RingSize + 1);
            byte[][]      issuanceCommitments = _gatewayService.GetIssuanceCommitments(issuer, _portalConfiguration.RingSize + 1);
            RequestResult requestResult       = utxoPersistency.TransactionsService.SendCompromisedProofs(requestInput, compromisedKeyImage, outputModels, issuanceCommitments).Result;

            return(Ok(requestResult.Result));
        }
Esempio n. 9
0
        public void InitializeUtxoExecutionServices(long accountId, byte[] secretSpendKey, byte[] secretViewKey, byte[] pwdSecretKey, Func <long, IUtxoClientCryptoService, CancellationToken, IUpdater> updaterFactory = null)
        {
            lock (_utxoPersistencyItems)
            {
                if (_utxoPersistencyItems.ContainsKey(accountId))
                {
                    _logger.Info($"[{accountId}]: account already registered at UtxoPersistency");
                    return;
                }

                _logger.Info($"[{accountId}]: {nameof(InitializeUtxoExecutionServices)}");

                try
                {
                    IWitnessPackagesProvider   packetsProvider            = _witnessPackagesProviderRepository.GetInstance(_restApiConfiguration.WitnessProviderName);
                    IUtxoTransactionsService   transactionsService        = ActivatorUtilities.CreateInstance <UtxoTransactionsService>(_serviceProvider);
                    IUtxoClientCryptoService   clientCryptoService        = ActivatorUtilities.CreateInstance <UtxoClientCryptoService>(_serviceProvider);
                    IRelationsBindingService   relationsBindingService    = ActivatorUtilities.CreateInstance <RelationsBindingService>(_serviceProvider);
                    UtxoWalletSynchronizer     walletSynchronizer         = ActivatorUtilities.CreateInstance <UtxoWalletSynchronizer>(_serviceProvider);
                    UtxoWalletPacketsExtractor utxoWalletPacketsExtractor = ActivatorUtilities.CreateInstance <UtxoWalletPacketsExtractor>(_serviceProvider);

                    CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();

                    packetsProvider.Initialize(accountId, cancellationTokenSource.Token);
                    clientCryptoService.Initialize(secretSpendKey, secretViewKey);

                    TaskCompletionSource <byte[]> pwdSource = new TaskCompletionSource <byte[]>();
                    if (pwdSecretKey != null)
                    {
                        pwdSource.SetResult(pwdSecretKey);
                    }
                    relationsBindingService.Initialize(pwdSource);

                    transactionsService.AccountId = accountId;
                    transactionsService.Initialize(clientCryptoService, relationsBindingService);
                    utxoWalletPacketsExtractor.AccountId = accountId;
                    utxoWalletPacketsExtractor.Initialize(clientCryptoService);
                    transactionsService.PipeOutTransactions.LinkTo(_gatewayService.PipeInTransactions);
                    transactionsService.PipeOutKeyImages.LinkTo(utxoWalletPacketsExtractor.PipeInKeyImages);

                    IUpdater userIdentitiesUpdater = updaterFactory != null?updaterFactory(accountId, clientCryptoService, cancellationTokenSource.Token) : CreateUtxoUpdater(accountId, clientCryptoService, cancellationTokenSource.Token);

                    walletSynchronizer.Initialize(accountId, clientCryptoService);

                    packetsProvider.PipeOut.LinkTo(utxoWalletPacketsExtractor.PipeIn);
                    utxoWalletPacketsExtractor.PipeOutPackets.LinkTo(walletSynchronizer.PipeInPackets);
                    utxoWalletPacketsExtractor.PipeOutProcessed.LinkTo(walletSynchronizer.PipeInPackage);
                    utxoWalletPacketsExtractor.PipeOutNotifications.LinkTo(userIdentitiesUpdater.PipInNotifications);

                    walletSynchronizer.PipeOutPackets.LinkTo(userIdentitiesUpdater.PipeIn);
                    walletSynchronizer.PipeOutNotifications.LinkTo(userIdentitiesUpdater.PipInNotifications);

                    packetsProvider.Start();

                    var state = new UtxoPersistency
                    {
                        AccountId               = accountId,
                        PacketsProvider         = packetsProvider,
                        TransactionsService     = transactionsService,
                        ClientCryptoService     = clientCryptoService,
                        RelationsBindingService = relationsBindingService,
                        PacketsExtractor        = utxoWalletPacketsExtractor,
                        WalletSynchronizer      = walletSynchronizer,
                        CancellationTokenSource = cancellationTokenSource,
                        BindingKeySource        = pwdSource
                    };
                    _utxoPersistencyItems.Add(accountId, state);
                }
                catch (Exception ex)
                {
                    _logger.Error($"[{accountId}]: Failure during {nameof(InitializeUtxoExecutionServices)}", ex);

                    throw;
                }
            }
        }
Esempio n. 10
0
        public IActionResult SendEmployeeRequest([FromBody] UserAttributeTransferDto userAttributeTransfer)
        {
            ulong           accountId       = ulong.Parse(User.Identity.Name, CultureInfo.InvariantCulture);
            UtxoPersistency utxoPersistency = _executionContextManager.ResolveUtxoExecutionServices(accountId);

            bool proceed = true;

            if (!string.IsNullOrEmpty(userAttributeTransfer.ImageContent) && !string.IsNullOrEmpty(userAttributeTransfer.Content))
            {
                string sourceImage = _dataAccessService.GetUserAssociatedAttributes(accountId).FirstOrDefault(t => t.Item1 == AttributeType.PassportPhoto)?.Item2;
                BiometricPersonDataForSignatureDto biometricPersonDataForSignature = new BiometricPersonDataForSignatureDto
                {
                    ImageSource = sourceImage,
                    ImageTarget = userAttributeTransfer.ImageContent
                };

                try
                {
                    BiometricSignedVerificationDto biometricSignedVerification = $"{Request.Scheme}://{Request.Host.ToUriComponent()}/biometric/".AppendPathSegment("SignPersonFaceVerification").PostJsonAsync(biometricPersonDataForSignature).ReceiveJson <BiometricSignedVerificationDto>().Result;
                }
                catch (FlurlHttpException)
                {
                    proceed = false;
                }
                //Tuple<bool, bool> faceRes = VerifyFaceImage(userAttributeTransfer.ImageContent, userAttributeTransfer.Content);

                proceed = true; // faceRes.Item1;
            }

            if (proceed)
            {
                SendEmployeeRequest(userAttributeTransfer, utxoPersistency.TransactionsService);

                string[] categoryEntries = userAttributeTransfer.ExtraInfo.Split("/");

                foreach (string categoryEntry in categoryEntries)
                {
                    string groupOwnerName = categoryEntry.Split("|")[0];
                    string groupName      = categoryEntry.Split("|")[1];

                    ulong groupRelationId = _dataAccessService.AddUserGroupRelation(accountId, groupOwnerName, userAttributeTransfer.Target, groupName);

                    if (groupRelationId > 0)
                    {
                        GroupRelationDto groupRelationDto = new GroupRelationDto
                        {
                            GroupRelationId = groupRelationId,
                            GroupOwnerName  = groupOwnerName,
                            GroupOwnerKey   = userAttributeTransfer.Target,
                            GroupName       = groupName
                        };

                        _idenitiesHubContext.Clients.Group(accountId.ToString(CultureInfo.InvariantCulture)).SendAsync("PushGroupRelation", groupRelationDto);
                    }
                }


                return(Ok(true));
            }

            return(Ok(false));
        }