Example #1
0
        /// <summary>
        /// Application specific configuration
        /// This method should initialize any IoC resources utilized by your web service classes.
        /// </summary>
        public override void Configure(Container container)
        {
            Plugins.Add(new CorsFeature());

            this.GlobalRequestFilters.Add((httpReq, httpRes, requestDto) => {
                // Handles Request and closes Responses after emitting global HTTP Headers
                if (httpReq.GetHttpMethodOverride() == "OPTIONS")
                {
                    httpRes.EndRequest();
                }
            });

            container.Register(c => DatabaseProvider.PrepareDatabase());

            container.Register <IAuthRepository>(c =>
                                                 new OrmLiteAuthRepository(c.Resolve <IDbConnectionFactory>()));
            container.Resolve <IAuthRepository>().InitSchema();

            container.Register <ICacheClient>(new MemoryCacheClient());

            Plugins.Add(new AuthFeature(
                            () => new AuthUserSession(),
                            new IAuthProvider[] {
                new JwtAuthProvider(AppSettings)
                {
                    AuthKey = AesUtils.CreateKey()
                },
                new BasicAuthProvider(),
                new CredentialsAuthProvider(),
            }
                            ));
            Plugins.Add(new RegistrationFeature());
        }
Example #2
0
        public void Configure(IAppHost appHost)
        {
            var AppSettings = appHost.AppSettings;

            appHost.Plugins.Add(new AuthFeature(() => new AuthUserSession(),
                                                new IAuthProvider[] {
                //new BasicAuthProvider(), //Sign-in with HTTP Basic Auth
                new JwtAuthProvider(AppSettings)
                {
                    AuthKey = AesUtils.CreateKey(),
                    RequireSecureConnection = false,
                },
                new CredentialsAuthProvider(),     //HTML Form post of UserName/Password credentials
                new FacebookAuthProvider(AppSettings),
                new TwitterAuthProvider(AppSettings),
            }));

            appHost.Plugins.Add(new RegistrationFeature());

            var userRep = new InMemoryAuthRepository();

            appHost.Register <IAuthRepository>(userRep);

            var authRepo = userRep;

            var newAdmin = new UserAuth {
                Email = "*****@*****.**", DisplayName = "Admin User"
            };
            var user = authRepo.CreateUserAuth(newAdmin, "p@55wOrd");

            authRepo.AssignRoles(user, new List <string> {
                "Admin"
            });
        }
    /// <summary>
    /// 解密Comment
    /// </summary>
    /// <param name="ori"></param>
    private void DecryptText(string ori)
    {
        var result = AesUtils.Decrypt(ori, UIPanel163Key.AesKey);

        Debug.Log("" + result);
        mIpResult.text = result;
    }
Example #4
0
        public void Configure(IAppHost appHost)
        {
            var AppSettings = appHost.AppSettings;

            appHost.Plugins.Add(new AuthFeature(() => new CustomUserSession(),
                                                new IAuthProvider[] {
                new CredentialsAuthProvider(AppSettings),     //Enable UserName/Password Credentials Auth
                new JwtAuthProvider(AppSettings)
                {
                    RequireSecureConnection = false,
                    AuthKey = AesUtils.CreateKey(),     //Transient Auth Key
                },
            }));

            appHost.Plugins.Add(new RegistrationFeature()); //Enable /register Service

            //override the default registration validation with your own custom implementation
            appHost.RegisterAs <CustomRegistrationValidator, IValidator <Register> >();

            appHost.Register <ICacheClient>(new MemoryCacheClient());         //Store User Sessions in Memory

            appHost.Register <IAuthRepository>(new InMemoryAuthRepository()); //Store Authenticated Users in Memory

            CreateUser(appHost, "*****@*****.**", "Admin User", "p@55wOrd", roles: new[] { RoleNames.Admin });
        }
        public void Can_Send_Encrypted_Message()
        {
            var client = CreateClient();

            var request = new HelloSecure {
                Name = "World"
            };

            var aes = new AesManaged {
                KeySize = AesUtils.KeySize
            };

            var aesKeyBytes       = aes.Key.Combine(aes.IV);
            var rsaEncAesKeyBytes = RsaUtils.Encrypt(aesKeyBytes, SecureConfig.PublicKeyXml);

            var timestamp = DateTime.UtcNow.ToUnixTime();

            var requestBody = timestamp + " POST " + typeof(HelloSecure).Name + " " + request.ToJson();

            var encryptedMessage = new EncryptedMessage
            {
                EncryptedSymmetricKey = Convert.ToBase64String(rsaEncAesKeyBytes),
                EncryptedBody         = AesUtils.Encrypt(requestBody, aes.Key, aes.IV)
            };
            var encResponse = client.Post(encryptedMessage);

            var responseJson = AesUtils.Decrypt(encResponse.EncryptedBody, aes.Key, aes.IV);
            var response     = responseJson.FromJson <HelloSecureResponse>();

            Assert.That(response.Result, Is.EqualTo("Hello, World!"));
        }
Example #6
0
        public (string token, Key privateKey) Login(string email, string password, string pin)
        {
            string token = api.Auth.PostAuthResponse(new AuthenticateModel()
            {
                Email    = email,
                Password = password
            }).Validate.StatusCode(HttpStatusCode.OK).Validate.NoApiError()
                           .GetResponseObject().Result.Token;

            api.PinSecurity.GetPinSecurity(pin, token).Validate.StatusCode(HttpStatusCode.OK).Validate.NoApiError();

            api.Client.GetClientCodes(token).Validate.StatusCode(HttpStatusCode.OK).Validate.NoApiError();

            string accessToken = api.Client.PostClientCodes(new SubmitCodeModel("0000"), token).Validate.StatusCode(HttpStatusCode.OK)
                                 .Validate.NoApiError().GetResponseObject().Result.AccessToken;

            string encodedPrivateKey = api.Client
                                       .PostClientEncodedMainKey(new AccessTokenModel(accessToken), token)
                                       .Validate.StatusCode(HttpStatusCode.OK).Validate.NoApiError()
                                       .GetResponseObject().Result.EncodedPrivateKey;

            string privateKeyStr = AesUtils.Decrypt(encodedPrivateKey, password);
            Key    privateKey    = Key.Parse(privateKeyStr);

            return(token, privateKey);
        }
        public void Does_Hybrid_RSA_SHA512_AES_MasterKey_and_HmacSha256()
        {
            var request = new HelloSecure {
                Name = "World"
            };
            var msgBytes = request.ToJson().ToUtf8Bytes();

            byte[] masterKey, iv;
            AesUtils.CreateKeyAndIv(out masterKey, out iv);

            var sha512KeyBytes = masterKey.ToSha512HashBytes();

            var cryptKey = new byte[sha512KeyBytes.Length / 2];
            var authKey  = new byte[sha512KeyBytes.Length / 2];

            Buffer.BlockCopy(sha512KeyBytes, 0, cryptKey, 0, cryptKey.Length);
            Buffer.BlockCopy(sha512KeyBytes, cryptKey.Length, authKey, 0, authKey.Length);

            var encryptedBytes     = AesUtils.Encrypt(msgBytes, cryptKey, iv);
            var authEncryptedBytes = HmacUtils.Authenticate(encryptedBytes, authKey, iv);

            var aesKeyNonceBytes       = iv.Combine(masterKey);
            var rsaEncAesKeyNonceBytes = RsaUtils.Encrypt(aesKeyNonceBytes, SecureConfig.PublicKeyXml);

            var json = ValidateAndDecryptWithMasterKey(rsaEncAesKeyNonceBytes, authEncryptedBytes);

            var fromJson = json.FromJson <HelloSecure>();

            Assert.That(fromJson.Name, Is.EqualTo(request.Name));
        }
 protected override JwtAuthProvider CreateJwtAuthProvider()
 {
     return(new JwtAuthProvider
     {
         AuthKey = AesUtils.CreateKey(),
         RequireSecureConnection = false,
     });
 }
