Пример #1
0
        public void Capability_WithMultipleResources_OrdersThemInAlphabeticalOrder()
        {
            var capability = new Capability();

            capability.AddResource("second").AllowPublish();
            capability.AddResource("first").AllowAll();

            Assert.Equal("{\"first\":[\"*\"],\"second\":[\"publish\"]}", capability.ToJson());
        }
Пример #2
0
        public async Task WithDefaultTokenParamsAndTokenParamsSpecified_ShouldUseOnlyParamsPassedIntoTheMethod()
        {
            var client = GetRestClient(
                null,
                options => options.DefaultTokenParams = new TokenParams
            {
                ClientId = "123", Ttl = TimeSpan.FromHours(2)
            });

            var capability = new Capability();

            capability.AddResource("a").AllowAll();
            var methodParams = new TokenParams
            {
                Capability = capability,
                ClientId   = "999",
                Ttl        = TimeSpan.FromMinutes(1),
                Nonce      = "123",
                Timestamp  = Now.AddHours(1)
            };

            await client.Auth.RequestTokenAsync(methodParams);

            var data = LastRequest.PostData as TokenRequest;

            data.Capability.Should().Be(capability);
            data.ClientId.Should().Be(methodParams.ClientId);
            data.Ttl.Should().Be(methodParams.Ttl);
            data.Nonce.Should().Be(methodParams.Nonce);
            data.Timestamp.Should().Be(methodParams.Timestamp);
        }
Пример #3
0
        public void ShouldReturnTheRequestedToken()
        {
            //Arrange
            var ttl        = TimeSpan.FromSeconds(30 * 60);
            var capability = new Capability();

            capability.AddResource("foo").AllowPublish();

            RestClient ably    = GetRestClient();
            var        options = ably.Options;

            //Act
            var token = ably.Auth.RequestToken(new TokenRequest {
                Capability = capability, Ttl = ttl
            }, null);

            //Assert
            var key   = options.ParseKey();
            var appId = key.KeyName.Split('.').First();

            token.Token.Should().MatchRegex(string.Format(@"^{0}\.[\w-]+$", appId));
            token.KeyName.Should().Be(key.KeyName);
            token.Issued.Should().BeWithin(TimeSpan.FromSeconds(30)).Before(DateTime.UtcNow);
            token.Expires.Should().BeWithin(TimeSpan.FromSeconds(30)).Before(DateTime.UtcNow + ttl);
        }
Пример #4
0
        public async Task WithTokenId_AuthenticatesSuccessfullyOverHttpAndHttps(Protocol protocol)
        {
            var capability = new Capability();

            capability.AddResource("foo").AllowPublish();

            var ably = await GetRestClient(protocol);

            var token = await ably.Auth.RequestTokenAsync(CreateTokenParams(capability), null);

            var options = await Fixture.GetSettings();

            var httpTokenAbly =
                new AblyRest(new ClientOptions {
                Token = token.Token, Environment = options.Environment, Tls = false
            });
            var httpsTokenAbly =
                new AblyRest(new ClientOptions {
                Token = token.Token, Environment = options.Environment, Tls = true
            });

            //If it doesn't throw we are good :)
            await httpTokenAbly.Channels.Get("foo").PublishAsync("test", "true");

            await httpsTokenAbly.Channels.Get("foo").PublishAsync("test", "true");
        }
Пример #5
0
        public void FromJson_ParsesTokenCorrectly()
        {
            string json = @"{
	                            ""access_token"": {
		                            ""token"": ""QF_CjTvDs2kFQMKLwpccEhIkNcKpw5ovPsOnLsOgJMKow5ACXHvCgGzCtcK7"",
		                            ""key"": ""3lJG9Q"",
		                            ""issued"": 1430784000000,
		                            ""expires"": 1430784000000,
		                            ""capability"": {
			                            ""*"": [
				                            ""*""
			                            ]
		                            }
	                            }
                            }";

            var token = JsonHelper.DeserializeObject <TokenDetails>((JObject)JObject.Parse(json)["access_token"]);

            Assert.Equal("QF_CjTvDs2kFQMKLwpccEhIkNcKpw5ovPsOnLsOgJMKow5ACXHvCgGzCtcK7", token.Token);
            //Assert.Equal("3lJG9Q", token.ClientId
            Assert.Equal(1430784000000, token.Issued.ToUnixTimeInMilliseconds());
            Assert.Equal(1430784000000, token.Expires.ToUnixTimeInMilliseconds());
            var expectedCapability = new Capability();

            expectedCapability.AddResource("*").AllowAll();
            Assert.Equal(expectedCapability.ToJson(), token.Capability.ToJson());
        }
