diff options
author | Jason Alexander <jason.alexander@gmail.com> | 2007-02-25 05:30:02 +0000 |
---|---|---|
committer | Jason <jason.alexander@gmail.com> | 2007-02-25 05:30:02 +0000 |
commit | b9ca835d34a0ca8b3739195e0a37f4ba0ff41528 (patch) | |
tree | b829ad7d6bfdc57deb8302689e66894774531bbe | |
parent | 22b116fbafbbd6011a12022d3f82c4cf3884e9cb (diff) | |
download | DotNetOpenAuth-b9ca835d34a0ca8b3739195e0a37f4ba0ff41528.zip DotNetOpenAuth-b9ca835d34a0ca8b3739195e0a37f4ba0ff41528.tar.gz DotNetOpenAuth-b9ca835d34a0ca8b3739195e0a37f4ba0ff41528.tar.bz2 |
git-svn-id: https://dotnetopenid.googlecode.com/svn/trunk@11 01efa1a6-402a-0410-b0ae-47b76eba00f0
17 files changed, 546 insertions, 18 deletions
diff --git a/source/Janrain.OpenId.suo b/source/Janrain.OpenId.suo Binary files differindex 6df535e..1c47bfa 100644 --- a/source/Janrain.OpenId.suo +++ b/source/Janrain.OpenId.suo diff --git a/source/Janrain.OpenId/Association.cs b/source/Janrain.OpenId/Association.cs index 3c3bf54..0e21db0 100644 --- a/source/Janrain.OpenId/Association.cs +++ b/source/Janrain.OpenId/Association.cs @@ -98,6 +98,8 @@ namespace Janrain.OpenId #endregion
+ #region Methods
+
public virtual byte[] Serialize()
{
Dictionary<string, string> dict = new Dictionary<string,string>();
@@ -127,11 +129,16 @@ namespace Janrain.OpenId throw new NotSupportedException("Unknown association type: " + assoc_type);
}
+ #endregion
+
}
+ // TODO Move this class out to it's own file
public class HMACSHA1Association : Association
{
+ #region Constructor(s)
+
public HMACSHA1Association(string handle, byte[] secret, TimeSpan expiresIn)
{
this.Handle = handle;
@@ -151,6 +158,10 @@ namespace Janrain.OpenId this._expiresIn = new TimeSpan(0, 0, seconds);
}
+ #endregion
+
+ #region Methods
+
public override string AssociationType()
{
return "HMAC-SHA1";
@@ -221,5 +232,8 @@ namespace Janrain.OpenId hmac.Clear();
return hash;
}
+
+ #endregion
+
}
}
diff --git a/source/Janrain.OpenId/CryptUtil.cs b/source/Janrain.OpenId/CryptUtil.cs index b2be5a9..e8fd7b5 100644 --- a/source/Janrain.OpenId/CryptUtil.cs +++ b/source/Janrain.OpenId/CryptUtil.cs @@ -9,6 +9,7 @@ namespace Janrain.OpenId {
public class CryptUtil
{
+
#region Member Variables
public static byte[] DEFAULT_GEN = {2};
@@ -124,6 +125,5 @@ namespace Janrain.OpenId #endregion
-
}
}
diff --git a/source/Janrain.OpenId/Janrain.OpenId.csproj b/source/Janrain.OpenId/Janrain.OpenId.csproj index a9f5bc3..6efe2d4 100644 --- a/source/Janrain.OpenId/Janrain.OpenId.csproj +++ b/source/Janrain.OpenId/Janrain.OpenId.csproj @@ -51,13 +51,18 @@ <Compile Include="DiffieHellman\mono\SequentialSearchPrimeGeneratorBase.cs" />
<Compile Include="KVUtil.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="store\IAssociationStore.cs" />
- <Compile Include="store\MemoryStore.cs" />
+ <Compile Include="Server\CheckIdRequest.cs" />
+ <Compile Include="Server\IEncodable.cs" />
+ <Compile Include="Server\ProtocolException.cs" />
+ <Compile Include="Server\Request.cs" />
+ <Compile Include="Server\Response.cs" />
+ <Compile Include="Server\TrustRoot.cs" />
+ <Compile Include="Store\IAssociationStore.cs" />
+ <Compile Include="Store\MemoryStore.cs" />
<Compile Include="Util.cs" />
</ItemGroup>
<ItemGroup>
- <Folder Include="consumer\" />
- <Folder Include="server\" />
+ <Folder Include="Consumer\" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
diff --git a/source/Janrain.OpenId/KVUtil.cs b/source/Janrain.OpenId/KVUtil.cs index a297b51..b204af7 100644 --- a/source/Janrain.OpenId/KVUtil.cs +++ b/source/Janrain.OpenId/KVUtil.cs @@ -10,10 +10,16 @@ namespace Janrain.OpenId public class KVUtil
{
+ #region Constructor(s)
+
public KVUtil()
{
}
+ #endregion
+
+ #region Methods
+
private static void Error(string message, bool strict)
{
if (strict)
@@ -83,5 +89,7 @@ namespace Janrain.OpenId return dict;
}
+ #endregion
+
}
}
diff --git a/source/Janrain.OpenId/Server/CheckIdRequest.cs b/source/Janrain.OpenId/Server/CheckIdRequest.cs new file mode 100644 index 0000000..d63fac2 --- /dev/null +++ b/source/Janrain.OpenId/Server/CheckIdRequest.cs @@ -0,0 +1,120 @@ +using System;
+using System.Collections.Specialized;
+using System.Text;
+
+namespace Janrain.OpenId.Server
+{
+ public class UntrustedReturnUrl : ProtocolException
+ {
+ private Uri _return_to;
+ private string _trust_root;
+
+ public UntrustedReturnUrl(NameValueCollection query, Uri return_to, string trust_root)
+ : base(query, "return_to " + return_to.AbsoluteUri + " not under trust_root " + trust_root)
+ {
+ _return_to = return_to;
+ _trust_root = trust_root;
+ }
+ }
+
+ public class MalformedReturnUrl : ProtocolException
+ {
+ private string _return_to;
+
+ public MalformedReturnUrl(NameValueCollection query, string return_to)
+ : base(query, "")
+ {
+ _return_to = return_to;
+ }
+ }
+
+ public class MalformedTrustRoot : ProtocolException
+ {
+ public MalformedTrustRoot(NameValueCollection query, string text)
+ : base(query, text)
+ {
+ }
+ }
+
+ public class CheckIdRequest : AssociatedRequest
+ {
+ private bool _immediate;
+ private string _trust_root;
+ private Uri _identity;
+ private string _mode;
+ private Uri _return_to;
+
+ public CheckIdRequest(Uri identity, Uri return_to, string trust_root, bool immediate, string assoc_handle)
+ {
+ this.AssocHandle = assoc_handle;
+
+ _identity = identity;
+ _return_to = return_to;
+
+ if (trust_root == null)
+ _trust_root = return_to.AbsoluteUri;
+ else
+ _trust_root = trust_root;
+
+ _immediate = immediate;
+ if (_immediate)
+ _mode = "checkid_immediate";
+ else
+ _mode = "checkid_setup";
+
+ try
+ {
+ TrustRoot trustRoot = new TrustRoot(_return_to.AbsolutePath);
+ }
+ catch (ArgumentException e)
+ {
+ throw new MalformedReturnUrl(null, _return_to.AbsoluteUri);
+ }
+
+ if (!this.TrustRootValid)
+ throw new UntrustedReturnUrl(null, _return_to, _trust_root);
+
+ }
+
+ public bool TrustRootValid
+ {
+ get
+ {
+ // TODO this doesn't seem right to me
+ if (_trust_root == null)
+ return true;
+
+ TrustRoot tr = new TrustRoot(_trust_root);
+ if (tr == null)
+ throw new MalformedTrustRoot(null, _trust_root);
+
+ return tr.ValidateUrl(_return_to);
+ }
+ }
+
+ public bool Immediate
+ {
+ get { return _immediate; }
+ }
+
+ public string TrustRoot
+ {
+ get { return _trust_root; }
+ }
+
+ public Uri IdentityUrl
+ {
+ get { return _identity; }
+ }
+
+ public Uri ReturnTo
+ {
+ get { return _return_to; }
+ }
+
+ public override string Mode
+ {
+ get { throw new Exception("The method or operation is not implemented."); }
+ }
+ }
+}
diff --git a/source/Janrain.OpenId/Server/IEncodable.cs b/source/Janrain.OpenId/Server/IEncodable.cs index f6664a3..a4bc2ed 100644 --- a/source/Janrain.OpenId/Server/IEncodable.cs +++ b/source/Janrain.OpenId/Server/IEncodable.cs @@ -5,6 +5,7 @@ using System.Text; namespace Janrain.OpenId.Server
{
+ // TODO Move this enum out to it's own file
public enum EncodingType
{
ENCODE_NONE,
diff --git a/source/Janrain.OpenId/Server/ProtocolException.cs b/source/Janrain.OpenId/Server/ProtocolException.cs new file mode 100644 index 0000000..23769bf --- /dev/null +++ b/source/Janrain.OpenId/Server/ProtocolException.cs @@ -0,0 +1,86 @@ +using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Text;
+
+namespace Janrain.OpenId.Server
+{
+ public class ProtocolException : ApplicationException, IEncodable
+ {
+ private NameValueCollection _query = new NameValueCollection();
+
+ public ProtocolException(NameValueCollection query, string text)
+ : base(text)
+ {
+ _query = query;
+ }
+
+ public bool HasReturnTo
+ {
+ get
+ {
+ return (_query["openid.return_to"] != null);
+ }
+ }
+
+ #region IEncodable Members
+
+ public EncodingType WhichEncoding
+ {
+ get
+ {
+ if (this.HasReturnTo)
+ return EncodingType.ENCODE_URL;
+
+ string mode = _query.Get("openid.mode");
+ if (mode != null)
+ if (mode != "checkid_setup" &&
+ mode != "checkid_immediate")
+ return EncodingType.ENCODE_KVFORM;
+
+ // Notes from the original port
+ //# According to the OpenID spec as of this writing, we are
+ //# probably supposed to switch on request type here (GET
+ //# versus POST) to figure out if we're supposed to print
+ //# machine-readable or human-readable content at this
+ //# point. GET/POST seems like a pretty lousy way of making
+ //# the distinction though, as it's just as possible that
+ //# the user agent could have mistakenly been directed to
+ //# post to the server URL.
+
+ //# Basically, if your request was so broken that you didn't
+ //# manage to include an openid.mode, I'm not going to worry
+ //# too much about returning you something you can't parse.
+ return EncodingType.ENCODE_NONE;
+ }
+ }
+
+ public Uri EncodeToUrl()
+ {
+ string return_to = _query.Get("openid.return_to");
+ if (return_to == null)
+ throw new ApplicationException("return_to URL has not been set.");
+
+ NameValueCollection q = new NameValueCollection();
+ q.Add("openid.mode", "error");
+ q.Add("openid.error", this.Message);
+
+ UriBuilder builder = new UriBuilder(return_to);
+ Util.AppendQueryArgs(ref builder, q);
+
+ return new Uri(builder.ToString(), true);
+ }
+
+ public byte[] EncodeToKVForm()
+ {
+ Hashtable d = new Hashtable();
+
+ d.Add("mode", "error");
+ d.Add("error", this.Message);
+
+ return KVUtil.DictToKV((IDictionary)d);
+ }
+
+ #endregion
+ }
+}
diff --git a/source/Janrain.OpenId/Server/Request.cs b/source/Janrain.OpenId/Server/Request.cs index b73352f..69c5b99 100644 --- a/source/Janrain.OpenId/Server/Request.cs +++ b/source/Janrain.OpenId/Server/Request.cs @@ -4,7 +4,25 @@ using System.Text; namespace Janrain.OpenId.Server
{
- class Request
+
+ public abstract class Request
+ {
+
+ public abstract string Mode { get; }
+
+ }
+
+ // Move this ABC out to it's own file
+ public abstract class AssociatedRequest : Request
{
+
+ private string _assoc_handle;
+
+ public string AssocHandle
+ {
+ get { return _assoc_handle; }
+ set { _assoc_handle = value; }
+ }
+
}
}
diff --git a/source/Janrain.OpenId/Server/Response.cs b/source/Janrain.OpenId/Server/Response.cs index ac2fc16..1a50fe7 100644 --- a/source/Janrain.OpenId/Server/Response.cs +++ b/source/Janrain.OpenId/Server/Response.cs @@ -9,17 +9,28 @@ namespace Janrain.OpenId.Server class Response : IEncodable
{
+ #region Private Members
+
private Hashtable _fields;
- private ListDictionary _signed;
+ private ArrayList _signed;
private Request _request;
+ #endregion
+
+ #region Constructor(s)
+
public Response(Request request)
{
this.Request = request;
- _signed = new ListDictionary();
+ _signed = new ArrayList();
_fields = new Hashtable();
+
}
+ #endregion
+
+ #region Properties
+
public Request Request
{
get { return _request; }
@@ -33,31 +44,113 @@ namespace Janrain.OpenId.Server public string[] Signed
{
- get { return (string[])_signed; ; }
+ get { return (string[]) _signed.ToArray(); }
+ }
+
+ public bool NeedsSigning
+ {
+ get
+ {
+ return (
+ (this.Request.Mode == "checkid_setup" ||
+ this.Request.Mode == "checkid_immediate")
+ &&
+ (this.Signed.Length > 0)
+ );
+ }
+ }
+
+ #endregion
+
+ #region Methods
+
+ public void AddField(string nmspace, string key, string value, bool signed)
+ {
+ if (nmspace != null && nmspace != String.Empty)
+ {
+ key = nmspace + "." + key;
+ }
+
+ this.Fields[key] = value;
+ if (this.Signed != null && !Util.InArray(this.Signed, key))
+ {
+ _signed.Add(key);
+ }
+ }
+
+ public void AddFields(string nmspace, IDictionary fields, bool signed)
+ {
+ foreach (DictionaryEntry pair in fields)
+ {
+ this.AddField(nmspace, (string)pair.Key, (string)pair.Value, signed);
+ }
}
+ public void Update(string nmspace, Response other)
+ {
+ Hashtable nmspaced_fields = new Hashtable();
+ ArrayList nmspaced_signed = new ArrayList();
+
+
+ if (nmspace == null || nmspace == String.Empty)
+ {
+ nmspaced_fields = (Hashtable) other.Fields;
+ nmspaced_signed = new ArrayList(this.Signed);
+ }
+ else
+ {
+ foreach (DictionaryEntry pair in other.Fields)
+ {
+ nmspaced_fields.Add(nmspace + "." + pair.Key.ToString(), pair.Value);
+ }
+
+ foreach (string k in other.Signed)
+ {
+ nmspaced_signed.Add(nmspace + "." + k);
+ }
+ }
+
+ }
+
+ #endregion
+
#region IEncodable Members
public EncodingType WhichEncoding
{
get
{
- throw new Exception("The method or operation is not implemented.");
- }
- set
- {
- throw new Exception("The method or operation is not implemented.");
+ if (this.Request.Mode == "checkid_setup" || this.Request.Mode == "checkid_immediate")
+ {
+ return EncodingType.ENCODE_URL;
+ }
+ else
+ {
+ return EncodingType.ENCODE_KVFORM;
+ }
}
}
public Uri EncodeToUrl()
{
- throw new Exception("The method or operation is not implemented.");
+ NameValueCollection nvc = new NameValueCollection();
+
+
+ foreach (DictionaryEntry pair in this.Fields)
+ {
+ nvc.Add("openid." + pair.Key.ToString(), pair.Value.ToString());
+ }
+
+ CheckIdRequest checkidreq = (CheckIdRequest)this.Request;
+ UriBuilder builder = new UriBuilder(checkidreq.ReturnTo);
+ Util.AppendQueryArgs(ref builder, nvc);
+
+ return new Uri(builder.ToString(), true);
}
public byte[] EncodeToKVForm()
{
- throw new Exception("The method or operation is not implemented.");
+ return KVUtil.DictToKV(this.Fields);
}
#endregion
diff --git a/source/Janrain.OpenId/Server/TrustRoot.cs b/source/Janrain.OpenId/Server/TrustRoot.cs new file mode 100644 index 0000000..6e96c09 --- /dev/null +++ b/source/Janrain.OpenId/Server/TrustRoot.cs @@ -0,0 +1,137 @@ +using System;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+
+namespace Janrain.OpenId.Server
+{
+ public class TrustRoot
+ {
+ private static Regex _tr_regex = new Regex("^(?<scheme>https?)://((?<wildcard>\\*)|(?<wildcard>\\*\\.)?(?<host>[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*)\\.?)(:(?<port>[0-9]+))?(?<path>(/.*|$))");
+ private static string[] _top_level_domains = {"com", "edu", "gov", "int", "mil", "net", "org", "biz", "info", "name", "museum", "coop", "aero", "ac", "ad", "ae", "" +
+ "af", "ag", "ai", "al", "am", "an", "ao", "aq", "ar", "as", "at", "au", "aw", "az", "ba", "bb", "bd", "be", "bf", "bg", "bh", "bi", "bj", "" +
+ "bm", "bn", "bo", "br", "bs", "bt", "bv", "bw", "by", "bz", "ca", "cc", "cd", "cf", "cg", "ch", "ci", "ck", "cl", "cm", "cn", "co", "cr", "" +
+ "cu", "cv", "cx", "cy", "cz", "de", "dj", "dk", "dm", "do", "dz", "ec", "ee", "eg", "eh", "er", "es", "et", "fi", "fj", "fk", "fm", "fo", "" +
+ "fr", "ga", "gd", "ge", "gf", "gg", "gh", "gi", "gl", "gm", "gn", "gp", "gq", "gr", "gs", "gt", "gu", "gw", "gy", "hk", "hm", "hn", "hr", "" +
+ "ht", "hu", "id", "ie", "il", "im", "in", "io", "iq", "ir", "is", "it", "je", "jm", "jo", "jp", "ke", "kg", "kh", "ki", "km", "kn", "kp", "" +
+ "kr", "kw", "ky", "kz", "la", "lb", "lc", "li", "lk", "lr", "ls", "lt", "lu", "lv", "ly", "ma", "mc", "md", "mg", "mh", "mk", "ml", "mm", "" +
+ "mn", "mo", "mp", "mq", "mr", "ms", "mt", "mu", "mv", "mw", "mx", "my", "mz", "na", "nc", "ne", "nf", "ng", "ni", "nl", "no", "np", "nr", "" +
+ "nu", "nz", "om", "pa", "pe", "pf", "pg", "ph", "pk", "pl", "pm", "pn", "pr", "ps", "pt", "pw", "py", "qa", "re", "ro", "ru", "rw", "sa", "" +
+ "sb", "sc", "sd", "se", "sg", "sh", "si", "sj", "sk", "sl", "sm", "sn", "so", "sr", "st", "sv", "sy", "sz", "tc", "td", "tf", "tg", "th", "" +
+ "tj", "tk", "tm", "tn", "to", "tp", "tr", "tt", "tv", "tw", "tz", "ua", "ug", "uk", "um", "us", "uy", "uz", "va", "vc", "ve", "vg", "vi", "" +
+ "vn", "vu", "wf", "ws", "ye", "yt", "yu", "za", "zm", "zw"};
+ private string _unparsed;
+ private string _scheme;
+ private bool _wildcard;
+ private string _host;
+ private int _port;
+ private string _path;
+
+ public TrustRoot(string unparsed)
+ {
+ Match mo = _tr_regex.Match(unparsed);
+
+ if (mo.Success)
+ {
+ _unparsed = unparsed;
+ _scheme = mo.Groups["scheme"].Value;
+ _wildcard = mo.Groups["wildcard"].Value != String.Empty;
+ _host = mo.Groups["host"].Value.ToLower();
+
+ Group port_group = mo.Groups["port"];
+ if (port_group.Success)
+ _port = Convert.ToInt32(port_group.Value);
+ else if (_scheme == "https")
+ _port = 443;
+ else
+ _port = 80;
+
+ _path = mo.Groups["path"].Value;
+ if (_path == String.Empty)
+ _path = "/";
+ }
+ else
+ {
+ throw new ArgumentException(unparsed + " does not appear to be a valid TrustRoot");
+ }
+ }
+
+ public bool ValidateUrl(Uri url)
+ {
+ if (url.Scheme != _scheme)
+ return false;
+
+ if (url.Port != _port)
+ return false;
+
+ if (!_wildcard)
+ {
+ if (url.Host != _host)
+ {
+ return false;
+ }
+ }
+ else if (_host != String.Empty)
+ {
+ string[] host_parts = _host.Split('.');
+ string[] url_parts = url.Host.Split('.');
+ string end_parts = url_parts[url_parts.Length - host_parts.Length];
+
+ for (int i = 0; i < end_parts.Length; i++)
+ {
+ if (end_parts != host_parts[i])
+ return false;
+ }
+ }
+
+ if (url.PathAndQuery == _path)
+ return true;
+
+ int path_len = _path.Length;
+ string url_prefix = url.PathAndQuery.Substring(0, path_len);
+
+ if (_path != url_prefix)
+ return false;
+
+ string allowed = "";
+ if (_path.Contains("?"))
+ allowed = "&";
+ else
+ allowed = "?";
+
+
+ return (allowed.IndexOf(_path[_path.Length - 1]) >= 0 || allowed.IndexOf(url.PathAndQuery[path_len]) >= 0);
+ }
+
+ public bool IsSane
+ {
+ get
+ {
+ if (_host == "localhost")
+ return true;
+
+ string[] host_parts = _host.Split('.');
+
+ string tld = host_parts[host_parts.Length - 1];
+
+ if (!Util.InArray(_top_level_domains, tld))
+ return false;
+
+ if (tld.Length == 2)
+ {
+ if (host_parts.Length == 1)
+ return false;
+
+ if (host_parts[host_parts.Length - 2].Length <= 3)
+ return host_parts.Length > 2;
+
+ }
+ else
+ {
+ return host_parts.Length > 1;
+ }
+
+ return false;
+ }
+ }
+ }
+}
diff --git a/source/Janrain.OpenId/Store/MemoryStore.cs b/source/Janrain.OpenId/Store/MemoryStore.cs index 22f19a8..10d3373 100644 --- a/source/Janrain.OpenId/Store/MemoryStore.cs +++ b/source/Janrain.OpenId/Store/MemoryStore.cs @@ -65,6 +65,8 @@ namespace Janrain.OpenId.Store #endregion
+ #region Methods
+
public static MemoryStore GetInstance()
{
return local_instance;
@@ -157,6 +159,8 @@ namespace Janrain.OpenId.Store }
}
+ #endregion
+
#region IAssociationStore Members
byte[] IAssociationStore.AuthKey
@@ -214,17 +218,30 @@ namespace Janrain.OpenId.Store }
#endregion
+
}
+ // TODO Move this class out to it's own file
public class ServerAssocs
{
+
+ #region Private Members
+
private Hashtable assocs;
+ #endregion
+
+ #region Constructor(s)
+
public ServerAssocs()
{
this.assocs = new Hashtable();
}
+ #endregion
+
+ #region Methods
+
public void Set(Association assoc)
{
this.assocs.Add(assoc.Handle, assoc);
@@ -262,6 +279,8 @@ namespace Janrain.OpenId.Store return best;
}
+ #endregion
+
}
}
diff --git a/source/Janrain.OpenId/Util.cs b/source/Janrain.OpenId/Util.cs index 7a40d45..a1c3e4b 100644 --- a/source/Janrain.OpenId/Util.cs +++ b/source/Janrain.OpenId/Util.cs @@ -6,10 +6,10 @@ using System.Web; namespace Janrain.OpenId
{
- public class Util
+ public static class Util
{
- private Util() { }
+ #region NormalizeUri(string uriStr)
public static Uri NormalizeUri(string uriStr)
{
@@ -23,6 +23,10 @@ namespace Janrain.OpenId return bldr.Uri;
}
+ #endregion
+
+ #region CreateQueryString(NameValueCollection args)
+
public static string CreateQueryString(NameValueCollection args)
{
string[] parts = new string[args.Count];
@@ -38,6 +42,10 @@ namespace Janrain.OpenId return String.Join("&", parts);
}
+ #endregion
+
+ #region AppendQueryArg(ref UriBuilder builder, string key, string value)
+
public static void AppendQueryArg(ref UriBuilder builder, string key, string value)
{
string encKey = HttpUtility.UrlEncode(key);
@@ -54,6 +62,10 @@ namespace Janrain.OpenId }
+ #endregion
+
+ #region AppendQueryArgs(ref UriBuilder builder, NameValueCollection args)
+
public static void AppendQueryArgs(ref UriBuilder builder, NameValueCollection args)
{
if (args.Count > 0)
@@ -70,5 +82,20 @@ namespace Janrain.OpenId }
}
+ #endregion
+
+ #region InArray(string[] array, string valueToFind)
+
+ public static bool InArray(string[] array, string valueToFind)
+ {
+ foreach (string val in array)
+ {
+ if (val == valueToFind) return true;
+ }
+ return false;
+ }
+
+ #endregion
+
}
}
diff --git a/source/Janrain.OpenId/bin/Debug/Janrain.OpenId.dll b/source/Janrain.OpenId/bin/Debug/Janrain.OpenId.dll Binary files differindex 6aa5738..0eefe1a 100644 --- a/source/Janrain.OpenId/bin/Debug/Janrain.OpenId.dll +++ b/source/Janrain.OpenId/bin/Debug/Janrain.OpenId.dll diff --git a/source/Janrain.OpenId/bin/Debug/Janrain.OpenId.pdb b/source/Janrain.OpenId/bin/Debug/Janrain.OpenId.pdb Binary files differindex 600ad1d..0ca88aa 100644 --- a/source/Janrain.OpenId/bin/Debug/Janrain.OpenId.pdb +++ b/source/Janrain.OpenId/bin/Debug/Janrain.OpenId.pdb diff --git a/source/Janrain.OpenId/obj/Debug/Janrain.OpenId.dll b/source/Janrain.OpenId/obj/Debug/Janrain.OpenId.dll Binary files differindex 6aa5738..0eefe1a 100644 --- a/source/Janrain.OpenId/obj/Debug/Janrain.OpenId.dll +++ b/source/Janrain.OpenId/obj/Debug/Janrain.OpenId.dll diff --git a/source/Janrain.OpenId/obj/Debug/Janrain.OpenId.pdb b/source/Janrain.OpenId/obj/Debug/Janrain.OpenId.pdb Binary files differindex 600ad1d..0ca88aa 100644 --- a/source/Janrain.OpenId/obj/Debug/Janrain.OpenId.pdb +++ b/source/Janrain.OpenId/obj/Debug/Janrain.OpenId.pdb |