Example #9
0
        public void Test_Method1()
        {
            var kex = AesUtils.CreateKey().ToBase64UrlSafe();
            var service = appHost.Container.Resolve<MyServices>();

            var response = (HelloResponse)service.Any(new Hello { Name = "World" });

            Assert.That(response.Result, Is.EqualTo("Hello, World!"));
        }
        public void Does_throw_on_replayed_messages()
        {
            var client = CreateClient();

            var request = new HelloSecure {
                Name = "World"
            };

            byte[] cryptKey, iv;
            AesUtils.CreateKeyAndIv(out cryptKey, out iv);

            byte[] authKey = AesUtils.CreateKey();

            var cryptAuthKeys = cryptKey.Combine(authKey);

            var rsaEncCryptAuthKeys     = RsaUtils.Encrypt(cryptAuthKeys, SecureConfig.PublicKeyXml);
            var authRsaEncCryptAuthKeys = HmacUtils.Authenticate(rsaEncCryptAuthKeys, authKey, iv);

            var timestamp   = DateTime.UtcNow.ToUnixTime();
            var requestBody = timestamp + " POST " + typeof(HelloSecure).Name + " " + request.ToJson();

            var encryptedBytes     = AesUtils.Encrypt(requestBody.ToUtf8Bytes(), cryptKey, iv);
            var authEncryptedBytes = HmacUtils.Authenticate(encryptedBytes, authKey, iv);

            var encryptedMessage = new EncryptedMessage
            {
                EncryptedSymmetricKey = Convert.ToBase64String(authRsaEncCryptAuthKeys),
                EncryptedBody         = Convert.ToBase64String(authEncryptedBytes),
            };

            var encResponse = client.Post(encryptedMessage);

            try
            {
                client.Post(encryptedMessage);

                Assert.Fail("Should throw");
            }
            catch (WebServiceException ex)
            {
                ex.StatusDescription.Print();

                var errorResponse = (EncryptedMessageResponse)ex.ResponseDto;

                authEncryptedBytes = Convert.FromBase64String(errorResponse.EncryptedBody);
                if (!HmacUtils.Verify(authEncryptedBytes, authKey))
                {
                    throw new Exception("EncryptedBody is Invalid");
                }

                var responseBytes = HmacUtils.DecryptAuthenticated(authEncryptedBytes, cryptKey);
                var responseJson  = responseBytes.FromUtf8Bytes();
                var response      = responseJson.FromJson <ErrorResponse>();
                Assert.That(response.ResponseStatus.Message, Is.EqualTo("Nonce already seen"));
            }
        }
Example #11
0
 public override void Configure(Container container)
 {
     Plugins.Add(new AuthFeature(() => new AuthUserSession(),
                                 new IAuthProvider[] {
         new JwtAuthProvider(AppSettings)
         {
             AuthKey = AesUtils.CreateKey()
         },
     }));
 }
Example #12
0
        public void Does_parse_byte_array_as_Base64()
        {
            var authKey = AesUtils.CreateKey();

            var appSettings = new DictionarySettings(new Dictionary <string, string>
            {
                { "AuthKey", Convert.ToBase64String(authKey) }
            });

            Assert.That(appSettings.Get <byte[]>("AuthKey"), Is.EquivalentTo(authKey));
        }
Example #13
0
        // http://localhost:5000/auth/[email protected]&&password=!Abc1234
        // Configure your AppHost with the necessary configuration and dependencies your App needs
        public override void Configure(Container container)
        {
            Plugins.Add(new TemplatePagesFeature()); // enable server-side rendering, see: http://templates.servicestack.net

            if (Config.DebugMode)
            {
                Plugins.Add(new HotReloadFeature());
            }

            Plugins.Add(new RazorFormat()); // enable ServiceStack.Razor

            SetConfig(new HostConfig
            {
                AddRedirectParamsToQueryString = true,
                DebugMode = AppSettings.Get(nameof(HostConfig.DebugMode), false)
            });

            Plugins.Add(new AuthFeature(() => new AuthUserSession(),
                                        new IAuthProvider[] {
                //new BasicAuthProvider(), //Sign-in with HTTP Basic Auth
                new JwtAuthProvider(AppSettings)
                {
                    AuthKey = AesUtils.CreateKey(),
                    RequireSecureConnection = false,
                },
                new CredentialsAuthProvider(),     //HTML Form post of UserName/Password credentials
                new FacebookAuthProvider(AppSettings),
                new TwitterAuthProvider(AppSettings),
            }));

            Plugins.Add(new RegistrationFeature());

            Plugins.Add(new OpenApiFeature
            {
                UseBearerSecurity = true,
            });

            container.Register <ICacheClient>(new MemoryCacheClient());
            var userRep = new InMemoryAuthRepository();

            container.Register <IAuthRepository>(userRep);

            var authRepo = userRep;

            var newAdmin = new UserAuth {
                Email = "*****@*****.**"
            };
            var user = authRepo.CreateUserAuth(newAdmin, "test");

            authRepo.AssignRoles(user, new List <string> {
                "Admin"
            });
        }
Example #14
0
        /// <summary>
        /// Decrypt an encrypted text.
        /// </summary>
        /// <param name="encryptedText">The encrypted text.</param>
        /// <param name="options">The decryption options.</param>
        /// <returns>Returns a decrypted text.</returns>
        public static string Decrypt(string encryptedText, IDictionary <string, object> options)
        {
            var toDecrypt     = encryptedText;
            var decryptedText = string.Empty;

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            var decodeFromBase64 = options.ContainsKey("DecodeFromBase64") &&
                                   Convert.ToBoolean(options["DecodeFromBase64"], CultureInfo.InvariantCulture);
            var encodeToBase64 = options.ContainsKey("EncodeToBase64") && Convert.ToBoolean(options["EncodeToBase64"], CultureInfo.InvariantCulture);

            var method = options.ContainsKey("Method") ? options["Method"].ToString() : string.Empty;

            switch (method)
            {
            // RSA
            case "RSA":
                var privateKeyPath = options["PrivateKeyPath"].ToString();

                if (privateKeyPath.StartsWith("\"", StringComparison.InvariantCulture))
                {
                    privateKeyPath = privateKeyPath.Substring(1, privateKeyPath.Length - 1);
                }

                if (privateKeyPath.EndsWith("\"", StringComparison.InvariantCulture))
                {
                    privateKeyPath = privateKeyPath.Substring(0, privateKeyPath.Length - 1);
                }

                decryptedText = decodeFromBase64 ? RsaUtils.Base64DecodeAndDecrypt(toDecrypt, privateKeyPath) : RsaUtils.Decrypt(toDecrypt, privateKeyPath);
                break;

            // AES
            case "AES":
                var key = options["key"].ToString();
                var initializationValue = options["iniValue"].ToString();

                decryptedText = decodeFromBase64 ? AesUtils.Base64DecodeAndDecrypt(toDecrypt, key, initializationValue) : AesUtils.Decrypt(toDecrypt, key, initializationValue);
                break;

            // Base64
            case "Base64":
                decryptedText = GeneralUtils.Base64Decode(toDecrypt);
                break;
            }

            return(encodeToBase64 ? GeneralUtils.Base64Encode(decryptedText) : decryptedText);
        }