Пример #6
0
        public void Capability_WithResourceThatHasPublishAndThenAll_ReturnsJsonWithResourceEqualToStarWithoutShowingPublish()
        {
            var capability = new Capability();

            capability.AddResource("name").AllowPublish().AllowAll();

            Assert.Equal("{\"name\":[\"*\"]}", capability.ToJson());
        }
Пример #7
0
        public void Capability_WithResourceThatHasNoAllowedOperations_DoesNotIncludeResourceInJson()
        {
            var capability = new Capability();

            capability.AddResource("name");

            Assert.Equal("", capability.ToJson());
        }
Пример #8
0
        public void Capability_WithResourceThatHasNoAllowedOperations_DoesNotIncludeResourceInJson()
        {
            var capability = new Capability();

            capability.AddResource("name");

            capability.ToJson().Should().Be(string.Empty);
        }
Пример #9
0
        public void Capability_WithResourceThatHasPublishSubscribeAndPresence_ReturnsJsonStringWithCorrectResourceOrder()
        {
            var capability = new Capability();

            capability
            .AddResource("name").AllowSubscribe().AllowPublish().AllowPresence();

            Assert.Equal("{\"name\":[\"presence\",\"publish\",\"subscribe\"]}", capability.ToJson());
        }
Пример #10
0
        public void Capability_WithResource_ReturnsCorrectJsonString()
        {
            var capability = new Capability();

            capability
            .AddResource("name").AllowPublish();

            capability.ToJson().Should().Be("{\"name\":[\"publish\"]}");
        }
Пример #11
0
        public void Capability_WithResource_ReturnsCorrectJsonString()
        {
            var capability = new Capability();

            capability
            .AddResource("name").AllowPublish();

            Assert.Equal("{\"name\":[\"publish\"]}", capability.ToJson());
        }
Пример #12
0
        public void CanSerializeAndDeserialiseCapabilityObject()
        {
            var allAllowed      = Capability.AllowAll;
            var withOneResource = new Capability();

            withOneResource.AddResource("test").AllowPresence().AllowPublish().AllowSubscribe();
            var withTwoResources = new Capability();

            withTwoResources.AddResource("one").AllowAll();
            withTwoResources.AddResource("two").AllowPublish().AllowSubscribe();

            var list = new[] { allAllowed, withOneResource, withTwoResources };

            foreach (var item in list)
            {
                var data     = MsgPackHelper.Serialise(item);
                var unpacked = MsgPackHelper.Deserialise(data, typeof(Capability));
                Assert.Equal(item, unpacked);
            }
        }
Пример #13
0
        public void WithOverridingCapability_OverridesTheDefault()
        {
            var capability = new Capability();

            capability.AddResource("test").AllowAll();
            var tokenRequest = new TokenRequest {
                Capability = capability
            };

            RequestToken(tokenRequest, null, (data, request) => Assert.Equal(capability.ToJson(), data.capability));
        }
Пример #14
0
            public async Task WithCapabilitySpecifiedInTokenParams_ShouldPassTheJsonStringToRequest()
            {
                var capability = new Capability();

                capability.AddResource("a").AllowAll();
                var customParams = new TokenParams {
                    Capability = capability
                };
                var request = await CreateTokenRequest(Client, customParams);

                request.Capability.Should().Be(capability);
            }
        public void WithCapabilityOverridesDefault()
        {
            var capability = new Capability();

            capability.AddResource("test").AllowAll();

            var data = Client.Auth.CreateTokenRequest(new TokenRequest()
            {
                Capability = capability
            }, null);

            data.capability.Should().Be(capability.ToJson());
        }
