/// <param name="date">The current date and time, used to authenticate /// the API request. Typically, you should specify DateTime.UtcNow, /// but if you do not wish to rely on the system-wide clock, you may /// determine the current date/time by some other means.</param> /// <param name="timeout">The request timeout, in milliseconds. /// Specify 0 to use the system-default timeout. Use caution if /// you choose to specify a custom timeout - some API /// calls (particularly in the Auth APIs) will not /// return a response until an out-of-band authentication process /// has completed. In some cases, this may take as much as a /// small number of minutes.</param> public string ApiCall(string method, string path, Dictionary <string, string> parameters, int timeout, DateTime date, out HttpStatusCode statusCode) { string canon_params = DuoApi.CanonicalizeParams(parameters); string query = ""; if (!method.Equals("POST") && !method.Equals("PUT")) { if (parameters.Count > 0) { query = "?" + canon_params; } } string url = string.Format("{0}://{1}{2}{3}", this.url_scheme, this.host, path, query); string date_string = DuoApi.DateToRFC822(date); string auth = this.Sign(method, path, canon_params, date_string); HttpWebResponse response = AttemptRetriableHttpRequest( method, url, auth, date_string, canon_params, timeout); StreamReader reader = new StreamReader(response.GetResponseStream()); statusCode = response.StatusCode; return(reader.ReadToEnd()); }
public string Sign(string method, string path, string canon_params, string date) { string canon = this.CanonicalizeRequest(method, path, canon_params, date); string sig = this.HmacSign(canon); string auth = this.ikey + ':' + sig; return("Basic " + DuoApi.Encode64(auth)); }
static int Main(string[] args) { if (args.Length < 4) { System.Console.WriteLine("Usage: <integration key> <secret key> <integration host> <E.164-formatted phone number>"); return(1); } string ikey = args[0]; string skey = args[1]; string host = args[2]; string phone = args[3]; var client = new Duo.DuoApi(ikey, skey, host); var parameters = new Dictionary <string, string>(); parameters["phone"] = phone; parameters["message"] = "The PIN is <pin>"; // Start a call var r = client.JSONApiCall <Dictionary <string, object> >( "POST", "/verify/v1/call", parameters); // Get the transaction ID from the response. if (!r.ContainsKey("txid")) { System.Console.WriteLine("Could not send PIN!"); return(1); } // Poll the txid for the status of the transaction. System.Console.WriteLine("The PIN is " + r["pin"]); parameters.Clear(); parameters["txid"] = r["txid"] as String; String state; do { var status_res = client.JSONApiCall <Dictionary <string, object> >( "GET", "/verify/v1/status", parameters); state = status_res["state"] as String; System.Console.WriteLine(status_res["info"]); } while (state != "ended"); return(0); }
static int Main(string[] args) { if (args.Length < 4) { System.Console.WriteLine("Usage: <integration key> <secret key> <integration host> <E.164-formatted phone number>"); return 1; } string ikey = args[0]; string skey = args[1]; string host = args[2]; string phone = args[3]; var client = new Duo.DuoApi(ikey, skey, host); var parameters = new Dictionary<string, string>(); parameters["phone"] = phone; parameters["message"] = "The PIN is <pin>"; // Start a call var r = client.JSONApiCall<Dictionary<string, object>>( "POST", "/verify/v1/call", parameters); // Get the transaction ID from the response. if (! r.ContainsKey("txid")) { System.Console.WriteLine("Could not send PIN!"); return 1; } // Poll the txid for the status of the transaction. System.Console.WriteLine("The PIN is " + r["pin"]); parameters.Clear(); parameters["txid"] = r["txid"] as String; String state; do { var status_res = client.JSONApiCall<Dictionary<string, object>>( "GET", "/verify/v1/status", parameters); state = status_res["state"] as String; System.Console.WriteLine(status_res["info"]); } while (state != "ended"); return 0; }
public void HmacSha1() { var ikey = "test_ikey"; var skey = "gtdfxv9YgVBYcF6dl2Eq17KUQJN2PLM2ODVTkvoT"; var host = "foO.BAr52.cOm"; var client = new Duo.DuoApi(ikey, skey, host); var method = "PoSt"; var path = "/Foo/BaR2/qux"; var date = "Fri, 07 Dec 2012 17:18:00 -0000"; var parameters = new Dictionary<string, string> { {"\u469a\u287b\u35d0\u8ef3\u6727\u502a\u0810\ud091\xc8\uc170", "\u0f45\u1a76\u341a\u654c\uc23f\u9b09\uabe2\u8343\u1b27\u60d0"}, {"\u7449\u7e4b\uccfb\u59ff\ufe5f\u83b7\uadcc\u900c\ucfd1\u7813", "\u8db7\u5022\u92d3\u42ef\u207d\u8730\uacfe\u5617\u0946\u4e30"}, {"\u7470\u9314\u901c\u9eae\u40d8\u4201\u82d8\u8c70\u1d31\ua042", "\u17d9\u0ba8\u9358\uaadf\ua42a\u48be\ufb96\u6fe9\ub7ff\u32f3"}, {"\uc2c5\u2c1d\u2620\u3617\u96b3F\u8605\u20e8\uac21\u5934", "\ufba9\u41aa\ubd83\u840b\u2615\u3e6e\u652d\ua8b5\ud56bU"}, }; string canon_params = DuoApi.CanonicalizeParams(parameters); var actual = client.Sign(method, path, canon_params, date); var expected = "Basic dGVzdF9pa2V5OmYwMTgxMWNiYmY5NTYxNjIzYWI0NWI4OTMwOTYyNjdmZDQ2YTUxNzg="; Assert.AreEqual(expected, actual); }
public void HmacSha1() { var ikey = "test_ikey"; var skey = "gtdfxv9YgVBYcF6dl2Eq17KUQJN2PLM2ODVTkvoT"; var host = "foO.BAr52.cOm"; var client = new Duo.DuoApi(ikey, skey, host); var method = "PoSt"; var path = "/Foo/BaR2/qux"; var date = "Fri, 07 Dec 2012 17:18:00 -0000"; var parameters = new Dictionary <string, string> { { "\u469a\u287b\u35d0\u8ef3\u6727\u502a\u0810\ud091\xc8\uc170", "\u0f45\u1a76\u341a\u654c\uc23f\u9b09\uabe2\u8343\u1b27\u60d0" }, { "\u7449\u7e4b\uccfb\u59ff\ufe5f\u83b7\uadcc\u900c\ucfd1\u7813", "\u8db7\u5022\u92d3\u42ef\u207d\u8730\uacfe\u5617\u0946\u4e30" }, { "\u7470\u9314\u901c\u9eae\u40d8\u4201\u82d8\u8c70\u1d31\ua042", "\u17d9\u0ba8\u9358\uaadf\ua42a\u48be\ufb96\u6fe9\ub7ff\u32f3" }, { "\uc2c5\u2c1d\u2620\u3617\u96b3F\u8605\u20e8\uac21\u5934", "\ufba9\u41aa\ubd83\u840b\u2615\u3e6e\u652d\ua8b5\ud56bU" }, }; string canon_params = DuoApi.CanonicalizeParams(parameters); var actual = client.Sign(method, path, canon_params, date); var expected = "Basic dGVzdF9pa2V5OmYwMTgxMWNiYmY5NTYxNjIzYWI0NWI4OTMwOTYyNjdmZDQ2YTUxNzg="; Assert.AreEqual(expected, actual); }
static int Main(string[] args) { if (args.Length < 3) { System.Console.WriteLine("Usage: <integration key> <secret key> <integration host>"); return(1); } string ikey = args[0]; string skey = args[1]; string host = args[2]; var client = new Duo.DuoApi(ikey, skey, host); var parameters = new Dictionary <string, string>(); var r = client.JSONApiCall <Dictionary <string, object> >( "GET", "/admin/v1/info/authentication_attempts", parameters); var attempts = r["authentication_attempts"] as Dictionary <string, object>; foreach (KeyValuePair <string, object> info in attempts) { var s = String.Format("{0} authentication(s) ended with {1}.", info.Value, info.Key); System.Console.WriteLine(s); } // /admin/v1/users returns a JSON Array instead of an object. var users = client.JSONApiCall <System.Collections.ArrayList>( "GET", "/admin/v1/users", parameters); System.Console.WriteLine(String.Format("{0} users.", users.Count)); foreach (Dictionary <string, object> user in users) { System.Console.WriteLine( "\t" + "Username: "******"username"] as string)); } return(0); }
static int Main(string[] args) { if (args.Length < 3) { System.Console.WriteLine("Usage: <integration key> <secret key> <integration host>"); return 1; } string ikey = args[0]; string skey = args[1]; string host = args[2]; var client = new Duo.DuoApi(ikey, skey, host); var parameters = new Dictionary<string, string>(); var r = client.JSONApiCall<Dictionary<string, object>>( "GET", "/admin/v1/info/authentication_attempts", parameters); var attempts = r["authentication_attempts"] as Dictionary<string, object>; foreach (KeyValuePair<string, object> info in attempts) { var s = String.Format("{0} authentication(s) ended with {1}.", info.Value, info.Key); System.Console.WriteLine(s); } return 0; }
/// <param name="date">The current date and time, used to authenticate /// the API request. Typically, you should specify DateTime.UtcNow, /// but if you do not wish to rely on the system-wide clock, you may /// determine the current date/time by some other means.</param> /// <param name="timeout">The request timeout, in milliseconds. /// Specify 0 to use the system-default timeout. Use caution if /// you choose to specify a custom timeout - some API /// calls (particularly in the Auth and Verify APIs) will not /// return a response until an out-of-band authentication process /// has completed. In some cases, this may take as much as a /// small number of minutes.</param> public string ApiCall(string method, string path, Dictionary <string, string> parameters, int timeout, DateTime date, out HttpStatusCode statusCode) { string canon_params = DuoApi.CanonicalizeParams(parameters); string query = ""; if (!method.Equals("POST") && !method.Equals("PUT")) { if (parameters.Count > 0) { query = "?" + canon_params; } } string url = string.Format("{0}://{1}{2}{3}", this.url_scheme, this.host, path, query); string date_string = DuoApi.DateToRFC822(date); string auth = this.Sign(method, path, canon_params, date_string); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Method = method; request.Accept = "application/json"; request.Headers.Add("Authorization", auth); request.Headers.Add("X-Duo-Date", date_string); request.UserAgent = this.user_agent; // If no proxy, check for and use WinHTTP proxy as autoconfig won't pick this up when run from a service if (!HasProxyServer(request)) { request.Proxy = GetWinhttpProxy(); } LogProxyInfo(request.Proxy); if (method.Equals("POST") || method.Equals("PUT")) { byte[] data = Encoding.UTF8.GetBytes(canon_params); request.ContentType = "application/x-www-form-urlencoded"; request.ContentLength = data.Length; using (Stream requestStream = request.GetRequestStream()) { requestStream.Write(data, 0, data.Length); } } if (timeout > 0) { request.Timeout = timeout; } // Do the request and process the result. HttpWebResponse response; try { response = (HttpWebResponse)request.GetResponse(); } catch (WebException ex) { response = (HttpWebResponse)ex.Response; if (response == null) { throw; } } StreamReader reader = new StreamReader(response.GetResponseStream()); statusCode = response.StatusCode; return(reader.ReadToEnd()); }
static int Main(string[] args) { if (args.Length < 3) { System.Console.WriteLine("Usage: <integration key> <secret key> <integration host>"); return(1); } string ikey = args[0]; string skey = args[1]; string host = args[2]; var client = new Duo.DuoApi(ikey, skey, host); var parameters = new Dictionary <string, string>(); var r = client.JSONApiCall <Dictionary <string, object> >( "GET", "/admin/v1/info/authentication_attempts", parameters); var attempts = r["authentication_attempts"] as Dictionary <string, object>; foreach (KeyValuePair <string, object> info in attempts) { var s = String.Format("{0} authentication(s) ended with {1}.", info.Value, info.Key); System.Console.WriteLine(s); } // /admin/v1/users returns a JSON Array instead of an object. var users = client.JSONApiCall <System.Collections.ArrayList>( "GET", "/admin/v1/users", parameters); System.Console.WriteLine(String.Format("{0} users.", users.Count)); foreach (Dictionary <string, object> user in users) { System.Console.WriteLine( "\t" + "Username: "******"username"] as string)); } // paging call int?offset = 0; while (offset != null) { var jsonResponse = client.JSONPagingApiCall("GET", "/admin/v1/users", parameters, (int)offset, 10); var pagedUsers = jsonResponse["response"] as System.Collections.ArrayList; System.Console.WriteLine(String.Format("{0} users at offset {1}", pagedUsers.Count, offset)); foreach (Dictionary <string, object> user in pagedUsers) { System.Console.WriteLine( "\t" + "Username: "******"username"] as string)); } var metadata = jsonResponse["metadata"] as Dictionary <string, object>; if (metadata.ContainsKey("next_offset")) { offset = metadata["next_offset"] as int?; } else { offset = null; } } return(0); }