Example #15
0
        public override void Configure(Container container)
        {
            Plugins.Add(new AuthFeature(() => new AuthUserSession(),
                                        new IAuthProvider[] {
                new CredentialsAuthProvider(AppSettings),
                new JwtAuthProvider(AppSettings)
                {
                    AuthKey = AesUtils.CreateKey(),
                    RequireSecureConnection = false,
                },
            }));

            container.Register <IAuthRepository>(c => new InMemoryAuthRepository());
            var authRepo = container.Resolve <IAuthRepository>();

            try
            {
                ((IClearable)authRepo).Clear();
            }
            catch { /*ignore*/ }

            authRepo.CreateUserAuth(new UserAuth
            {
                Id          = 1,
                UserName    = "******",
                FirstName   = "First",
                LastName    = "Last",
                DisplayName = "Display",
            }, "p@55word");

            container.Register(c => createMqServerFn());

            var mqServer = container.Resolve <IMessageService>();

            mqServer.RegisterHandler <HelloIntro>(ExecuteMessage);
            mqServer.RegisterHandler <MqAuthOnlyToken>(ExecuteMessage);
            mqServer.RegisterHandler <MqAuthOnly>(m =>
            {
                var req = new BasicRequest
                {
                    Verb    = HttpMethods.Post,
                    Headers = { ["X-ss-id"] = m.GetBody().SessionId }
                };
                var response = ExecuteMessage(m, req);
                return(response);
            });
            mqServer.RegisterHandler <MqRestriction>(ExecuteMessage);
            mqServer.Start();
        }
    public void Can_Encrypt_and_Decrypt_with_AES()
    {
        var msg = new HelloSecure {
            Name = "World"
        };

        AesUtils.CreateKeyAndIv(out var cryptKey, out var iv);

        var encryptedText = AesUtils.Encrypt(msg.ToJson(), cryptKey, iv);

        var decryptedJson = AesUtils.Decrypt(encryptedText, cryptKey, iv);

        var decryptedMsg = decryptedJson.FromJson <HelloSecure>();

        Assert.That(decryptedMsg.Name, Is.EqualTo(msg.Name));
    }
    public void Can_Encrypt_and_Decrypt_with_AES_bytes()
    {
        var msg = new HelloSecure {
            Name = "World"
        };

        AesUtils.CreateKeyAndIv(out var cryptKey, out var iv);

        var encryptedBytes = AesUtils.Encrypt(msg.ToJson().ToUtf8Bytes(), cryptKey, iv);

        var msgBytes = AesUtils.Decrypt(encryptedBytes, cryptKey, iv);

        var decryptedMsg = msgBytes.FromUtf8Bytes().FromJson <HelloSecure>();

        Assert.That(decryptedMsg.Name, Is.EqualTo(msg.Name));
    }
    public override void Configure(Container container)
    {
        Plugins.Add(new EncryptedMessagesFeature
        {
            PrivateKey          = SecureConfig.PrivateKeyXml.ToPrivateRSAParameters(),
            FallbackPrivateKeys =
            {
                SecureConfig.FallbackPrivateKeyXml.ToPrivateRSAParameters()
            },
        });

        var apiKeyAuth = new ApiKeyAuthProvider(AppSettings);
        var jwtAuth    = new JwtAuthProvider(AppSettings)
        {
            AuthKey        = AesUtils.CreateKey(),
            UseTokenCookie = false, // only works with non HTTP Cookies
        };

        Plugins.Add(new AuthFeature(() => new AuthUserSession(),
                                    new IAuthProvider[] {
            new CredentialsAuthProvider(AppSettings),
            apiKeyAuth,
            jwtAuth,
        }));

        container.Register <IAuthRepository>(c => new InMemoryAuthRepository());
        var authRepo = container.Resolve <IAuthRepository>();

        var userAuth = authRepo.CreateUserAuth(
            new UserAuth {
            Email = "*****@*****.**"
        }, "p@55word");

        var apiKeys    = apiKeyAuth.GenerateNewApiKeys(userAuth.Id.ToString(), "live");
        var apiKeyRepo = (IManageApiKeys)authRepo;

        apiKeyRepo.StoreAll(apiKeys);
        LiveApiKey = apiKeys[0];

        JwtBearerToken = jwtAuth.CreateJwtBearerToken(new AuthUserSession {
            UserAuthId      = userAuth.Id.ToString(),
            Email           = userAuth.Email,
            IsAuthenticated = true,
        });
    }
        public void Can_Send_Encrypted_Message()
        {
            var client = CreateClient();

            var request = new HelloSecure {
                Name = "World"
            };

            byte[] cryptKey, authKey, iv;
            AesUtils.CreateCryptAuthKeysAndIv(out cryptKey, out authKey, out iv);

            var cryptAuthKeys = cryptKey.Combine(authKey);

            var rsaEncCryptAuthKeys     = RsaUtils.Encrypt(cryptAuthKeys, SecureConfig.PublicKeyXml);
            var authRsaEncCryptAuthKeys = HmacUtils.Authenticate(rsaEncCryptAuthKeys, authKey, iv);

            var timestamp   = DateTime.UtcNow.ToUnixTime();
            var requestBody = timestamp + " POST " + typeof(HelloSecure).Name + " " + request.ToJson();

            var encryptedBytes     = AesUtils.Encrypt(requestBody.ToUtf8Bytes(), cryptKey, iv);
            var authEncryptedBytes = HmacUtils.Authenticate(encryptedBytes, authKey, iv);

            var encryptedMessage = new EncryptedMessage
            {
                EncryptedSymmetricKey = Convert.ToBase64String(authRsaEncCryptAuthKeys),
                EncryptedBody         = Convert.ToBase64String(authEncryptedBytes),
            };

            var encResponse = client.Post(encryptedMessage);

            authEncryptedBytes = Convert.FromBase64String(encResponse.EncryptedBody);

            if (!HmacUtils.Verify(authEncryptedBytes, authKey))
            {
                throw new Exception("Invalid EncryptedBody");
            }

            var decryptedBytes = HmacUtils.DecryptAuthenticated(authEncryptedBytes, cryptKey);

            var responseJson = decryptedBytes.FromUtf8Bytes();
            var response     = responseJson.FromJson <HelloSecureResponse>();

            Assert.That(response.Result, Is.EqualTo("Hello, World!"));
        }
        public void Does_Hybrid_RSA_Crypt_and_Auth_AES_with_HMAC_SHA256()
        {
            var request = new HelloSecure {
                Name = "World"
            };
            var timestamp = DateTime.UtcNow.ToUnixTime();
            var msg       = timestamp + " POST " + request.GetType().Name + " " + request.ToJson();
            var msgBytes  = msg.ToUtf8Bytes();

            byte[] cryptKey, authKey, iv;
            AesUtils.CreateCryptAuthKeysAndIv(out cryptKey, out authKey, out iv);

            var encryptedBytes = AesUtils.Encrypt(msgBytes, cryptKey, iv);

            var decryptedBytes = AesUtils.Decrypt(encryptedBytes, cryptKey, iv);

            Assert.That(decryptedBytes, Is.EquivalentTo(msgBytes));

            var authEncryptedBytes = HmacUtils.Authenticate(encryptedBytes, authKey, iv);

            var cryptAuthKeys = cryptKey.Combine(authKey);

            var rsaEncCryptAuthKeys     = RsaUtils.Encrypt(cryptAuthKeys, SecureConfig.PublicKeyXml);
            var authRsaEncCryptAuthKeys = HmacUtils.Authenticate(rsaEncCryptAuthKeys, authKey, iv);

            var decryptedMsg = ValidateAndDecrypt(authRsaEncCryptAuthKeys, authEncryptedBytes);

            var parts = decryptedMsg.SplitOnFirst(' ');

            Assert.That(long.Parse(parts[0]), Is.EqualTo(timestamp));

            parts = parts[1].SplitOnFirst(' ');
            Assert.That(parts[0], Is.EqualTo("POST"));

            parts = parts[1].SplitOnFirst(' ');
            Assert.That(parts[0], Is.EqualTo(request.GetType().Name));

            var decryptedJson    = parts[1];
            var decryptedRequest = decryptedJson.FromJson <HelloSecure>();

            Assert.That(decryptedRequest.Name, Is.EqualTo(request.Name));
        }
        public void Does_throw_on_replayed_messages()
        {
            var client = CreateClient();

            var request = new HelloSecure {
                Name = "World"
            };

            var aes = new AesManaged {
                KeySize = AesUtils.KeySize
            };

            var aesKeyBytes       = aes.Key.Combine(aes.IV);
            var rsaEncAesKeyBytes = RsaUtils.Encrypt(aesKeyBytes, SecureConfig.PublicKeyXml);

            var timestamp   = DateTime.UtcNow.ToUnixTime();
            var requestBody = timestamp + " POST " + typeof(HelloSecure).Name + " " + request.ToJson();

            var encryptedMessage = new EncryptedMessage
            {
                EncryptedSymmetricKey = Convert.ToBase64String(rsaEncAesKeyBytes),
                EncryptedBody         = AesUtils.Encrypt(requestBody, aes.Key, aes.IV)
            };
            var encResponse = client.Post(encryptedMessage);

            try
            {
                client.Post(encryptedMessage);

                Assert.Fail("Should throw");
            }
            catch (WebServiceException ex)
            {
                ex.StatusDescription.Print();

                var errorResponse = (EncryptedMessageResponse)ex.ResponseDto;
                var responseJson  = AesUtils.Decrypt(errorResponse.EncryptedBody, aes.Key, aes.IV);
                var response      = responseJson.FromJson <ErrorResponse>();
                Assert.That(response.ResponseStatus.Message, Is.EqualTo("Nonce already seen"));
            }
        }
