Skip to content

Commit

Permalink
hanlde next_offset for v2
Browse files Browse the repository at this point in the history
  • Loading branch information
Christopher Hume committed Feb 5, 2019
1 parent b52a335 commit 5b5cb37
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 13 deletions.
67 changes: 54 additions & 13 deletions Duo.cs
Expand Up @@ -63,6 +63,24 @@ protected DuoApi(string ikey, string skey, string host, string user_agent, strin
}
}

public static string FinishCanonicalize(string p)
{
// Signatures require upper-case hex digits.
p = Regex.Replace(p,
"(%[0-9A-Fa-f][0-9A-Fa-f])",
c => c.Value.ToUpperInvariant());
// Escape only the expected characters.
p = Regex.Replace(p,
"([!'()*])",
c => "%" + Convert.ToByte(c.Value[0]).ToString("X"));
p = p.Replace("%7E", "~");
// UrlEncode converts space (" ") to "+". The
// signature algorithm requires "%20" instead. Actual
// + has already been replaced with %2B.
p = p.Replace("+", "%20");
return p;
}

public static string CanonicalizeParams(Dictionary<string, string> parameters)
{
var ret = new List<String>();
Expand All @@ -71,25 +89,48 @@ public static string CanonicalizeParams(Dictionary<string, string> parameters)
string p = String.Format("{0}={1}",
HttpUtility.UrlEncode(pair.Key),
HttpUtility.UrlEncode(pair.Value));
// Signatures require upper-case hex digits.
p = Regex.Replace(p,
"(%[0-9A-Fa-f][0-9A-Fa-f])",
c => c.Value.ToUpperInvariant());
// Escape only the expected characters.
p = Regex.Replace(p,
"([!'()*])",
c => "%" + Convert.ToByte(c.Value[0]).ToString("X"));
p = p.Replace("%7E", "~");
// UrlEncode converts space (" ") to "+". The
// signature algorithm requires "%20" instead. Actual
// + has already been replaced with %2B.
p = p.Replace("+", "%20");

p = FinishCanonicalize(p);
ret.Add(p);
}
ret.Sort(StringComparer.Ordinal);
return string.Join("&", ret.ToArray());
}


// handle value as an object eg. next_offset = ["123", "fdajkld"]
public static string CanonicalizeParams(Dictionary<string, object> parameters)
{
var ret = new List<String>();
foreach (KeyValuePair<string, object> pair in parameters)
{
string p = "";
if (pair.Value.GetType() == typeof(string[]))
{
string[] values = (string[])pair.Value;
string value1 = values[0];
string value2 = values[1];
p = String.Format("{0}={1}&{2}={3}",
HttpUtility.UrlEncode(pair.Key),
HttpUtility.UrlEncode(value1),
HttpUtility.UrlEncode(pair.Key),
HttpUtility.UrlEncode(value2));
}
else
{
string val = (string)pair.Value;
p = String.Format("{0}={1}",
HttpUtility.UrlEncode(pair.Key),
HttpUtility.UrlEncode(val));
}
p = FinishCanonicalizing(p);
ret.Add(p);
}
ret.Sort(StringComparer.Ordinal);
return string.Join("&", ret.ToArray());
}


protected string CanonicalizeRequest(string method,
string path,
string canon_params,
Expand Down
13 changes: 13 additions & 0 deletions test/QueryParamsTest.cs
Expand Up @@ -90,4 +90,17 @@ public void SortOrderWithCommonPrefix()
var expected = "foo=1&foo_bar=2";
Assert.AreEqual(expected, DuoApi.CanonicalizeParams(parameters));
}

[TestMethod]
public void NextOffsetTest()
{
string[] offset = new string[]{"fjaewoifjew", "473891274832917498"};
var parameters = new Dictionary<string, object>
{
{"next_offset", offset},
{"foo", "1"},
};
var expected = "foo=1&next_offset=fjaewoifjew&next_offset=473891274832917498";
Assert.AreEqual(expected, DuoApi.CanonicalizeParams(parameters));
}
}

0 comments on commit 5b5cb37

Please sign in to comment.