Пример #16
0
        public async Task ShouldReturnTheRequestedToken(Protocol protocol)
        {
            var ttl        = TimeSpan.FromSeconds(30 * 60);
            var capability = new Capability();

            capability.AddResource("foo").AllowPublish();

            var ably = await GetRestClient(protocol);

            var options = ably.Options;

            var token = await ably.Auth.RequestTokenAsync(CreateTokenParams(capability, ttl), null);

            var key   = options.ParseKey();
            var appId = key.KeyName.Split('.').First();

            token.Token.Should().MatchRegex($@"^{appId}\.[\w-]+$");
            token.Issued.Should().BeWithin(TimeSpan.FromSeconds(30)).Before(DateTimeOffset.UtcNow);
            token.Expires.Should().BeWithin(TimeSpan.FromSeconds(30)).Before(DateTimeOffset.UtcNow + ttl);
        }
Пример #17
0
        public void WithTokenId_AuthenticatesSuccessfully()
        {
            //Arrange
            var capability = new Capability();

            capability.AddResource("foo").AllowPublish();

            var ably  = GetRestClient();
            var token = ably.Auth.RequestToken(new TokenRequest()
            {
                Capability = capability
            }, null);

            var tokenAbly = new RestClient(new AblyOptions {
                Token = token.Token, Environment = TestsSetup.TestData.Environment
            });

            //Act & Assert
            Assert.DoesNotThrow(delegate { tokenAbly.Channels.Get("foo").Publish("test", true); });
        }
Пример #18
0
        public async Task WithTokenId_WhenTryingToPublishToUnspecifiedChannel_ThrowsAblyException(Protocol protocol)
        {
            var capability = new Capability();

            capability.AddResource("foo").AllowPublish();

            var ably = await GetRestClient(protocol);

            var token = ably.Auth.RequestTokenAsync(CreateTokenParams(capability), null).Result;

            var tokenAbly = new AblyRest(new ClientOptions {
                Token = token.Token, Environment = "sandbox"
            });

            var error =
                await
                Assert.ThrowsAsync <AblyException>(() => tokenAbly.Channels.Get("boo").PublishAsync("test", "true"));

            error.ErrorInfo.Code.Should().Be(40160);
            error.ErrorInfo.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
        }
Пример #19
0
        public void WithTokenId_WhenTryingToPublishToUnspecifiedChannel_ThrowsAblyException()
        {
            //Arrange
            var capability = new Capability();

            capability.AddResource("foo").AllowPublish();

            var ably = GetRestClient();

            var token = ably.Auth.RequestToken(new TokenRequest()
            {
                Capability = capability
            }, null);

            var tokenAbly = new RestClient(new AblyOptions {
                Token = token.Token, Environment = AblyEnvironment.Sandbox
            });

            //Act & Assert
            var error = Assert.Throws <AblyException>(delegate { tokenAbly.Channels.Get("boo").Publish("test", true); });

            error.ErrorInfo.Code.Should().Be(40160);
            error.ErrorInfo.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
        }