Example #22
0
        public void Configure(IAppHost appHost)
        {
            var AppSettings = appHost.AppSettings;

            appHost.Plugins.Add(new AuthFeature(() => new CustomUserSession(),
                                                new IAuthProvider[] {
                new JwtAuthProvider(AppSettings)
                {
                    AuthKey = AesUtils.CreateKey()
                },                                                // Use persistent key to enable JWT's beyond restarts
                new CredentialsAuthProvider(AppSettings),         /* Sign In with Username / Password credentials */
                new FacebookAuthProvider(AppSettings),            /* Create App https://developers.facebook.com/apps */
                new GoogleAuthProvider(AppSettings),              /* Create App https://console.developers.google.com/apis/credentials */
                new MicrosoftGraphAuthProvider(AppSettings),      /* Create App https://apps.dev.microsoft.com */
            }));

            appHost.Plugins.Add(new RegistrationFeature()); //Enable /register Service

            //override the default registration validation with your own custom implementation
            appHost.RegisterAs <CustomRegistrationValidator, IValidator <Register> >();
        }
Example #23
0
        public void Configure(IAppHost appHost)
        {
            var appSettings = appHost.AppSettings;

            // Setup Authentication
            appHost.Plugins.Add(new AuthFeature(() => new AuthUserSession(),
                                                new IAuthProvider[] {
                new CredentialsAuthProvider(appSettings),        // Username/Password credentials
                new FacebookAuthProvider(appSettings),           /* Create App https://developers.facebook.com/apps */
                new JwtAuthProvider(appSettings)
                {
                    AuthKey = AesUtils.CreateKey()
                },
            })
            {
                IncludeOAuthTokensInAuthenticateResponse = true, // Include OAuth Keys in authenticated /auth page
            });

            appHost.Plugins.Add(new RegistrationFeature()); //Enable /register Service

            // Allow posting messages back to Studio when loaded in an iframe
            appHost.Plugins.Add(new CorsFeature(allowOriginWhitelist: new[] { "https://localhost:5002" }));
        }
            public string GetApi1SignVerToken()
            {
                var signTokenResponse = WalletApi.SignatureVerificationToken.GetKeyConfirmation(wallet.WalletAddress, BearerToken);

                Assert.That(signTokenResponse.StatusCode, Is.EqualTo(HttpStatusCode.OK));

                var signToken    = signTokenResponse.ResponseObject.Result.Message.ToString();
                var signVerToken = signToken;

                //
                WalletApi.PinSecurity.GetPinSecurity(pin, BearerToken).Validate.StatusCode(HttpStatusCode.OK).Validate.NoApiError("Please Reset Pin for user in Back Office");

                WalletApi.Client.GetClientCodes(BearerToken).Validate.StatusCode(HttpStatusCode.OK).Validate.NoApiError();

                string accessToken = WalletApi.Client.PostClientCodes(new SubmitCodeModel("0000"), BearerToken).Validate.StatusCode(HttpStatusCode.OK)
                                     .Validate.NoApiError().GetResponseObject().Result.AccessToken;

                string encodedPrivateKey = WalletApi.Client
                                           .PostClientEncodedMainKey(new AccessTokenModel(accessToken), BearerToken)
                                           .Validate.StatusCode(HttpStatusCode.OK).Validate.NoApiError()
                                           .GetResponseObject().Result.EncodedPrivateKey;

                string privateKeyStr = AesUtils.Decrypt(encodedPrivateKey, wallet.WalletKey);
                Key    privateKey    = Key.Parse(privateKeyStr);

                //

                signToken = privateKey.SignMessage(signToken);

                var postSignResponse = WalletApi.SignatureVerificationToken.PostKeyConfirmation(new RecoveryTokenChallangeResponse {
                    Email = wallet.WalletAddress, SignedMessage = signToken
                }, BearerToken);

                Assert.That(postSignResponse.StatusCode, Is.EqualTo(HttpStatusCode.OK));
                return(postSignResponse.ResponseObject.Result.AccessToken);
            }
        public static string CreateEncryptedJweToken(JsonObject jwtPayload, RSAParameters publicKey)
        {
            //From: http://self-issued.info/docs/draft-ietf-jose-json-web-encryption-09.html#RSACBCExample
            var jweHeader = new JsonObject
            {
                { "alg", "RSA-OAEP" },
                { "enc", "A128CBC-HS256" },
                { "kid", Convert.ToBase64String(publicKey.Modulus).Substring(0, 3) },
            };

            var jweHeaderBase64Url = jweHeader.ToJson().ToUtf8Bytes().ToBase64UrlSafe();

            var authKey          = new byte[128 / 8];
            var cryptKey         = new byte[128 / 8];
            var cryptAuthKeys256 = AesUtils.CreateKey();

            Buffer.BlockCopy(cryptAuthKeys256, 0, authKey, 0, authKey.Length);
            Buffer.BlockCopy(cryptAuthKeys256, authKey.Length, cryptKey, 0, cryptKey.Length);

            var aes = Aes.Create();

            aes.KeySize   = 128;
            aes.BlockSize = 128;
            aes.Mode      = CipherMode.CBC;
            aes.Padding   = PaddingMode.PKCS7;
            using (aes)
            {
                aes.GenerateIV();
                var iv = aes.IV;
                aes.Key = cryptKey;

                var jweEncKey          = RsaUtils.Encrypt(cryptAuthKeys256, publicKey, UseRsaKeyLength);
                var jweEncKeyBase64Url = jweEncKey.ToBase64UrlSafe();
                var ivBase64Url        = iv.ToBase64UrlSafe();

                var aad          = jweHeaderBase64Url + "." + jweEncKeyBase64Url;
                var aadBytes     = aad.ToUtf8Bytes();
                var payloadBytes = jwtPayload.ToJson().ToUtf8Bytes();

                using (var cipherStream = MemoryStreamFactory.GetStream())
                    using (var encrypter = aes.CreateEncryptor(cryptKey, iv))
                        using (var cryptoStream = new CryptoStream(cipherStream, encrypter, CryptoStreamMode.Write))
                            using (var writer = new BinaryWriter(cryptoStream))
                            {
                                writer.Write(payloadBytes);
                                cryptoStream.FlushFinalBlock();

                                using (var hmac = new HMACSHA256(authKey))
                                    using (var encryptedStream = MemoryStreamFactory.GetStream())
                                        using (var bw = new BinaryWriter(encryptedStream))
                                        {
                                            bw.Write(aadBytes);
                                            bw.Write(iv);
                                            bw.Write(cipherStream.GetBuffer(), 0, (int)cipherStream.Length);
                                            bw.Flush();

                                            var tag = hmac.ComputeHash(encryptedStream.GetBuffer(), 0, (int)encryptedStream.Length);

                                            var cipherTextBase64Url = cipherStream.ToBase64UrlSafe();
                                            var tagBase64Url        = tag.ToBase64UrlSafe();

                                            var jweToken = jweHeaderBase64Url + "."
                                                           + jweEncKeyBase64Url + "."
                                                           + ivBase64Url + "."
                                                           + cipherTextBase64Url + "."
                                                           + tagBase64Url;

                                            return(jweToken);
                                        }
                            }
            }
        }
