-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Expand file tree
/
Copy pathOAuth1SignatureTests.cs
More file actions
123 lines (97 loc) · 5.69 KB
/
OAuth1SignatureTests.cs
File metadata and controls
123 lines (97 loc) · 5.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
using RestSharp.Authenticators;
using RestSharp.Authenticators.OAuth;
namespace RestSharp.Tests.Auth;
public class OAuth1SignatureTests {
readonly OAuthWorkflow _workflow = new() {
ParameterHandling = OAuthParameterHandling.UrlOrPostParameters,
Token = "370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb",
TokenSecret = "LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE",
ConsumerKey = "xvz1evFS4wEEPTGEFPHBog",
ConsumerSecret = "kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw",
SignatureMethod = OAuthSignatureMethod.HmacSha1,
Version = "1.0",
GetNonce = () => "kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg",
GetTimestamp = () => "1318622958"
};
readonly RestClient _client = new("https://api.twitter.com/1.1");
readonly RestRequest _request = new RestRequest("statuses/update.json", Method.Post)
.AddParameter("status", "Hello Ladies + Gentlemen, a signed OAuth request!")
.AddParameter("include_entities", "true");
[Fact]
public void Adds_correct_signature() {
OAuth1Authenticator.AddOAuthData(_client, _request, _workflow, OAuthType.ProtectedResource, null);
var signature = _request.Parameters.First(x => x.Name == "oauth_signature").Value;
signature.Should().Be("hCtSmYh+iHYCEqBWrE7C7hYmtUk=");
}
[Fact]
public void Generates_correct_signature_base() {
const string method = "POST";
var requestParameters = _request.Parameters.ToWebParameters().ToArray();
var parameters = new WebPairCollection();
parameters.AddRange(requestParameters);
var url = _client.BuildUri(_request).ToString();
_workflow.RequestUrl = url;
var oauthParameters = _workflow.BuildProtectedResourceSignature(method, parameters);
oauthParameters.Parameters.AddRange(requestParameters);
var signatureBase = OAuthTools.ConcatenateRequestElements(method, url, oauthParameters.Parameters);
signatureBase.Should()
.Be(
"POST&https%3A%2F%2Fapi.twitter.com%2F1.1%2Fstatuses%2Fupdate.json&include_entities%3Dtrue%26oauth_consumer_key%3Dxvz1evFS4wEEPTGEFPHBog%26oauth_nonce%3DkYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1318622958%26oauth_token%3D370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb%26oauth_version%3D1.0%26status%3DHello%2520Ladies%2520%252B%2520Gentlemen%252C%2520a%2520signed%2520OAuth%2520request%2521"
);
}
[Fact]
public void Handles_path_with_exclamation_mark() {
// Test that a path segment with ! is encoded correctly in the signature base
var client = new RestClient("https://api.example.com");
var request = new RestRequest("path/with!exclamation/resource", Method.Get);
const string method = "GET";
var url = client.BuildUri(request).ToString();
var parameters = new WebPairCollection();
_workflow.RequestUrl = url;
var oauthParameters = _workflow.BuildProtectedResourceSignature(method, parameters);
var signatureBase = OAuthTools.ConcatenateRequestElements(method, url, oauthParameters.Parameters);
// The URL should be encoded with ! as %21 in the signature base
signatureBase.Should().Contain("path%2Fwith%21exclamation%2Fresource");
}
[Theory]
[InlineData("path/with!exclamation", "%21")]
[InlineData("path/with*asterisk", "%2A")]
[InlineData("path/with'apostrophe", "%27")]
[InlineData("path/with(paren", "%28")]
[InlineData("path/with)paren", "%29")]
public void Encodes_RFC3986_special_chars_in_path(string path, string encodedChar) {
// Test that RFC 3986 special characters are properly encoded in path segments
var client = new RestClient("https://api.example.com");
var request = new RestRequest(path, Method.Get);
const string method = "GET";
var url = client.BuildUri(request).ToString();
var parameters = new WebPairCollection();
_workflow.RequestUrl = url;
var oauthParameters = _workflow.BuildProtectedResourceSignature(method, parameters);
var signatureBase = OAuthTools.ConcatenateRequestElements(method, url, oauthParameters.Parameters);
// The URL should contain the encoded character in the signature base
signatureBase.Should().Contain(encodedChar);
}
[Theory]
[InlineData("with!exclamation")]
[InlineData("with*asterisk")]
[InlineData("with'apostrophe")]
[InlineData("with(paren")]
[InlineData("with)paren")]
public void Handles_url_segment_with_RFC3986_special_chars(string segmentValue) {
// Test that URL segment parameters with RFC 3986 special characters don't get double-encoded
var client = new RestClient("https://api.example.com");
var request = new RestRequest("path/{segment}/resource", Method.Get);
request.AddUrlSegment("segment", segmentValue);
const string method = "GET";
var url = client.BuildUri(request).ToString();
var parameters = new WebPairCollection();
_workflow.RequestUrl = url;
var oauthParameters = _workflow.BuildProtectedResourceSignature(method, parameters);
var signatureBase = OAuthTools.ConcatenateRequestElements(method, url, oauthParameters.Parameters);
// The signature base should NOT contain double-encoded characters like %2521 (which is %25 + 21)
signatureBase.Should().NotContain("%25");
// But it should contain properly encoded special chars
signatureBase.Should().MatchRegex("%2[0-9A-F]");
}
}