Skip to content

Commit

Permalink
fix: add missing 'data' property in JWT tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
Tr00d committed Nov 21, 2024
1 parent 57c2257 commit 4f52489
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 91 deletions.
3 changes: 2 additions & 1 deletion OpenTok/Util/TokenGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ internal Dictionary<string, object> GeneratePayload()
{ "iat", creationTime },
{ "jti", GenerateTokenId() },
{ "initial_layout_list", string.Join(" ", InitialLayoutClasses) },
{ "nonce", OpenTokUtils.GetRandomNumber() }
{ "nonce", OpenTokUtils.GetRandomNumber() },
{ "data", this.Data },
};

return payload;
Expand Down
171 changes: 81 additions & 90 deletions OpenTokTest/TokenTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,71 +3,69 @@
using System.Globalization;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using FluentAssertions;
using Microsoft.IdentityModel.Tokens;
using Xunit;
using OpenTokSDK;
using OpenTokSDK.Util;
using OpenTokSDK.Exception;
using OpenTokSDK.Util;
using Xunit;

namespace OpenTokSDKTest
{
public class T1TokenTests : TestBase
{
[Fact]
public void GenerateTokenTest()
public void GenerateInvalidTokensTest()
{
OpenTok opentok = new OpenTok(ApiKey, ApiSecret);

String sessionId = "1_MX4xMjM0NTZ-flNhdCBNYXIgMTUgMTQ6NDI6MjMgUERUIDIwMTR-MC40OTAxMzAyNX4";
string token = opentok.GenerateT1Token(sessionId);
var opentok = new OpenTok(ApiKey, ApiSecret);
Assert.Throws<OpenTokArgumentException>(() => opentok.GenerateT1Token(null));
Assert.Throws<OpenTokArgumentException>(() => opentok.GenerateT1Token(""));
Assert.Throws<OpenTokArgumentException>(() => opentok.GenerateT1Token(string.Empty));
Assert.Throws<OpenTokArgumentException>(() => opentok.GenerateT1Token("NOT A VALID SESSION ID"));
}

[Fact]
public void GenerateTokenTest()
{
var opentok = new OpenTok(ApiKey, ApiSecret);
var sessionId = "1_MX4xMjM0NTZ-flNhdCBNYXIgMTUgMTQ6NDI6MjMgUERUIDIwMTR-MC40OTAxMzAyNX4";
var token = opentok.GenerateT1Token(sessionId);
Assert.NotNull(token);
var data = CheckToken(token);

Assert.Equal(data["partner_id"], ApiKey.ToString());
Assert.NotNull(data["sig"]);
Assert.NotNull(data["create_time"]);
Assert.NotNull(data["nonce"]);
Assert.Equal(data["role"], "publisher");

Check warning on line 40 in OpenTokTest/TokenTests.cs

View workflow job for this annotation

GitHub Actions / build

The literal or constant value "publisher" should be passed as the 'expected' argument in the call to 'Assert.Equal(expected, actual)' in method 'GenerateTokenTest' on type 'T1TokenTests'. Swap the parameter values. (https://xunit.net/xunit.analyzers/rules/xUnit2000)
}

[Theory]
[InlineData(Role.SUBSCRIBER, "subscriber")]
[InlineData(Role.PUBLISHER, "publisher")]
[InlineData(Role.MODERATOR, "moderator")]
[InlineData(Role.PUBLISHERONLY, "publisheronly")]
public void GenerateTokenWithRoleTest(Role role, string expectedRole)
[Fact]
public void GenerateTokenWithConnectionDataTest()
{
OpenTok opentok = new OpenTok(ApiKey, ApiSecret);

String sessionId = "1_MX4xMjM0NTZ-flNhdCBNYXIgMTUgMTQ6NDI6MjMgUERUIDIwMTR-MC40OTAxMzAyNX4";
string token = opentok.GenerateT1Token(sessionId, role: role);

var opentok = new OpenTok(ApiKey, ApiSecret);
var connectionData = "Somedatafortheconnection";
var sessionId = "1_MX4xMjM0NTZ-flNhdCBNYXIgMTUgMTQ6NDI6MjMgUERUIDIwMTR-MC40OTAxMzAyNX4";
var token = opentok.GenerateT1Token(sessionId, data: connectionData);
Assert.NotNull(token);
var data = CheckToken(token);

Assert.Equal(data["partner_id"], ApiKey.ToString());
Assert.NotNull(data["sig"]);
Assert.NotNull(data["create_time"]);
Assert.NotNull(data["nonce"]);
Assert.Equal(data["role"], expectedRole);
Assert.Equal(data["role"], "publisher");

Check warning on line 56 in OpenTokTest/TokenTests.cs

View workflow job for this annotation

GitHub Actions / build

The literal or constant value "publisher" should be passed as the 'expected' argument in the call to 'Assert.Equal(expected, actual)' in method 'GenerateTokenWithConnectionDataTest' on type 'T1TokenTests'. Swap the parameter values. (https://xunit.net/xunit.analyzers/rules/xUnit2000)
Assert.Equal(data["connection_data"], connectionData);
}

[Fact]
public void GenerateTokenWithExpireTimeTest()
{
OpenTok opentok = new OpenTok(ApiKey, ApiSecret);
double expireTime = OpenTokUtils.GetCurrentUnixTimeStamp() + 10;

String sessionId = "1_MX4xMjM0NTZ-flNhdCBNYXIgMTUgMTQ6NDI6MjMgUERUIDIwMTR-MC40OTAxMzAyNX4";
string token = opentok.GenerateT1Token(sessionId, expireTime: expireTime);

var opentok = new OpenTok(ApiKey, ApiSecret);
var expireTime = OpenTokUtils.GetCurrentUnixTimeStamp() + 10;
var sessionId = "1_MX4xMjM0NTZ-flNhdCBNYXIgMTUgMTQ6NDI6MjMgUERUIDIwMTR-MC40OTAxMzAyNX4";
var token = opentok.GenerateT1Token(sessionId, expireTime: expireTime);
Assert.NotNull(token);
var data = CheckToken(token);

Assert.Equal(data["partner_id"], ApiKey.ToString());
Assert.NotNull(data["sig"]);
Assert.NotNull(data["create_time"]);
Expand All @@ -77,75 +75,61 @@ public void GenerateTokenWithExpireTimeTest()
}

[Fact]
public void GenerateTokenWithConnectionDataTest()
public void GenerateTokenWithInitialLayoutClass()
{
OpenTok opentok = new OpenTok(ApiKey, ApiSecret);
string connectionData = "Somedatafortheconnection";
String sessionId = "1_MX4xMjM0NTZ-flNhdCBNYXIgMTUgMTQ6NDI6MjMgUERUIDIwMTR-MC40OTAxMzAyNX4";
string token = opentok.GenerateT1Token(sessionId, data:connectionData);

var opentok = new OpenTok(ApiKey, ApiSecret);
var sessionId = "1_MX4xMjM0NTZ-flNhdCBNYXIgMTUgMTQ6NDI6MjMgUERUIDIwMTR-MC40OTAxMzAyNX4";
var initalLayoutClassList = new List<string>();
initalLayoutClassList.Add("focus");
var token = opentok.GenerateT1Token(sessionId, initialLayoutClassList: initalLayoutClassList);
Assert.NotNull(token);
var data = CheckToken(token);

Assert.Equal(data["partner_id"], ApiKey.ToString());
Assert.NotNull(data["sig"]);
Assert.NotNull(data["create_time"]);
Assert.NotNull(data["nonce"]);
Assert.Equal(data["role"], "publisher");

Check warning on line 91 in OpenTokTest/TokenTests.cs

View workflow job for this annotation

GitHub Actions / build

The literal or constant value "publisher" should be passed as the 'expected' argument in the call to 'Assert.Equal(expected, actual)' in method 'GenerateTokenWithInitialLayoutClass' on type 'T1TokenTests'. Swap the parameter values. (https://xunit.net/xunit.analyzers/rules/xUnit2000)
Assert.Equal(data["connection_data"], connectionData);
Assert.Equal("focus", data["initial_layout_class_list"]);
}

[Fact]
public void GenerateTokenWithInitialLayoutClass()
[Theory]
[InlineData(Role.SUBSCRIBER, "subscriber")]
[InlineData(Role.PUBLISHER, "publisher")]
[InlineData(Role.MODERATOR, "moderator")]
[InlineData(Role.PUBLISHERONLY, "publisheronly")]
public void GenerateTokenWithRoleTest(Role role, string expectedRole)
{
OpenTok opentok = new OpenTok(ApiKey, ApiSecret);

String sessionId = "1_MX4xMjM0NTZ-flNhdCBNYXIgMTUgMTQ6NDI6MjMgUERUIDIwMTR-MC40OTAxMzAyNX4";
List<string> initalLayoutClassList = new List<string>();
initalLayoutClassList.Add("focus");
string token = opentok.GenerateT1Token(sessionId, initialLayoutClassList: initalLayoutClassList);

var opentok = new OpenTok(ApiKey, ApiSecret);
var sessionId = "1_MX4xMjM0NTZ-flNhdCBNYXIgMTUgMTQ6NDI6MjMgUERUIDIwMTR-MC40OTAxMzAyNX4";
var token = opentok.GenerateT1Token(sessionId, role);
Assert.NotNull(token);
var data = CheckToken(token);

Assert.Equal(data["partner_id"], ApiKey.ToString());
Assert.NotNull(data["sig"]);
Assert.NotNull(data["create_time"]);
Assert.NotNull(data["nonce"]);
Assert.Equal(data["role"],"publisher");
Assert.Equal("focus", data["initial_layout_class_list"]);
}

[Fact]
public void GenerateInvalidTokensTest()
{
OpenTok opentok = new OpenTok(ApiKey, ApiSecret);
Assert.Throws<OpenTokArgumentException>(() => opentok.GenerateT1Token(null));
Assert.Throws<OpenTokArgumentException>(() => opentok.GenerateT1Token(""));
Assert.Throws<OpenTokArgumentException>(() => opentok.GenerateT1Token(string.Empty));
Assert.Throws<OpenTokArgumentException>(() => opentok.GenerateT1Token("NOT A VALID SESSION ID"));
Assert.Equal(data["role"], expectedRole);
}


private Dictionary<string,string> CheckToken(string token)
private Dictionary<string, string> CheckToken(string token)
{
string baseToken = OpenTokUtils.Decode64(token.Substring(4));
char[] sep = { '&' };
string[] tokenFields = baseToken.Split(sep);
var baseToken = OpenTokUtils.Decode64(token.Substring(4));
char[] sep = {'&'};
var tokenFields = baseToken.Split(sep);
var tokenData = new Dictionary<string, string>();

foreach (var t in tokenFields)
{
tokenData.Add(t.Split('=')[0], t.Split('=')[1]);
}

return tokenData;
}
}

public class TokenTests
{
private const string ApiSecret = "1234567890abcdef1234567890abcdef1234567890";
private const int ApiKey = 123456;
private const string ApiSecret = "1234567890abcdef1234567890abcdef1234567890";
private const string SessionId = "1_MX4xMjM0NTZ-flNhdCBNYXIgMTUgMTQ6NDI6MjMgUERUIDIwMTR-MC40OTAxMzAyNX4";
private readonly OpenTok sut = new(ApiKey, ApiSecret);

Expand All @@ -166,19 +150,14 @@ public void GenerateToken_ShouldReturnTokenWithDefaultValues()
claims["role"].Should().Be("publisher");
claims.ContainsKey("initial_layout_class_list").Should().BeFalse();
}

[Theory]
[InlineData(Role.SUBSCRIBER, "subscriber")]
[InlineData(Role.PUBLISHER, "publisher")]
[InlineData(Role.MODERATOR, "moderator")]
[InlineData(Role.PUBLISHERONLY, "publisheronly")]
public void GenerateToken_ShouldSetRole(Role role, string expectedRole)

[Fact]
public void GenerateToken_ShouldSetData()
{
var token = sut.GenerateToken(SessionId, role);
var claims = ExtractClaims(token);
claims["role"].Should().Be(expectedRole);
var token = sut.GenerateToken(SessionId, data: "Some data.");
ExtractClaims(token)["data"].Should().Be("Some data.");
}

[Fact]
public void GenerateToken_ShouldSetExpireTime()
{
Expand All @@ -187,29 +166,41 @@ public void GenerateToken_ShouldSetExpireTime()
var claims = ExtractClaims(token);
claims["exp"].Should().Be(expireTime.ToString(CultureInfo.InvariantCulture));
}

[Fact]
public void GenerateToken_ShouldSetInitialLayoutClass()
{
var list = new List<string> { "focus", "hello" };
var list = new List<string> {"focus", "hello"};
var token = sut.GenerateToken(SessionId, initialLayoutClassList: list);
var claims = ExtractClaims(token);
claims["initial_layout_list"].Should().Be("focus hello");
}

[Theory]
[InlineData(Role.SUBSCRIBER, "subscriber")]
[InlineData(Role.PUBLISHER, "publisher")]
[InlineData(Role.MODERATOR, "moderator")]
[InlineData(Role.PUBLISHERONLY, "publisheronly")]
public void GenerateToken_ShouldSetRole(Role role, string expectedRole)
{
var token = sut.GenerateToken(SessionId, role);
var claims = ExtractClaims(token);
claims["role"].Should().Be(expectedRole);
}

private static Dictionary<string, string> ExtractClaims(string token)
{
var key = Encoding.ASCII.GetBytes(ApiSecret);
new JwtSecurityTokenHandler().ValidateToken(token, new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false,
}, out SecurityToken validatedToken);
var jwtToken = (JwtSecurityToken)validatedToken;
return jwtToken.Claims.ToDictionary(claim => claim.Type, claim => claim.Value);;
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false,
}, out var validatedToken);
var jwtToken = (JwtSecurityToken) validatedToken;
return jwtToken.Claims.ToDictionary(claim => claim.Type, claim => claim.Value);
;
}
}
}

}

0 comments on commit 4f52489

Please sign in to comment.