Example #26
0
        public override void Configure(Container container)
        {
            if (Use != null)
            {
                Use(container);
            }

            if (EnableRazor)
            {
                Plugins.Add(new RazorFormat());
            }

            Plugins.Add(new SwaggerFeature());
            Plugins.Add(new RequestInfoFeature());
            Plugins.Add(new RequestLogsFeature());
            Plugins.Add(new ServerEventsFeature());

            Plugins.Add(new ValidationFeature());
            container.RegisterValidators(typeof(AutoValidationValidator).Assembly);

            var dbFactory = new OrmLiteConnectionFactory(":memory:", SqliteDialect.Provider);

            container.Register <IDbConnectionFactory>(dbFactory);

            dbFactory.RegisterConnection("testdb", "~/App_Data/test.sqlite".MapAbsolutePath(), SqliteDialect.Provider);

            using (var db = dbFactory.OpenDbConnection())
            {
                db.DropAndCreateTable <Rockstar>(); //Create table if not exists
                db.Insert(Rockstar.SeedData);       //Populate with seed data
            }

            using (var db = dbFactory.OpenDbConnection("testdb"))
            {
                db.DropAndCreateTable <Rockstar>(); //Create table if not exists
                db.Insert(new Rockstar(1, "Test", "Database", 27));
            }

            SetConfig(new HostConfig
            {
                AdminAuthSecret = "secret",
                DebugMode       = true,
            });

            if (EnableAuth)
            {
                Plugins.Add(new AuthFeature(() => new AuthUserSession(),
                                            new IAuthProvider[] {
                    new BasicAuthProvider(AppSettings),
                    new CredentialsAuthProvider(AppSettings),
                    new ApiKeyAuthProvider(AppSettings)
                    {
                        RequireSecureConnection = false
                    },
                    new JwtAuthProvider(AppSettings)
                    {
                        AuthKey = JwtRsaPrivateKey != null || JwtRsaPublicKey != null ? null : AesUtils.CreateKey(),
                        RequireSecureConnection = false,
                        HashAlgorithm           = JwtRsaPrivateKey != null || JwtRsaPublicKey != null ? "RS256" : "HS256",
                        PublicKey      = JwtRsaPublicKey,
                        PrivateKey     = JwtRsaPrivateKey,
                        EncryptPayload = JwtEncryptPayload,
                    },
                })
                {
                    IncludeRegistrationService = true,
                });

                container.Resolve <IAuthRepository>().InitSchema();
            }
        }