Пример #20
0
        public async Task WithConnectedClient_WhenDowngradingCapabilities_ChannelShouldBecomeFailed(Protocol protocol)
        {
            var clientId         = "RTC8a1-downgrade".AddRandomSuffix();
            var channelName      = "RTC8a1-downgrade-channel".AddRandomSuffix();
            var wrongChannelName = "wrong".AddRandomSuffix();

            var(realtime, channel) = await SetupRealtimeClient();

            channel.On(statechange => Output.WriteLine($"Changed state: {statechange.Previous} to {statechange.Current}. Error: {statechange.Error}"));
            realtime.Connection.Once(ConnectionEvent.Disconnected, change => throw new Exception("Should not require a disconnect"));

            var result = await channel.PublishAsync("test", "should-not-fail");

            result.IsSuccess.Should().BeTrue();

            ChannelStateChange stateChange = null;

            var failedAwaiter = new TaskCompletionAwaiter(2000);

            channel.Once(ChannelEvent.Failed, state =>
            {
                stateChange = state;
                failedAwaiter.SetCompleted();
            });
            await DowngradeCapability(realtime);

            await channel.WaitForState(ChannelState.Failed, TimeSpan.FromSeconds(6));

            await failedAwaiter.Task;

            stateChange.Should().NotBeNull("channel should have failed");
            stateChange.Error.Code.Should().Be(ErrorCodes.OperationNotPermittedWithCapability);
            stateChange.Error.Message.Should().Contain("Channel denied access");

            async Task DowngradeCapability(AblyRealtime rt)
            {
                var capability = new Capability();

                capability.AddResource(wrongChannelName).AllowSubscribe();

                var newToken = await rt.Auth.AuthorizeAsync(new TokenParams
                {
                    Capability = capability,
                    ClientId   = clientId,
                });

                newToken.Should().NotBeNull();
            }

            async Task <(AblyRealtime, IRealtimeChannel)> SetupRealtimeClient()
            {
                var capability = new Capability();

                capability.AddResource(channelName).AllowAll();

                var restClient = await GetRestClient(protocol);

                var tokenDetails = await restClient.Auth.RequestTokenAsync(new TokenParams
                {
                    ClientId   = clientId,
                    Capability = capability
                });

                var rt = await GetRealtimeClient(protocol, (opts, _) => { opts.Token = tokenDetails.Token; });

                await rt.WaitForState(ConnectionState.Connected);

                var ch = rt.Channels.Get(channelName);
                await ch.AttachAsync();

                return(rt, ch);
            }
        }
Пример #21
0
        public async Task WithConnectedClient_WhenUpgradingCapabilities_ConnectionShouldNotBeImpaired(Protocol protocol)
        {
            var clientId   = "RTC8a1".AddRandomSuffix();
            var capability = new Capability();

            capability.AddResource("foo").AllowPublish();

            var restClient = await GetRestClient(protocol, options => { options.UseTokenAuth = true; });

            var tokenDetails = await restClient.Auth.RequestTokenAsync(new TokenParams
            {
                ClientId   = clientId,
                Capability = capability,
            });

            var realtime = await GetRealtimeClient(protocol, (opts, _) =>
            {
                opts.Token = tokenDetails.Token;
            });

            await realtime.WaitForState();

            // upgrade of capabilities without any loss of continuity or connectivity
            realtime.Connection.Once(ConnectionEvent.Disconnected, change => throw new Exception("should not disconnect"));

            var fooChannel = realtime.Channels.Get("foo");
            var barChannel = realtime.Channels.Get("bar");

            var fooSuccessAWaiter = new TaskCompletionAwaiter(5000);

            fooChannel.Publish("test", "should-not-fail", (b, info) =>
            {
                // foo should succeed
                b.Should().BeTrue();
                info.Should().BeNull();
                fooSuccessAWaiter.SetCompleted();
            });
            fooChannel.Attach();
            Assert.True(await fooSuccessAWaiter.Task);

            var barFailAwaiter = new TaskCompletionAwaiter(5000);

            barChannel.Publish("test", "should-fail", (b, info) =>
            {
                // bar should fail
                b.Should().BeFalse();
                info.Code.Should().Be(ErrorCodes.OperationNotPermittedWithCapability);
                barFailAwaiter.SetCompleted();
            });
            barChannel.Attach();
            Assert.True(await barFailAwaiter.Task);

            // upgrade bar
            capability = new Capability();
            capability.AddResource("bar").AllowPublish();
            await realtime.Auth.AuthorizeAsync(new TokenParams
            {
                Capability = capability,
                ClientId   = clientId,
            });

            realtime.Connection.State.Should().Be(ConnectionState.Connected);
            var barSuccessAwaiter = new TaskCompletionAwaiter(5000);

            barChannel.Attach((b2, info2) =>
            {
                b2.Should().BeTrue();
                barChannel.Publish("test", "should-succeed", (b, info) =>
                {
                    b.Should().BeTrue();
                    info.Should().BeNull();
                    barSuccessAwaiter.SetCompleted();
                });
            });

            Assert.True(await barSuccessAwaiter.Task);
        }