Example #27
0
        /// <summary>
        /// Application specific configuration
        /// This method should initialize any IoC resources utilized by your web service classes.
        /// </summary>
        public override void Configure(Container container)
        {
            //Console.WriteLine
            LogManager.LogFactory = new ConsoleLogFactory(debugEnabled: true);

            container.Register <IAuthRepository>(c =>
                                                 new OrmLiteAuthRepository(container.Resolve <IDbConnectionFactory>())
            {
                UseDistinctRoleTables = true
            });

            //Create UserAuth RDBMS Tables
            container.Resolve <IAuthRepository>().InitSchema();

            //Also store User Sessions in SQL Server
            container.RegisterAs <OrmLiteCacheClient, ICacheClient>();
            container.Resolve <ICacheClient>().InitSchema();
            container.RegisterAs <OrmLiteAuthRepository, IUserAuthRepository>();

            //Register Autofac IoC container adapter, so ServiceStack can use it
            container.Adapter = new AutofacIocAdapter(autoFacContainer);

            //This method scans the assembly for validators
            container.RegisterValidators(typeof(Api.General.RegistrationValidator).Assembly);

            SetConfig(new HostConfig {
                UseCamelCase = true
            });

            Plugins.Add(new SwaggerFeature {
                UseBootstrapTheme = true
            });
            Plugins.Add(new PostmanFeature());
            Plugins.Add(new CorsFeature());

            //Plugins.Add(new RazorFormat());

            Plugins.Add(new AutoQueryFeature {
                MaxLimit = 100
            });
            Plugins.Add(new AdminFeature());
            Plugins.Add(new ValidationFeature());

            //Plugins.Add(new RegistrationFeature());

            //Add Support for
            Plugins.Add(new AuthFeature(() => new AuthUserSession(),
                                        new IAuthProvider[] {
                new JwtAuthProvider(AppSettings)
                {
                    AuthKey = AesUtils.CreateKey(), RequireSecureConnection = false
                },
                new ApiKeyAuthProvider(AppSettings),            //Sign-in with API Key
                new CredentialsAuthProvider(),                  //Sign-in with UserName/Password credentials
                new BasicAuthProvider(),                        //Sign-in with HTTP Basic Auth
                new DigestAuthProvider(AppSettings),            //Sign-in with HTTP Digest Auth
                new TwitterAuthProvider(AppSettings),           //Sign-in with Twitter
                new FacebookAuthProvider(AppSettings),          //Sign-in with Facebook
                //new YahooOpenIdOAuthProvider(AppSettings),  //Sign-in with Yahoo OpenId
                //new OpenIdOAuthProvider(AppSettings),       //Sign-in with Custom OpenId
                //new GoogleOAuth2Provider(AppSettings),      //Sign-in with Google OAuth2 Provider
                //new LinkedInOAuth2Provider(AppSettings),    //Sign-in with LinkedIn OAuth2 Provider
                //new GithubAuthProvider(AppSettings),        //Sign-in with GitHub OAuth Provider
                //new YandexAuthProvider(AppSettings),        //Sign-in with Yandex OAuth Provider
                //new VkAuthProvider(AppSettings),            //Sign-in with VK.com OAuth Provider
            }));

            using (var db = container.Resolve <IDbConnectionFactory>().Open())
            {
                //Create the PortalTempUser POCO table if it doesn't already exist
                db.CreateTableIfNotExists <PortalTempUser>();
            }
        }
        /// <summary>
        /// 修改歌曲信息协程
        /// </summary>
        /// <param name="dirPath"></param>
        /// <returns></returns>
        private IEnumerator EditComment(string dirPath)
        {
            mCorRunning = true;
            mIgnoreNum  = 0;
            mAllNum     = 0;
            mFailNum    = 0;
            mDealNum    = 0;
            mMapKeyInfo.Clear();

            var pathList = new[] { dirPath };

            if (!mIsFile)
            {
                //判断单文件还是文件夹
                pathList = Directory.GetFiles(dirPath);
            }

            var startTime = Time.realtimeSinceStartup;

            mAllNum = pathList.Length;

            for (var i = 0; i < pathList.Length; i++)
            {
                var path = pathList[i];
                if (path.EndsWith("mp3"))
                {
                    var name = "";
                    var f    = File.Create(path);

                    if (!mTgCover.isOn && f.Tag.Comment.Contains("163"))
                    {
                        //不覆盖
                        Debug.LogWarning("不覆盖已经有Comment的,跳过:" + f.Tag.Title);
                        mIgnoreNum++;
                        continue;
                    }

                    if (!mTgCoverMatch.isOn && MatchTag.Equals(f.Tag.Description))
                    {
                        //不覆盖已经准确匹配过的
                        Debug.LogWarning("不覆盖已经准确匹配过的,跳过:" + f.Tag.Title);
                        mIgnoreNum++;
                        continue;
                    }


                    name = f.Tag.Title.Trim();

                    if (string.IsNullOrEmpty(name))
                    {
                        //Tag里面为空就从路径里面获取
                        name = Path.GetFileNameWithoutExtension(path);
                        // name = path.Substring(path.LastIndexOf("/") + 1);
                        // name = name.Substring(0, name.IndexOf("."));
                    }

                    Debug.Log("歌曲名字: " + name);

                    if (!string.IsNullOrEmpty(name))
                    {
                        if (f.Tag.Performers != null && f.Tag.Performers.Length > 0)
                        {
                            //搜索增加名字
                            name += " " + f.Tag.Performers[0];
                        }

                        mDealNum++;

                        mTvStatus.text = "正在处理:" + mDealNum + "/" + mAllNum + ",忽略:" + mIgnoreNum + ",失败:" + mFailNum;
                        mLog.Enqueue("正在处理 " + f.Tag.Title);

                        if (mTgDiyUrl.isOn)
                        {
                            //自定义修改
                            Debug.Log("自定义修改: " + mDiySongID);
                            mMapKeyInfo.Add(path, new SongInfo()
                            {
                                id = mDiySongID,
                            });
                        }
                        else
                        {
                            yield return(Search(f.Tag, path, name, (songInfo) =>
                            {
                                if (songInfo != null)
                                {
                                    mMapKeyInfo.Add(path, songInfo);
                                }
                                else
                                {
                                    mFailNum++;
                                }

                                f.Dispose();
                            }));
                        }


                        if (i == pathList.Length - 1 || mMapKeyInfo.Count == DetailNum)
                        {
                            //每20条内容或者最后一条了,就获取详情
                            Debug.Log("开始获取详情:" + mDealNum);
                            mLog.Enqueue("开始获取详情:" + mDealNum);
                            var idList = new List <int>();
                            foreach (var keyValuePair in mMapKeyInfo)
                            {
                                idList.Add(keyValuePair.Value.id);
                            }

                            //获取歌曲详情
                            yield return(GetSongDetail(idList.ToArray(), (songs) =>
                            {
                                if (songs != null && songs.Count > 0)
                                {
                                    var keyList = mMapKeyInfo.Keys.ToArray();
                                    foreach (var key in keyList)
                                    {
                                        mMapKeyInfo.TryGetValue(key, out var outInfo);
                                        if (outInfo != null)
                                        {
                                            var isMatch = outInfo.IsMatch;
                                            var songInfo = songs.Find(v => v.id == outInfo.id);
                                            songInfo.IsMatch = isMatch;
                                            //替换搜索的实体为详情得到的实体
                                            mMapKeyInfo[key] = songInfo;
                                        }
                                    }

                                    foreach (var keyValuePair in mMapKeyInfo)
                                    {
                                        var songInfo = keyValuePair.Value;

                                        if (songInfo != null)
                                        {
                                            var fCache = File.Create(keyValuePair.Key);
                                            songInfo.bitrate = fCache.Properties.AudioBitrate * 1000;
                                            var comment = JsonMapper.ToJson(songInfo.ToKeyInfo());
                                            fCache.Tag.Comment = "163 key(Don't modify):" +
                                                                 AesUtils.Encrypt("music:" + comment, AesKey);
                                            //定义是否完全匹配
                                            fCache.Tag.Description = (songInfo.IsMatch ? MatchTag : "");
                                            fCache.Save();
                                            fCache.Dispose();

                                            var fileName = "/" + Path.GetFileName(keyValuePair.Key);
                                            //根据文件名称来删除数据库
                                            mDataDataService?.DeleteRow(fileName);
                                        }
                                        else
                                        {
                                            mFailNum++;
                                        }
                                    }
                                }
                                else
                                {
                                    mFailNum += idList.Count;
                                }
                            }));

                            //清空当前歌曲库
                            mMapKeyInfo.Clear();
                        }
                    }
                }
            }

            mCorRunning = false;
            mBtnEdit.GetComponentInChildren <Text>().text = "开始";
            yield return(null);

            Debug.Log("搜索完毕,耗时:" + (Time.realtimeSinceStartup - startTime) + "秒");
            mTvStatus.text = "处理完毕:" + mDealNum + "/" + mAllNum + ",忽略:" + mIgnoreNum + ",失败:" + mFailNum;
            mLog.Enqueue(mTvStatus.text);

            if (mNeedReOpen)
            {
                if (mDealNum > 0)
                {
                    Debug.Log("需要重启网易云生效");
                    mLog.Enqueue("请重启网易云生效");
                }

                mDataDataService?.Close();
            }
        }
            public void E2EOrdinaryFlowApi1ExtensionsTest()
            {
                string initialEtherBalance = "";
                string finalEtherBalance   = "";
                string DESTNATION_ADDRESS  = "rLUEUviNDaEU395WAdD7osWbzy6v9FqaMY";
                var    RippleBalanceAPIURL = $"https://s.altnet.rippletest.net:51234";
                var    walletBalance       = 0d;
                var    finalBalance        = 0d;
                var    assetId             = "c9cf27b2-9c68-4159-a30f-23a99950d929";
                var    signToken           = "";
                var    signVerToken        = "";
                var    pin = "1111";
                var    signedVerificationToken = "";
                var    WalletId          = "da268259-c2f1-414a-96b1-e0fd5b9b724f";
                var    zeroTransactionId = "";
                var    extension         = "";
                var    pkSecret          = "sapoZtw4oZiwhoHvF6Z7thTGmpaJ6";
                var    volume            = 1m;

                //Step($"Get latest transaction id for wallet {WalletId}", () =>
                //{
                //    zeroTransactionId = GetLatestFinishedTransactionId(WalletId);
                //});

                Step("Get initial balance of Ripple waller: bcn initial balance = GET http://ripplerpc:[email protected]:5005/", () =>
                {
                    var json = "{\"method\": \"account_info\",\"params\": [{\"account\": \"rLUEUviNDaEU395WAdD7osWbzy6v9FqaMY\" }]}";

                    var balancePage = apiV2.CustomRequests.PostResponse(RippleBalanceAPIURL, json);
                    Assert.That(balancePage.StatusCode, Is.EqualTo(HttpStatusCode.OK), "Could not get initial Ripple balance");

                    initialEtherBalance = JsonConvert.DeserializeObject <ExtensionBalanceResponse>(balancePage.Content).result.account_data.Balance;
                });

                Step("Get initial balance of lykke client wallet. initial balance = GET https://api-test.lykkex.net/api/Wallets assets.id = e58aa37d - dd46 - 4bdb - bac1 - a6d0d44e6dc9 assets.Balance-> % initialBalance % ", () =>
                {
                    var wallet         = WalletApi.Wallets.GetWallets(BearerToken);
                    var balances       = apiV2.wallets.GetWalletsBalances(BearerToken).ResponseObject;
                    var walletBalances = balances.First().Balances.ToList();
                    var assetBalance   = walletBalances.Find(b => b.AssetId == assetId);

                    walletBalance = assetBalance.Balance;
                });

                Step("GET https://api-test.lykkex.net/api/signatureVerificationToken/KeyConfirmation?email=%email%", () =>
                {
                    var signTokenResponse = WalletApi.SignatureVerificationToken.GetKeyConfirmation(wallet.WalletAddress, BearerToken);
                    Assert.That(signTokenResponse.StatusCode, Is.EqualTo(HttpStatusCode.OK));

                    signToken    = signTokenResponse.ResponseObject.Result.Message.ToString();
                    signVerToken = signToken;

                    //
                    WalletApi.PinSecurity.GetPinSecurity(pin, BearerToken).Validate.StatusCode(HttpStatusCode.OK).Validate.NoApiError("Please Reset Pin for user in Back Office");

                    WalletApi.Client.GetClientCodes(BearerToken).Validate.StatusCode(HttpStatusCode.OK).Validate.NoApiError();

                    string accessToken = WalletApi.Client.PostClientCodes(new SubmitCodeModel("0000"), BearerToken).Validate.StatusCode(HttpStatusCode.OK)
                                         .Validate.NoApiError().GetResponseObject().Result.AccessToken;

                    string encodedPrivateKey = WalletApi.Client
                                               .PostClientEncodedMainKey(new AccessTokenModel(accessToken), BearerToken)
                                               .Validate.StatusCode(HttpStatusCode.OK).Validate.NoApiError()
                                               .GetResponseObject().Result.EncodedPrivateKey;

                    string privateKeyStr = AesUtils.Decrypt(encodedPrivateKey, wallet.WalletKey);
                    Key privateKey       = Key.Parse(privateKeyStr);
                    //

                    signToken = privateKey.SignMessage(signToken);
                });

                Step("POST https://api-test.lykkex.net/api/signatureVerificationToken/KeyConfirmation", () =>
                {
                    var postSignResponse = WalletApi.SignatureVerificationToken.PostKeyConfirmation(new RecoveryTokenChallangeResponse {
                        Email = wallet.WalletAddress, SignedMessage = signToken
                    }, BearerToken);
                    Assert.That(postSignResponse.StatusCode, Is.EqualTo(HttpStatusCode.OK));
                    signedVerificationToken = postSignResponse.ResponseObject.Result.AccessToken;
                });

                Step("POST https://api-test.lykkex.net/api/HotWallet/cashout", () =>
                {
                    var postCashOut = WalletApi.HotWallet.PostCashOut(new HotWalletCashoutOperation
                    {
                        AssetId                     = assetId,
                        DestinationAddress          = DESTNATION_ADDRESS,
                        DestinationAddressExtension = "",
                        Volume = (double)volume
                    }, signedVerificationToken, BearerToken);

                    Assert.That(postCashOut.StatusCode, Does.Not.EqualTo(HttpStatusCode.NotFound).And.Not.EqualTo(HttpStatusCode.InternalServerError).And.Not.EqualTo(HttpStatusCode.BadGateway), "Wrong Cashout Status code");
                });

                Step("Delay ~ 20min cashout confirmation and waiting fo Finished status", () =>
                {
                    if (!WaitForLatestHistoryResponseGotFinishedState(WalletId, TimeSpan.FromMinutes(20)))
                    {
                        Assert.Fail("Cashout comfirmation does not exist afer 20 minutes");
                    }
                    Assert.That(GetLatestFinishedTransactionId(WalletId), Does.Not.EqualTo(zeroTransactionId), "Latest transaction ID is the same as before test. History service does not know about our transaction. POST cashout failed?");
                });

                Step("Get Final Balance; final balance = GET https://api-test.lykkex.net/api/Wallets assets.id = e58aa37d - dd46 - 4bdb  - bac1 - a6d0d44e6dc9 assets.Balance-> % finalBalance %      initialBalance + finalBalance = %Volume - %feeSize", () =>
                {
                    var wallet         = WalletApi.Wallets.GetWallets(BearerToken);
                    var balances       = apiV2.wallets.GetWalletsBalances(BearerToken).ResponseObject;
                    var walletBalances = balances.First().Balances.ToList();
                    var assetBalance   = walletBalances.Find(b => b.AssetId == assetId);

                    finalBalance = assetBalance.Balance;
                });

                Step("bcn final balance = GET https://ropsten.etherscan.io/address/0x856924997fa22efad8dc75e83acfa916490989a4 . Validate that final balance on ether wallet is initial balance + volume cashout ", () =>
                {
                    var json = "{\"method\": \"account_info\",\"params\": [{\"account\": \"rLUEUviNDaEU395WAdD7osWbzy6v9FqaMY\" }]}";

                    var balancePage = apiV2.CustomRequests.PostResponse(RippleBalanceAPIURL, json);
                    Assert.That(balancePage.StatusCode, Is.EqualTo(HttpStatusCode.OK), "Could not get initial Ripple balance");

                    Assert.That(() => decimal.Parse(
                                    JsonConvert.DeserializeObject <ExtensionBalanceResponse>(apiV2.CustomRequests.PostResponse(RippleBalanceAPIURL, json).Content).result.account_data.Balance

                                    ), Is.EqualTo(decimal.Parse(initialEtherBalance) + volume * (decimal)Math.Pow(10, 6)).After(3).Minutes.PollEvery(2).Seconds);
                });
            }
            public void E2EOrdinaryCashOutNumerousTest()
            {
                string initialEtherBalance = "";
                string finalEtherBalance   = "";
                string DESTNATION_ADDRESS  = "0x856924997fa22efad8dc75e83acfa916490989a4";
                var    EtherBalanceAPIURL  = $"https://api-ropsten.etherscan.io/api?module=account&action=balance&address={DESTNATION_ADDRESS}&tag=latest";
                var    walletBalance       = 0d;
                var    finalBalance        = 0d;
                var    assetId             = "e58aa37d-dd46-4bdb-bac1-a6d0d44e6dc9";
                var    signToken           = "";
                var    signVerToken        = "";
                var    pin = "1111";
                var    signedVerificationToken = "";
                var    WalletId          = "da268259-c2f1-414a-96b1-e0fd5b9b724f";
                var    zeroTransactionId = "";

                Step($"Get latest transaction id for wallet {WalletId}", () =>
                {
                    zeroTransactionId = GetLatestFinishedTransactionId(WalletId);
                });

                Step("Get initial balance of Ether waller: bcn initial balance = GET https://ropsten.etherscan.io/address/0x856924997fa22efad8dc75e83acfa916490989a4   Balance: % somebalance % Ether-> % inicialBcnBalance % ", () =>
                {
                    var balancePage = apiV2.CustomRequests.GetResponse(EtherBalanceAPIURL);
                    Assert.That(balancePage.StatusCode, Is.EqualTo(HttpStatusCode.OK), "Could not get initial ETHER balance");

                    initialEtherBalance = JsonConvert.DeserializeObject <EtherBalanceObjectModel>(balancePage.Content).result;
                });

                Step("Get initial balance of lykke client wallet. initial balance = GET https://api-test.lykkex.net/api/Wallets assets.id = e58aa37d - dd46 - 4bdb - bac1 - a6d0d44e6dc9 assets.Balance-> % initialBalance % ", () =>
                {
                    var wallet         = WalletApi.Wallets.GetWallets(BearerToken);
                    var balances       = apiV2.wallets.GetWalletsBalances(BearerToken).ResponseObject;
                    var walletBalances = balances.First().Balances.ToList();
                    var assetBalance   = walletBalances.Find(b => b.AssetId == assetId);

                    walletBalance = assetBalance.Balance;
                });

                Step("GET https://api-test.lykkex.net/api/signatureVerificationToken/KeyConfirmation?email=%email%", () =>
                {
                    var signTokenResponse = WalletApi.SignatureVerificationToken.GetKeyConfirmation(wallet.WalletAddress, BearerToken);
                    Assert.That(signTokenResponse.StatusCode, Is.EqualTo(HttpStatusCode.OK));

                    signToken    = signTokenResponse.ResponseObject.Result.Message.ToString();
                    signVerToken = signToken;

                    //
                    WalletApi.PinSecurity.GetPinSecurity(pin, BearerToken).Validate.StatusCode(HttpStatusCode.OK).Validate.NoApiError("Please Reset Pin for user in Back Office");

                    WalletApi.Client.GetClientCodes(BearerToken).Validate.StatusCode(HttpStatusCode.OK).Validate.NoApiError();

                    string accessToken = WalletApi.Client.PostClientCodes(new SubmitCodeModel("0000"), BearerToken).Validate.StatusCode(HttpStatusCode.OK)
                                         .Validate.NoApiError().GetResponseObject().Result.AccessToken;

                    string encodedPrivateKey = WalletApi.Client
                                               .PostClientEncodedMainKey(new AccessTokenModel(accessToken), BearerToken)
                                               .Validate.StatusCode(HttpStatusCode.OK).Validate.NoApiError()
                                               .GetResponseObject().Result.EncodedPrivateKey;

                    string privateKeyStr = AesUtils.Decrypt(encodedPrivateKey, wallet.WalletKey);
                    Key privateKey       = Key.Parse(privateKeyStr);
                    //

                    signToken = privateKey.SignMessage(signToken);
                });

                Step("POST https://api-test.lykkex.net/api/signatureVerificationToken/KeyConfirmation", () =>
                {
                    var postSignResponse = WalletApi.SignatureVerificationToken.PostKeyConfirmation(new RecoveryTokenChallangeResponse {
                        Email = wallet.WalletAddress, SignedMessage = signToken
                    }, BearerToken);
                    Assert.That(postSignResponse.StatusCode, Is.EqualTo(HttpStatusCode.OK));
                    signedVerificationToken = postSignResponse.ResponseObject.Result.AccessToken;
                });

                Step("POST https://api-test.lykkex.net/api/HotWallet/cashout", () =>
                {
                    var postCashOut = WalletApi.HotWallet.PostCashOut(new HotWalletCashoutOperation
                    {
                        AssetId                     = assetId,
                        DestinationAddress          = DESTNATION_ADDRESS,
                        DestinationAddressExtension = "",
                        Volume = 0.0001
                    }, signedVerificationToken, BearerToken);

                    Assert.That(postCashOut.StatusCode, Does.Not.EqualTo(HttpStatusCode.NotFound).And.Not.EqualTo(HttpStatusCode.InternalServerError).And.Not.EqualTo(HttpStatusCode.BadGateway), "Wrong Cashout Status code");

                    for (int i = 0; i < 2; i++)
                    {
                        signedVerificationToken = GetApi1SignVerToken();
                        postCashOut             = WalletApi.HotWallet.PostCashOut(new HotWalletCashoutOperation
                        {
                            AssetId                     = assetId,
                            DestinationAddress          = DESTNATION_ADDRESS,
                            DestinationAddressExtension = "",
                            Volume = 0.0001
                        }, signedVerificationToken, BearerToken);

                        Assert.That(postCashOut.StatusCode, Does.Not.EqualTo(HttpStatusCode.NotFound).And.Not.EqualTo(HttpStatusCode.InternalServerError).And.Not.EqualTo(HttpStatusCode.BadGateway), "Wrong Cashout Status code");
                    }
                });

                Step("Delay ~ 20min cashout confirmation and waiting fo Finished status", () =>
                {
                    if (!WaitForLatestHistoryResponseGotFinishedState(WalletId, TimeSpan.FromMinutes(20)))
                    {
                        Assert.Fail("Cashout comfirmation does not exist afer 20 minutes");
                    }
                    Assert.That(GetLatestFinishedTransactionId(WalletId), Does.Not.EqualTo(zeroTransactionId), "Latest transaction ID is the same as before test. History service does not know about our transaction. POST cashout failed?");
                });

                Step("Get Final Balance; final balance = GET https://api-test.lykkex.net/api/Wallets assets.id = e58aa37d - dd46 - 4bdb  - bac1 - a6d0d44e6dc9 assets.Balance-> % finalBalance %      initialBalance + finalBalance = %Volume - %feeSize", () =>
                {
                    var wallet         = WalletApi.Wallets.GetWallets(BearerToken);
                    var balances       = apiV2.wallets.GetWalletsBalances(BearerToken).ResponseObject;
                    var walletBalances = balances.First().Balances.ToList();
                    var assetBalance   = walletBalances.Find(b => b.AssetId == assetId);

                    finalBalance = assetBalance.Balance;
                });

                Step("bcn final balance = GET https://ropsten.etherscan.io/address/0x856924997fa22efad8dc75e83acfa916490989a4 . Validate that final balance on ether wallet is initial balance + 20* volume cashout ", () =>
                {
                    var balancePage = apiV2.CustomRequests.GetResponse(EtherBalanceAPIURL);
                    Assert.That(balancePage.StatusCode, Is.EqualTo(HttpStatusCode.OK), "Could not get initial ETHER balance");

                    finalEtherBalance = JsonConvert.DeserializeObject <EtherBalanceObjectModel>(balancePage.Content).result;

                    Assert.That(decimal.Parse(finalEtherBalance), Is.EqualTo(decimal.Parse(initialEtherBalance) + 22 * 100m));
                });
            }