summaryrefslogtreecommitdiffstats
path: root/src/OAuth/OAuthServiceProvider
diff options
context:
space:
mode:
Diffstat (limited to 'src/OAuth/OAuthServiceProvider')
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/Constants.cs32
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/CustomOAuthTypeProvider.cs34
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/DataClasses.dbml57
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/DataClasses.dbml.layout57
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/DataClasses.designer.cs1190
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/DatabaseNonceStore.cs55
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/DatabaseTokenManager.cs163
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/Global.cs135
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/IDataApi.cs20
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs65
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/OAuthConsumer.cs43
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/OAuthPrincipalAuthorizationPolicy.cs47
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/OAuthToken.cs95
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/RequestScopedTokenMessage.cs25
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/TokenAuthorizationState.cs26
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/TracePageAppender.cs13
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/Utilities.cs28
-rw-r--r--src/OAuth/OAuthServiceProvider/DataApi.cs34
-rw-r--r--src/OAuth/OAuthServiceProvider/DataApi.svc1
-rw-r--r--src/OAuth/OAuthServiceProvider/Default.aspx13
-rw-r--r--src/OAuth/OAuthServiceProvider/Default.aspx.cs49
-rw-r--r--src/OAuth/OAuthServiceProvider/Default.aspx.designer.cs33
-rw-r--r--src/OAuth/OAuthServiceProvider/Global.asax1
-rw-r--r--src/OAuth/OAuthServiceProvider/Login.aspx7
-rw-r--r--src/OAuth/OAuthServiceProvider/MasterPage.master23
-rw-r--r--src/OAuth/OAuthServiceProvider/Members/Authorize.aspx58
-rw-r--r--src/OAuth/OAuthServiceProvider/Members/Authorize.aspx.cs80
-rw-r--r--src/OAuth/OAuthServiceProvider/Members/Authorize.aspx.designer.cs105
-rw-r--r--src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx6
-rw-r--r--src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx.cs17
-rw-r--r--src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx.designer.cs15
-rw-r--r--src/OAuth/OAuthServiceProvider/Members/Logoff.aspx8
-rw-r--r--src/OAuth/OAuthServiceProvider/Members/Web.config8
-rw-r--r--src/OAuth/OAuthServiceProvider/OAuth.ashx42
-rw-r--r--src/OAuth/OAuthServiceProvider/OAuthServiceProvider.csproj206
-rw-r--r--src/OAuth/OAuthServiceProvider/Properties/AssemblyInfo.cs35
-rw-r--r--src/OAuth/OAuthServiceProvider/Settings.StyleCop1
-rw-r--r--src/OAuth/OAuthServiceProvider/TracePage.aspx18
-rw-r--r--src/OAuth/OAuthServiceProvider/TracePage.aspx.cs24
-rw-r--r--src/OAuth/OAuthServiceProvider/TracePage.aspx.designer.cs42
-rw-r--r--src/OAuth/OAuthServiceProvider/Web.config180
-rw-r--r--src/OAuth/OAuthServiceProvider/favicon.icobin0 -> 1150 bytes
42 files changed, 3091 insertions, 0 deletions
diff --git a/src/OAuth/OAuthServiceProvider/Code/Constants.cs b/src/OAuth/OAuthServiceProvider/Code/Constants.cs
new file mode 100644
index 0000000..3e629f0
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/Constants.cs
@@ -0,0 +1,32 @@
+namespace OAuthServiceProvider.Code {
+ using System;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuth;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+
+ /// <summary>
+ /// Service Provider definitions.
+ /// </summary>
+ public static class Constants {
+ public static Uri WebRootUrl { get; set; }
+
+ public static ServiceProviderDescription SelfDescription {
+ get {
+ ServiceProviderDescription description = new ServiceProviderDescription {
+ AccessTokenEndpoint = new MessageReceivingEndpoint(new Uri(WebRootUrl, "/OAuth.ashx"), HttpDeliveryMethods.PostRequest),
+ RequestTokenEndpoint = new MessageReceivingEndpoint(new Uri(WebRootUrl, "/OAuth.ashx"), HttpDeliveryMethods.PostRequest),
+ UserAuthorizationEndpoint = new MessageReceivingEndpoint(new Uri(WebRootUrl, "/OAuth.ashx"), HttpDeliveryMethods.PostRequest),
+ TamperProtectionElements = new ITamperProtectionChannelBindingElement[] {
+ new HmacSha1SigningBindingElement(),
+ },
+ };
+
+ return description;
+ }
+ }
+
+ public static ServiceProvider CreateServiceProvider() {
+ return new ServiceProvider(SelfDescription, Global.TokenManager, Global.NonceStore);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/CustomOAuthTypeProvider.cs b/src/OAuth/OAuthServiceProvider/Code/CustomOAuthTypeProvider.cs
new file mode 100644
index 0000000..67da17c
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/CustomOAuthTypeProvider.cs
@@ -0,0 +1,34 @@
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+ using DotNetOpenAuth.OAuth.Messages;
+
+ /// <summary>
+ /// A custom class that will cause the OAuth library to use our custom message types
+ /// where we have them.
+ /// </summary>
+ public class CustomOAuthMessageFactory : OAuthServiceProviderMessageFactory {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CustomOAuthMessageFactory"/> class.
+ /// </summary>
+ /// <param name="tokenManager">The token manager instance to use.</param>
+ public CustomOAuthMessageFactory(IServiceProviderTokenManager tokenManager)
+ : base(tokenManager) {
+ }
+
+ public override IDirectedProtocolMessage GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary<string, string> fields) {
+ var message = base.GetNewRequestMessage(recipient, fields);
+
+ // inject our own type here to replace the standard one
+ if (message is UnauthorizedTokenRequest) {
+ message = new RequestScopedTokenMessage(recipient, message.Version);
+ }
+
+ return message;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/DataClasses.dbml b/src/OAuth/OAuthServiceProvider/Code/DataClasses.dbml
new file mode 100644
index 0000000..5522ec8
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/DataClasses.dbml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?><Database Name="Database" EntityNamespace="OAuthServiceProvider.Code" Class="DataClassesDataContext" xmlns="http://schemas.microsoft.com/linqtosql/dbml/2007">
+ <Connection Mode="WebSettings" ConnectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True" SettingsObjectName="System.Configuration.ConfigurationManager.ConnectionStrings" SettingsPropertyName="DatabaseConnectionString" Provider="System.Data.SqlClient" />
+ <Table Name="dbo.[User]" Member="Users">
+ <Type Name="User">
+ <Column Name="UserId" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
+ <Column Name="OpenIDClaimedIdentifier" Type="System.String" DbType="NVarChar(150) NOT NULL" CanBeNull="false" />
+ <Column Name="OpenIDFriendlyIdentifier" Type="System.String" DbType="NVarChar(150)" CanBeNull="true" />
+ <Column Name="FullName" Type="System.String" DbType="NVarChar(150)" CanBeNull="false" />
+ <Column Name="Age" Type="System.Int32" DbType="int" CanBeNull="true" />
+ <Association Name="User_FavoriteSite" Member="FavoriteSites" ThisKey="UserId" OtherKey="UserId" Type="FavoriteSite" />
+ <Association Name="User_OAuthToken" Member="OAuthTokens" ThisKey="UserId" OtherKey="UserId" Type="OAuthToken" />
+ </Type>
+ </Table>
+ <Table Name="dbo.FavoriteSite" Member="FavoriteSites">
+ <Type Name="FavoriteSite">
+ <Column Name="FavoriteSiteId" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
+ <Column Name="UserId" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
+ <Column Name="SiteUrl" Type="System.String" DbType="NVarChar(255) NOT NULL" CanBeNull="false" />
+ <Association Name="User_FavoriteSite" Member="User" ThisKey="UserId" OtherKey="UserId" Type="User" IsForeignKey="true" DeleteRule="CASCADE" DeleteOnNull="true" />
+ </Type>
+ </Table>
+ <Table Name="dbo.OAuthConsumer" Member="OAuthConsumers">
+ <Type Name="OAuthConsumer">
+ <Column Name="ConsumerId" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
+ <Column Name="ConsumerKey" Type="System.String" DbType="NVarChar(50) NOT NULL" CanBeNull="false" />
+ <Column Name="ConsumerSecret" Type="System.String" DbType="NVarChar(50) NOT NULL" CanBeNull="false" />
+ <Column Name="Callback" Type="System.String" CanBeNull="true" />
+ <Column Name="VerificationCodeFormat" Type="DotNetOpenAuth.OAuth.VerificationCodeFormat" CanBeNull="false" />
+ <Column Name="VerificationCodeLength" Type="System.Int32" CanBeNull="false" />
+ <Association Name="OAuthConsumer_OAuthToken" Member="OAuthTokens" ThisKey="ConsumerId" OtherKey="ConsumerId" Type="OAuthToken" />
+ </Type>
+ </Table>
+ <Table Name="dbo.OAuthToken" Member="OAuthTokens">
+ <Type Name="OAuthToken">
+ <Column Name="TokenId" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
+ <Column Name="Token" Type="System.String" DbType="NVarChar(50) NOT NULL" CanBeNull="false" />
+ <Column Name="TokenSecret" Type="System.String" DbType="NVarChar(50) NOT NULL" CanBeNull="false" />
+ <Column Name="State" Type="OAuthServiceProvider.Code.TokenAuthorizationState" DbType="INT NOT NULL" CanBeNull="false" />
+ <Column Name="IssueDate" Type="System.DateTime" DbType="DateTime NOT NULL" CanBeNull="false" />
+ <Column Name="ConsumerId" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
+ <Column Name="UserId" Type="System.Int32" DbType="Int" CanBeNull="true" />
+ <Column Name="Scope" Type="System.String" DbType="nvarchar(MAX)" CanBeNull="false" />
+ <Column Name="RequestTokenVerifier" Type="System.String" CanBeNull="true" />
+ <Column Name="RequestTokenCallback" Type="System.String" CanBeNull="true" />
+ <Column Name="ConsumerVersion" Type="System.String" CanBeNull="true" />
+ <Association Name="OAuthConsumer_OAuthToken" Member="OAuthConsumer" ThisKey="ConsumerId" OtherKey="ConsumerId" Type="OAuthConsumer" IsForeignKey="true" DeleteRule="CASCADE" DeleteOnNull="true" />
+ <Association Name="User_OAuthToken" Member="User" ThisKey="UserId" OtherKey="UserId" Type="User" IsForeignKey="true" DeleteRule="CASCADE" />
+ </Type>
+ </Table>
+ <Table Name="" Member="Nonces">
+ <Type Name="Nonce">
+ <Column Member="Context" Type="System.String" IsPrimaryKey="true" CanBeNull="false" />
+ <Column Member="Code" Type="System.String" IsPrimaryKey="true" CanBeNull="false" />
+ <Column Member="Timestamp" Type="System.DateTime" IsPrimaryKey="true" CanBeNull="false" />
+ </Type>
+ </Table>
+</Database> \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/DataClasses.dbml.layout b/src/OAuth/OAuthServiceProvider/Code/DataClasses.dbml.layout
new file mode 100644
index 0000000..9b80443
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/DataClasses.dbml.layout
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ordesignerObjectsDiagram dslVersion="1.0.0.0" absoluteBounds="0, 0, 11, 8.5" name="DataClasses">
+ <DataContextMoniker Name="/DataClassesDataContext" />
+ <nestedChildShapes>
+ <classShape Id="696d2c69-040e-411d-9257-bb664b743834" absoluteBounds="0.5, 0.5, 2.125, 1.7708968098958331">
+ <DataClassMoniker Name="/DataClassesDataContext/User" />
+ <nestedChildShapes>
+ <elementListCompartment Id="cd90aeff-476c-44a9-897f-a986e4a8305b" absoluteBounds="0.515, 0.96, 2.0949999999999998, 1.2108968098958333" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+ </nestedChildShapes>
+ </classShape>
+ <classShape Id="8a79b099-7f87-4766-907a-db2c3e1b5716" absoluteBounds="3.5, 0.625, 2, 1.3862939453125005">
+ <DataClassMoniker Name="/DataClassesDataContext/FavoriteSite" />
+ <nestedChildShapes>
+ <elementListCompartment Id="eba736b9-f9ec-484b-8083-c77155a49e4e" absoluteBounds="3.515, 1.085, 1.9700000000000002, 0.8262939453125" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+ </nestedChildShapes>
+ </classShape>
+ <classShape Id="f909becb-85b1-4fe6-bb16-3feb3e4fe3ee" absoluteBounds="0.625, 3.25, 2, 1.9631982421874996">
+ <DataClassMoniker Name="/DataClassesDataContext/OAuthConsumer" />
+ <nestedChildShapes>
+ <elementListCompartment Id="464308c4-d112-4448-b0c9-d9b82fb0ca4e" absoluteBounds="0.64, 3.71, 1.9700000000000002, 1.4031982421875" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+ </nestedChildShapes>
+ </classShape>
+ <classShape Id="895ebbc8-8352-4c04-9e53-b8e6c8302d36" absoluteBounds="3.5, 3.125, 2, 2.9247054036458326">
+ <DataClassMoniker Name="/DataClassesDataContext/OAuthToken" />
+ <nestedChildShapes>
+ <elementListCompartment Id="403126d0-3d2a-4af4-b0b8-c489a830bbd4" absoluteBounds="3.515, 3.585, 1.9700000000000002, 2.364705403645833" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+ </nestedChildShapes>
+ </classShape>
+ <associationConnector edgePoints="[(2.625 : 1.31814697265625); (3.5 : 1.31814697265625)]" fixedFrom="NotFixed" fixedTo="NotFixed">
+ <AssociationMoniker Name="/DataClassesDataContext/User/User_FavoriteSite" />
+ <nodes>
+ <classShapeMoniker Id="696d2c69-040e-411d-9257-bb664b743834" />
+ <classShapeMoniker Id="8a79b099-7f87-4766-907a-db2c3e1b5716" />
+ </nodes>
+ </associationConnector>
+ <associationConnector edgePoints="[(2.625 : 4.23159912109375); (3.5 : 4.23159912109375)]" fixedFrom="NotFixed" fixedTo="NotFixed">
+ <AssociationMoniker Name="/DataClassesDataContext/OAuthConsumer/OAuthConsumer_OAuthToken" />
+ <nodes>
+ <classShapeMoniker Id="f909becb-85b1-4fe6-bb16-3feb3e4fe3ee" />
+ <classShapeMoniker Id="895ebbc8-8352-4c04-9e53-b8e6c8302d36" />
+ </nodes>
+ </associationConnector>
+ <associationConnector edgePoints="[(0.53125 : 2.27089680989583); (0.53125 : 5.66270182291667); (3.5 : 5.66270182291667)]" fixedFrom="NotFixed" fixedTo="NotFixed">
+ <AssociationMoniker Name="/DataClassesDataContext/User/User_OAuthToken" />
+ <nodes>
+ <classShapeMoniker Id="696d2c69-040e-411d-9257-bb664b743834" />
+ <classShapeMoniker Id="895ebbc8-8352-4c04-9e53-b8e6c8302d36" />
+ </nodes>
+ </associationConnector>
+ <classShape Id="a63562a7-acf2-4ed9-9686-52a1ad85633e" absoluteBounds="1.375, 6.375, 2, 1.3862939453124996">
+ <DataClassMoniker Name="/DataClassesDataContext/Nonce" />
+ <nestedChildShapes>
+ <elementListCompartment Id="9e4514ef-bc7b-4179-88e6-05363bf6ee5e" absoluteBounds="1.39, 6.835, 1.9700000000000002, 0.8262939453125" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+ </nestedChildShapes>
+ </classShape>
+ </nestedChildShapes>
+</ordesignerObjectsDiagram> \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/DataClasses.designer.cs b/src/OAuth/OAuthServiceProvider/Code/DataClasses.designer.cs
new file mode 100644
index 0000000..b7d291c
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/DataClasses.designer.cs
@@ -0,0 +1,1190 @@
+#pragma warning disable 1591
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.1
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthServiceProvider.Code
+{
+ using System.Data.Linq;
+ using System.Data.Linq.Mapping;
+ using System.Data;
+ using System.Collections.Generic;
+ using System.Reflection;
+ using System.Linq;
+ using System.Linq.Expressions;
+ using System.ComponentModel;
+ using System;
+
+
+ [global::System.Data.Linq.Mapping.DatabaseAttribute(Name="Database")]
+ public partial class DataClassesDataContext : System.Data.Linq.DataContext
+ {
+
+ private static System.Data.Linq.Mapping.MappingSource mappingSource = new AttributeMappingSource();
+
+ #region Extensibility Method Definitions
+ partial void OnCreated();
+ partial void InsertUser(User instance);
+ partial void UpdateUser(User instance);
+ partial void DeleteUser(User instance);
+ partial void InsertFavoriteSite(FavoriteSite instance);
+ partial void UpdateFavoriteSite(FavoriteSite instance);
+ partial void DeleteFavoriteSite(FavoriteSite instance);
+ partial void InsertOAuthConsumer(OAuthConsumer instance);
+ partial void UpdateOAuthConsumer(OAuthConsumer instance);
+ partial void DeleteOAuthConsumer(OAuthConsumer instance);
+ partial void InsertOAuthToken(OAuthToken instance);
+ partial void UpdateOAuthToken(OAuthToken instance);
+ partial void DeleteOAuthToken(OAuthToken instance);
+ partial void InsertNonce(Nonce instance);
+ partial void UpdateNonce(Nonce instance);
+ partial void DeleteNonce(Nonce instance);
+ #endregion
+
+ public DataClassesDataContext() :
+ base(global::System.Configuration.ConfigurationManager.ConnectionStrings["DatabaseConnectionString"].ConnectionString, mappingSource)
+ {
+ OnCreated();
+ }
+
+ public DataClassesDataContext(string connection) :
+ base(connection, mappingSource)
+ {
+ OnCreated();
+ }
+
+ public DataClassesDataContext(System.Data.IDbConnection connection) :
+ base(connection, mappingSource)
+ {
+ OnCreated();
+ }
+
+ public DataClassesDataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
+ base(connection, mappingSource)
+ {
+ OnCreated();
+ }
+
+ public DataClassesDataContext(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
+ base(connection, mappingSource)
+ {
+ OnCreated();
+ }
+
+ public System.Data.Linq.Table<User> Users
+ {
+ get
+ {
+ return this.GetTable<User>();
+ }
+ }
+
+ public System.Data.Linq.Table<FavoriteSite> FavoriteSites
+ {
+ get
+ {
+ return this.GetTable<FavoriteSite>();
+ }
+ }
+
+ public System.Data.Linq.Table<OAuthConsumer> OAuthConsumers
+ {
+ get
+ {
+ return this.GetTable<OAuthConsumer>();
+ }
+ }
+
+ public System.Data.Linq.Table<OAuthToken> OAuthTokens
+ {
+ get
+ {
+ return this.GetTable<OAuthToken>();
+ }
+ }
+
+ public System.Data.Linq.Table<Nonce> Nonces
+ {
+ get
+ {
+ return this.GetTable<Nonce>();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[User]")]
+ public partial class User : INotifyPropertyChanging, INotifyPropertyChanged
+ {
+
+ private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(string.Empty);
+
+ private int _UserId;
+
+ private string _OpenIDClaimedIdentifier;
+
+ private string _OpenIDFriendlyIdentifier;
+
+ private string _FullName;
+
+ private System.Nullable<int> _Age;
+
+ private EntitySet<FavoriteSite> _FavoriteSites;
+
+ private EntitySet<OAuthToken> _OAuthTokens;
+
+ #region Extensibility Method Definitions
+ partial void OnLoaded();
+ partial void OnValidate(System.Data.Linq.ChangeAction action);
+ partial void OnCreated();
+ partial void OnUserIdChanging(int value);
+ partial void OnUserIdChanged();
+ partial void OnOpenIDClaimedIdentifierChanging(string value);
+ partial void OnOpenIDClaimedIdentifierChanged();
+ partial void OnOpenIDFriendlyIdentifierChanging(string value);
+ partial void OnOpenIDFriendlyIdentifierChanged();
+ partial void OnFullNameChanging(string value);
+ partial void OnFullNameChanged();
+ partial void OnAgeChanging(System.Nullable<int> value);
+ partial void OnAgeChanged();
+ #endregion
+
+ public User()
+ {
+ this._FavoriteSites = new EntitySet<FavoriteSite>(new Action<FavoriteSite>(this.attach_FavoriteSites), new Action<FavoriteSite>(this.detach_FavoriteSites));
+ this._OAuthTokens = new EntitySet<OAuthToken>(new Action<OAuthToken>(this.attach_OAuthTokens), new Action<OAuthToken>(this.detach_OAuthTokens));
+ OnCreated();
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UserId", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+ public int UserId
+ {
+ get
+ {
+ return this._UserId;
+ }
+ set
+ {
+ if ((this._UserId != value))
+ {
+ this.OnUserIdChanging(value);
+ this.SendPropertyChanging();
+ this._UserId = value;
+ this.SendPropertyChanged("UserId");
+ this.OnUserIdChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OpenIDClaimedIdentifier", DbType="NVarChar(150) NOT NULL", CanBeNull=false)]
+ public string OpenIDClaimedIdentifier
+ {
+ get
+ {
+ return this._OpenIDClaimedIdentifier;
+ }
+ set
+ {
+ if ((this._OpenIDClaimedIdentifier != value))
+ {
+ this.OnOpenIDClaimedIdentifierChanging(value);
+ this.SendPropertyChanging();
+ this._OpenIDClaimedIdentifier = value;
+ this.SendPropertyChanged("OpenIDClaimedIdentifier");
+ this.OnOpenIDClaimedIdentifierChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OpenIDFriendlyIdentifier", DbType="NVarChar(150)")]
+ public string OpenIDFriendlyIdentifier
+ {
+ get
+ {
+ return this._OpenIDFriendlyIdentifier;
+ }
+ set
+ {
+ if ((this._OpenIDFriendlyIdentifier != value))
+ {
+ this.OnOpenIDFriendlyIdentifierChanging(value);
+ this.SendPropertyChanging();
+ this._OpenIDFriendlyIdentifier = value;
+ this.SendPropertyChanged("OpenIDFriendlyIdentifier");
+ this.OnOpenIDFriendlyIdentifierChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_FullName", DbType="NVarChar(150)", CanBeNull=false)]
+ public string FullName
+ {
+ get
+ {
+ return this._FullName;
+ }
+ set
+ {
+ if ((this._FullName != value))
+ {
+ this.OnFullNameChanging(value);
+ this.SendPropertyChanging();
+ this._FullName = value;
+ this.SendPropertyChanged("FullName");
+ this.OnFullNameChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Age", DbType="int")]
+ public System.Nullable<int> Age
+ {
+ get
+ {
+ return this._Age;
+ }
+ set
+ {
+ if ((this._Age != value))
+ {
+ this.OnAgeChanging(value);
+ this.SendPropertyChanging();
+ this._Age = value;
+ this.SendPropertyChanged("Age");
+ this.OnAgeChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.AssociationAttribute(Name="User_FavoriteSite", Storage="_FavoriteSites", ThisKey="UserId", OtherKey="UserId")]
+ public EntitySet<FavoriteSite> FavoriteSites
+ {
+ get
+ {
+ return this._FavoriteSites;
+ }
+ set
+ {
+ this._FavoriteSites.Assign(value);
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.AssociationAttribute(Name="User_OAuthToken", Storage="_OAuthTokens", ThisKey="UserId", OtherKey="UserId")]
+ public EntitySet<OAuthToken> OAuthTokens
+ {
+ get
+ {
+ return this._OAuthTokens;
+ }
+ set
+ {
+ this._OAuthTokens.Assign(value);
+ }
+ }
+
+ public event PropertyChangingEventHandler PropertyChanging;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void SendPropertyChanging()
+ {
+ if ((this.PropertyChanging != null))
+ {
+ this.PropertyChanging(this, emptyChangingEventArgs);
+ }
+ }
+
+ protected virtual void SendPropertyChanged(String propertyName)
+ {
+ if ((this.PropertyChanged != null))
+ {
+ this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+
+ private void attach_FavoriteSites(FavoriteSite entity)
+ {
+ this.SendPropertyChanging();
+ entity.User = this;
+ }
+
+ private void detach_FavoriteSites(FavoriteSite entity)
+ {
+ this.SendPropertyChanging();
+ entity.User = null;
+ }
+
+ private void attach_OAuthTokens(OAuthToken entity)
+ {
+ this.SendPropertyChanging();
+ entity.User = this;
+ }
+
+ private void detach_OAuthTokens(OAuthToken entity)
+ {
+ this.SendPropertyChanging();
+ entity.User = null;
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.FavoriteSite")]
+ public partial class FavoriteSite : INotifyPropertyChanging, INotifyPropertyChanged
+ {
+
+ private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(string.Empty);
+
+ private int _FavoriteSiteId;
+
+ private int _UserId;
+
+ private string _SiteUrl;
+
+ private EntityRef<User> _User;
+
+ #region Extensibility Method Definitions
+ partial void OnLoaded();
+ partial void OnValidate(System.Data.Linq.ChangeAction action);
+ partial void OnCreated();
+ partial void OnFavoriteSiteIdChanging(int value);
+ partial void OnFavoriteSiteIdChanged();
+ partial void OnUserIdChanging(int value);
+ partial void OnUserIdChanged();
+ partial void OnSiteUrlChanging(string value);
+ partial void OnSiteUrlChanged();
+ #endregion
+
+ public FavoriteSite()
+ {
+ this._User = default(EntityRef<User>);
+ OnCreated();
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_FavoriteSiteId", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+ public int FavoriteSiteId
+ {
+ get
+ {
+ return this._FavoriteSiteId;
+ }
+ set
+ {
+ if ((this._FavoriteSiteId != value))
+ {
+ this.OnFavoriteSiteIdChanging(value);
+ this.SendPropertyChanging();
+ this._FavoriteSiteId = value;
+ this.SendPropertyChanged("FavoriteSiteId");
+ this.OnFavoriteSiteIdChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UserId", DbType="Int NOT NULL")]
+ public int UserId
+ {
+ get
+ {
+ return this._UserId;
+ }
+ set
+ {
+ if ((this._UserId != value))
+ {
+ if (this._User.HasLoadedOrAssignedValue)
+ {
+ throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+ }
+ this.OnUserIdChanging(value);
+ this.SendPropertyChanging();
+ this._UserId = value;
+ this.SendPropertyChanged("UserId");
+ this.OnUserIdChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_SiteUrl", DbType="NVarChar(255) NOT NULL", CanBeNull=false)]
+ public string SiteUrl
+ {
+ get
+ {
+ return this._SiteUrl;
+ }
+ set
+ {
+ if ((this._SiteUrl != value))
+ {
+ this.OnSiteUrlChanging(value);
+ this.SendPropertyChanging();
+ this._SiteUrl = value;
+ this.SendPropertyChanged("SiteUrl");
+ this.OnSiteUrlChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.AssociationAttribute(Name="User_FavoriteSite", Storage="_User", ThisKey="UserId", OtherKey="UserId", IsForeignKey=true, DeleteOnNull=true, DeleteRule="CASCADE")]
+ public User User
+ {
+ get
+ {
+ return this._User.Entity;
+ }
+ set
+ {
+ User previousValue = this._User.Entity;
+ if (((previousValue != value)
+ || (this._User.HasLoadedOrAssignedValue == false)))
+ {
+ this.SendPropertyChanging();
+ if ((previousValue != null))
+ {
+ this._User.Entity = null;
+ previousValue.FavoriteSites.Remove(this);
+ }
+ this._User.Entity = value;
+ if ((value != null))
+ {
+ value.FavoriteSites.Add(this);
+ this._UserId = value.UserId;
+ }
+ else
+ {
+ this._UserId = default(int);
+ }
+ this.SendPropertyChanged("User");
+ }
+ }
+ }
+
+ public event PropertyChangingEventHandler PropertyChanging;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void SendPropertyChanging()
+ {
+ if ((this.PropertyChanging != null))
+ {
+ this.PropertyChanging(this, emptyChangingEventArgs);
+ }
+ }
+
+ protected virtual void SendPropertyChanged(String propertyName)
+ {
+ if ((this.PropertyChanged != null))
+ {
+ this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.OAuthConsumer")]
+ public partial class OAuthConsumer : INotifyPropertyChanging, INotifyPropertyChanged
+ {
+
+ private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(string.Empty);
+
+ private int _ConsumerId;
+
+ private string _ConsumerKey;
+
+ private string _ConsumerSecret;
+
+ private string _Callback;
+
+ private DotNetOpenAuth.OAuth.VerificationCodeFormat _VerificationCodeFormat;
+
+ private int _VerificationCodeLength;
+
+ private EntitySet<OAuthToken> _OAuthTokens;
+
+ #region Extensibility Method Definitions
+ partial void OnLoaded();
+ partial void OnValidate(System.Data.Linq.ChangeAction action);
+ partial void OnCreated();
+ partial void OnConsumerIdChanging(int value);
+ partial void OnConsumerIdChanged();
+ partial void OnConsumerKeyChanging(string value);
+ partial void OnConsumerKeyChanged();
+ partial void OnConsumerSecretChanging(string value);
+ partial void OnConsumerSecretChanged();
+ partial void OnCallbackChanging(string value);
+ partial void OnCallbackChanged();
+ partial void OnVerificationCodeFormatChanging(DotNetOpenAuth.OAuth.VerificationCodeFormat value);
+ partial void OnVerificationCodeFormatChanged();
+ partial void OnVerificationCodeLengthChanging(int value);
+ partial void OnVerificationCodeLengthChanged();
+ #endregion
+
+ public OAuthConsumer()
+ {
+ this._OAuthTokens = new EntitySet<OAuthToken>(new Action<OAuthToken>(this.attach_OAuthTokens), new Action<OAuthToken>(this.detach_OAuthTokens));
+ OnCreated();
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ConsumerId", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+ public int ConsumerId
+ {
+ get
+ {
+ return this._ConsumerId;
+ }
+ set
+ {
+ if ((this._ConsumerId != value))
+ {
+ this.OnConsumerIdChanging(value);
+ this.SendPropertyChanging();
+ this._ConsumerId = value;
+ this.SendPropertyChanged("ConsumerId");
+ this.OnConsumerIdChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ConsumerKey", DbType="NVarChar(50) NOT NULL", CanBeNull=false)]
+ public string ConsumerKey
+ {
+ get
+ {
+ return this._ConsumerKey;
+ }
+ set
+ {
+ if ((this._ConsumerKey != value))
+ {
+ this.OnConsumerKeyChanging(value);
+ this.SendPropertyChanging();
+ this._ConsumerKey = value;
+ this.SendPropertyChanged("ConsumerKey");
+ this.OnConsumerKeyChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ConsumerSecret", DbType="NVarChar(50) NOT NULL", CanBeNull=false)]
+ public string ConsumerSecret
+ {
+ get
+ {
+ return this._ConsumerSecret;
+ }
+ set
+ {
+ if ((this._ConsumerSecret != value))
+ {
+ this.OnConsumerSecretChanging(value);
+ this.SendPropertyChanging();
+ this._ConsumerSecret = value;
+ this.SendPropertyChanged("ConsumerSecret");
+ this.OnConsumerSecretChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Callback")]
+ public string Callback
+ {
+ get
+ {
+ return this._Callback;
+ }
+ set
+ {
+ if ((this._Callback != value))
+ {
+ this.OnCallbackChanging(value);
+ this.SendPropertyChanging();
+ this._Callback = value;
+ this.SendPropertyChanged("Callback");
+ this.OnCallbackChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_VerificationCodeFormat")]
+ public DotNetOpenAuth.OAuth.VerificationCodeFormat VerificationCodeFormat
+ {
+ get
+ {
+ return this._VerificationCodeFormat;
+ }
+ set
+ {
+ if ((this._VerificationCodeFormat != value))
+ {
+ this.OnVerificationCodeFormatChanging(value);
+ this.SendPropertyChanging();
+ this._VerificationCodeFormat = value;
+ this.SendPropertyChanged("VerificationCodeFormat");
+ this.OnVerificationCodeFormatChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_VerificationCodeLength")]
+ public int VerificationCodeLength
+ {
+ get
+ {
+ return this._VerificationCodeLength;
+ }
+ set
+ {
+ if ((this._VerificationCodeLength != value))
+ {
+ this.OnVerificationCodeLengthChanging(value);
+ this.SendPropertyChanging();
+ this._VerificationCodeLength = value;
+ this.SendPropertyChanged("VerificationCodeLength");
+ this.OnVerificationCodeLengthChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.AssociationAttribute(Name="OAuthConsumer_OAuthToken", Storage="_OAuthTokens", ThisKey="ConsumerId", OtherKey="ConsumerId")]
+ public EntitySet<OAuthToken> OAuthTokens
+ {
+ get
+ {
+ return this._OAuthTokens;
+ }
+ set
+ {
+ this._OAuthTokens.Assign(value);
+ }
+ }
+
+ public event PropertyChangingEventHandler PropertyChanging;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void SendPropertyChanging()
+ {
+ if ((this.PropertyChanging != null))
+ {
+ this.PropertyChanging(this, emptyChangingEventArgs);
+ }
+ }
+
+ protected virtual void SendPropertyChanged(String propertyName)
+ {
+ if ((this.PropertyChanged != null))
+ {
+ this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+
+ private void attach_OAuthTokens(OAuthToken entity)
+ {
+ this.SendPropertyChanging();
+ entity.OAuthConsumer = this;
+ }
+
+ private void detach_OAuthTokens(OAuthToken entity)
+ {
+ this.SendPropertyChanging();
+ entity.OAuthConsumer = null;
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.OAuthToken")]
+ public partial class OAuthToken : INotifyPropertyChanging, INotifyPropertyChanged
+ {
+
+ private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(string.Empty);
+
+ private int _TokenId;
+
+ private string _Token;
+
+ private string _TokenSecret;
+
+ private OAuthServiceProvider.Code.TokenAuthorizationState _State;
+
+ private System.DateTime _IssueDate;
+
+ private int _ConsumerId;
+
+ private System.Nullable<int> _UserId;
+
+ private string _Scope;
+
+ private string _RequestTokenVerifier;
+
+ private string _RequestTokenCallback;
+
+ private string _ConsumerVersion;
+
+ private EntityRef<OAuthConsumer> _OAuthConsumer;
+
+ private EntityRef<User> _User;
+
+ #region Extensibility Method Definitions
+ partial void OnLoaded();
+ partial void OnValidate(System.Data.Linq.ChangeAction action);
+ partial void OnCreated();
+ partial void OnTokenIdChanging(int value);
+ partial void OnTokenIdChanged();
+ partial void OnTokenChanging(string value);
+ partial void OnTokenChanged();
+ partial void OnTokenSecretChanging(string value);
+ partial void OnTokenSecretChanged();
+ partial void OnStateChanging(OAuthServiceProvider.Code.TokenAuthorizationState value);
+ partial void OnStateChanged();
+ partial void OnIssueDateChanging(System.DateTime value);
+ partial void OnIssueDateChanged();
+ partial void OnConsumerIdChanging(int value);
+ partial void OnConsumerIdChanged();
+ partial void OnUserIdChanging(System.Nullable<int> value);
+ partial void OnUserIdChanged();
+ partial void OnScopeChanging(string value);
+ partial void OnScopeChanged();
+ partial void OnRequestTokenVerifierChanging(string value);
+ partial void OnRequestTokenVerifierChanged();
+ partial void OnRequestTokenCallbackChanging(string value);
+ partial void OnRequestTokenCallbackChanged();
+ partial void OnConsumerVersionChanging(string value);
+ partial void OnConsumerVersionChanged();
+ #endregion
+
+ public OAuthToken()
+ {
+ this._OAuthConsumer = default(EntityRef<OAuthConsumer>);
+ this._User = default(EntityRef<User>);
+ OnCreated();
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_TokenId", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+ public int TokenId
+ {
+ get
+ {
+ return this._TokenId;
+ }
+ set
+ {
+ if ((this._TokenId != value))
+ {
+ this.OnTokenIdChanging(value);
+ this.SendPropertyChanging();
+ this._TokenId = value;
+ this.SendPropertyChanged("TokenId");
+ this.OnTokenIdChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Token", DbType="NVarChar(50) NOT NULL", CanBeNull=false)]
+ public string Token
+ {
+ get
+ {
+ return this._Token;
+ }
+ set
+ {
+ if ((this._Token != value))
+ {
+ this.OnTokenChanging(value);
+ this.SendPropertyChanging();
+ this._Token = value;
+ this.SendPropertyChanged("Token");
+ this.OnTokenChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_TokenSecret", DbType="NVarChar(50) NOT NULL", CanBeNull=false)]
+ public string TokenSecret
+ {
+ get
+ {
+ return this._TokenSecret;
+ }
+ set
+ {
+ if ((this._TokenSecret != value))
+ {
+ this.OnTokenSecretChanging(value);
+ this.SendPropertyChanging();
+ this._TokenSecret = value;
+ this.SendPropertyChanged("TokenSecret");
+ this.OnTokenSecretChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_State", DbType="INT NOT NULL", CanBeNull=false)]
+ public OAuthServiceProvider.Code.TokenAuthorizationState State
+ {
+ get
+ {
+ return this._State;
+ }
+ set
+ {
+ if ((this._State != value))
+ {
+ this.OnStateChanging(value);
+ this.SendPropertyChanging();
+ this._State = value;
+ this.SendPropertyChanged("State");
+ this.OnStateChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_IssueDate", DbType="DateTime NOT NULL")]
+ public System.DateTime IssueDate
+ {
+ get
+ {
+ return this._IssueDate;
+ }
+ set
+ {
+ if ((this._IssueDate != value))
+ {
+ this.OnIssueDateChanging(value);
+ this.SendPropertyChanging();
+ this._IssueDate = value;
+ this.SendPropertyChanged("IssueDate");
+ this.OnIssueDateChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ConsumerId", DbType="Int NOT NULL")]
+ public int ConsumerId
+ {
+ get
+ {
+ return this._ConsumerId;
+ }
+ set
+ {
+ if ((this._ConsumerId != value))
+ {
+ if (this._OAuthConsumer.HasLoadedOrAssignedValue)
+ {
+ throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+ }
+ this.OnConsumerIdChanging(value);
+ this.SendPropertyChanging();
+ this._ConsumerId = value;
+ this.SendPropertyChanged("ConsumerId");
+ this.OnConsumerIdChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UserId", DbType="Int")]
+ public System.Nullable<int> UserId
+ {
+ get
+ {
+ return this._UserId;
+ }
+ set
+ {
+ if ((this._UserId != value))
+ {
+ if (this._User.HasLoadedOrAssignedValue)
+ {
+ throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+ }
+ this.OnUserIdChanging(value);
+ this.SendPropertyChanging();
+ this._UserId = value;
+ this.SendPropertyChanged("UserId");
+ this.OnUserIdChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Scope", DbType="nvarchar(MAX)", CanBeNull=false)]
+ public string Scope
+ {
+ get
+ {
+ return this._Scope;
+ }
+ set
+ {
+ if ((this._Scope != value))
+ {
+ this.OnScopeChanging(value);
+ this.SendPropertyChanging();
+ this._Scope = value;
+ this.SendPropertyChanged("Scope");
+ this.OnScopeChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_RequestTokenVerifier")]
+ public string RequestTokenVerifier
+ {
+ get
+ {
+ return this._RequestTokenVerifier;
+ }
+ set
+ {
+ if ((this._RequestTokenVerifier != value))
+ {
+ this.OnRequestTokenVerifierChanging(value);
+ this.SendPropertyChanging();
+ this._RequestTokenVerifier = value;
+ this.SendPropertyChanged("RequestTokenVerifier");
+ this.OnRequestTokenVerifierChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_RequestTokenCallback")]
+ public string RequestTokenCallback
+ {
+ get
+ {
+ return this._RequestTokenCallback;
+ }
+ set
+ {
+ if ((this._RequestTokenCallback != value))
+ {
+ this.OnRequestTokenCallbackChanging(value);
+ this.SendPropertyChanging();
+ this._RequestTokenCallback = value;
+ this.SendPropertyChanged("RequestTokenCallback");
+ this.OnRequestTokenCallbackChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ConsumerVersion")]
+ public string ConsumerVersion
+ {
+ get
+ {
+ return this._ConsumerVersion;
+ }
+ set
+ {
+ if ((this._ConsumerVersion != value))
+ {
+ this.OnConsumerVersionChanging(value);
+ this.SendPropertyChanging();
+ this._ConsumerVersion = value;
+ this.SendPropertyChanged("ConsumerVersion");
+ this.OnConsumerVersionChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.AssociationAttribute(Name="OAuthConsumer_OAuthToken", Storage="_OAuthConsumer", ThisKey="ConsumerId", OtherKey="ConsumerId", IsForeignKey=true, DeleteOnNull=true, DeleteRule="CASCADE")]
+ public OAuthConsumer OAuthConsumer
+ {
+ get
+ {
+ return this._OAuthConsumer.Entity;
+ }
+ set
+ {
+ OAuthConsumer previousValue = this._OAuthConsumer.Entity;
+ if (((previousValue != value)
+ || (this._OAuthConsumer.HasLoadedOrAssignedValue == false)))
+ {
+ this.SendPropertyChanging();
+ if ((previousValue != null))
+ {
+ this._OAuthConsumer.Entity = null;
+ previousValue.OAuthTokens.Remove(this);
+ }
+ this._OAuthConsumer.Entity = value;
+ if ((value != null))
+ {
+ value.OAuthTokens.Add(this);
+ this._ConsumerId = value.ConsumerId;
+ }
+ else
+ {
+ this._ConsumerId = default(int);
+ }
+ this.SendPropertyChanged("OAuthConsumer");
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.AssociationAttribute(Name="User_OAuthToken", Storage="_User", ThisKey="UserId", OtherKey="UserId", IsForeignKey=true, DeleteRule="CASCADE")]
+ public User User
+ {
+ get
+ {
+ return this._User.Entity;
+ }
+ set
+ {
+ User previousValue = this._User.Entity;
+ if (((previousValue != value)
+ || (this._User.HasLoadedOrAssignedValue == false)))
+ {
+ this.SendPropertyChanging();
+ if ((previousValue != null))
+ {
+ this._User.Entity = null;
+ previousValue.OAuthTokens.Remove(this);
+ }
+ this._User.Entity = value;
+ if ((value != null))
+ {
+ value.OAuthTokens.Add(this);
+ this._UserId = value.UserId;
+ }
+ else
+ {
+ this._UserId = default(Nullable<int>);
+ }
+ this.SendPropertyChanged("User");
+ }
+ }
+ }
+
+ public event PropertyChangingEventHandler PropertyChanging;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void SendPropertyChanging()
+ {
+ if ((this.PropertyChanging != null))
+ {
+ this.PropertyChanging(this, emptyChangingEventArgs);
+ }
+ }
+
+ protected virtual void SendPropertyChanged(String propertyName)
+ {
+ if ((this.PropertyChanged != null))
+ {
+ this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.TableAttribute(Name="")]
+ public partial class Nonce : INotifyPropertyChanging, INotifyPropertyChanged
+ {
+
+ private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(string.Empty);
+
+ private string _Context;
+
+ private string _Code;
+
+ private System.DateTime _Timestamp;
+
+ #region Extensibility Method Definitions
+ partial void OnLoaded();
+ partial void OnValidate(System.Data.Linq.ChangeAction action);
+ partial void OnCreated();
+ partial void OnContextChanging(string value);
+ partial void OnContextChanged();
+ partial void OnCodeChanging(string value);
+ partial void OnCodeChanged();
+ partial void OnTimestampChanging(System.DateTime value);
+ partial void OnTimestampChanged();
+ #endregion
+
+ public Nonce()
+ {
+ OnCreated();
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Context", CanBeNull=false, IsPrimaryKey=true)]
+ public string Context
+ {
+ get
+ {
+ return this._Context;
+ }
+ set
+ {
+ if ((this._Context != value))
+ {
+ this.OnContextChanging(value);
+ this.SendPropertyChanging();
+ this._Context = value;
+ this.SendPropertyChanged("Context");
+ this.OnContextChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Code", CanBeNull=false, IsPrimaryKey=true)]
+ public string Code
+ {
+ get
+ {
+ return this._Code;
+ }
+ set
+ {
+ if ((this._Code != value))
+ {
+ this.OnCodeChanging(value);
+ this.SendPropertyChanging();
+ this._Code = value;
+ this.SendPropertyChanged("Code");
+ this.OnCodeChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Timestamp", IsPrimaryKey=true)]
+ public System.DateTime Timestamp
+ {
+ get
+ {
+ return this._Timestamp;
+ }
+ set
+ {
+ if ((this._Timestamp != value))
+ {
+ this.OnTimestampChanging(value);
+ this.SendPropertyChanging();
+ this._Timestamp = value;
+ this.SendPropertyChanged("Timestamp");
+ this.OnTimestampChanged();
+ }
+ }
+ }
+
+ public event PropertyChangingEventHandler PropertyChanging;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void SendPropertyChanging()
+ {
+ if ((this.PropertyChanging != null))
+ {
+ this.PropertyChanging(this, emptyChangingEventArgs);
+ }
+ }
+
+ protected virtual void SendPropertyChanged(String propertyName)
+ {
+ if ((this.PropertyChanged != null))
+ {
+ this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+ }
+}
+#pragma warning restore 1591
diff --git a/src/OAuth/OAuthServiceProvider/Code/DatabaseNonceStore.cs b/src/OAuth/OAuthServiceProvider/Code/DatabaseNonceStore.cs
new file mode 100644
index 0000000..1f8f56e
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/DatabaseNonceStore.cs
@@ -0,0 +1,55 @@
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using DotNetOpenAuth.Messaging.Bindings;
+
+ /// <summary>
+ /// A database-persisted nonce store.
+ /// </summary>
+ public class DatabaseNonceStore : INonceStore {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DatabaseNonceStore"/> class.
+ /// </summary>
+ public DatabaseNonceStore() {
+ }
+
+ #region INonceStore Members
+
+ /// <summary>
+ /// Stores a given nonce and timestamp.
+ /// </summary>
+ /// <param name="context">The context, or namespace, within which the
+ /// <paramref name="nonce"/> must be unique.
+ /// The context SHOULD be treated as case-sensitive.
+ /// The value will never be <c>null</c> but may be the empty string.</param>
+ /// <param name="nonce">A series of random characters.</param>
+ /// <param name="timestampUtc">The UTC timestamp that together with the nonce string make it unique
+ /// within the given <paramref name="context"/>.
+ /// The timestamp may also be used by the data store to clear out old nonces.</param>
+ /// <returns>
+ /// True if the context+nonce+timestamp (combination) was not previously in the database.
+ /// False if the nonce was stored previously with the same timestamp and context.
+ /// </returns>
+ /// <remarks>
+ /// The nonce must be stored for no less than the maximum time window a message may
+ /// be processed within before being discarded as an expired message.
+ /// This maximum message age can be looked up via the
+ /// <see cref="DotNetOpenAuth.Configuration.MessagingElement.MaximumMessageLifetime"/>
+ /// property, accessible via the <see cref="DotNetOpenAuth.Configuration.DotNetOpenAuthSection.Configuration"/>
+ /// property.
+ /// </remarks>
+ public bool StoreNonce(string context, string nonce, DateTime timestampUtc) {
+ Global.DataContext.Nonces.InsertOnSubmit(new Nonce { Context = context, Code = nonce, Timestamp = timestampUtc });
+ try {
+ Global.DataContext.SubmitChanges();
+ return true;
+ } catch (System.Data.Linq.DuplicateKeyException) {
+ return false;
+ }
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/DatabaseTokenManager.cs b/src/OAuth/OAuthServiceProvider/Code/DatabaseTokenManager.cs
new file mode 100644
index 0000000..49da45d
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/DatabaseTokenManager.cs
@@ -0,0 +1,163 @@
+//-----------------------------------------------------------------------
+// <copyright file="DatabaseTokenManager.cs" company="Outercurve Foundation">
+// Copyright (c) Outercurve Foundation. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.Linq;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+ using DotNetOpenAuth.OAuth.Messages;
+
+ public class DatabaseTokenManager : IServiceProviderTokenManager {
+ #region IServiceProviderTokenManager
+
+ public IConsumerDescription GetConsumer(string consumerKey) {
+ var consumerRow = Global.DataContext.OAuthConsumers.SingleOrDefault(
+ consumerCandidate => consumerCandidate.ConsumerKey == consumerKey);
+ if (consumerRow == null) {
+ throw new KeyNotFoundException();
+ }
+
+ return consumerRow;
+ }
+
+ public IServiceProviderRequestToken GetRequestToken(string token) {
+ try {
+ return Global.DataContext.OAuthTokens.First(t => t.Token == token && t.State != TokenAuthorizationState.AccessToken);
+ } catch (InvalidOperationException ex) {
+ throw new KeyNotFoundException("Unrecognized token", ex);
+ }
+ }
+
+ public IServiceProviderAccessToken GetAccessToken(string token) {
+ try {
+ return Global.DataContext.OAuthTokens.First(t => t.Token == token && t.State == TokenAuthorizationState.AccessToken);
+ } catch (InvalidOperationException ex) {
+ throw new KeyNotFoundException("Unrecognized token", ex);
+ }
+ }
+
+ public void UpdateToken(IServiceProviderRequestToken token) {
+ // Nothing to do here, since we're using Linq To SQL, and
+ // We call LinqToSql's SubmitChanges method via our Global.Application_EndRequest method.
+ // This is a good pattern because we only save changes if the request didn't end up somehow failing.
+ // But if you DO want to save changes at this point, you could do it like so:
+ ////Global.DataContext.SubmitChanges();
+ }
+
+ #endregion
+
+ #region ITokenManager Members
+
+ public string GetTokenSecret(string token) {
+ var tokenRow = Global.DataContext.OAuthTokens.SingleOrDefault(
+ tokenCandidate => tokenCandidate.Token == token);
+ if (tokenRow == null) {
+ throw new ArgumentException();
+ }
+
+ return tokenRow.TokenSecret;
+ }
+
+ public void StoreNewRequestToken(UnauthorizedTokenRequest request, ITokenSecretContainingMessage response) {
+ RequestScopedTokenMessage scopedRequest = (RequestScopedTokenMessage)request;
+ var consumer = Global.DataContext.OAuthConsumers.Single(consumerRow => consumerRow.ConsumerKey == request.ConsumerKey);
+ string scope = scopedRequest.Scope;
+ OAuthToken newToken = new OAuthToken {
+ OAuthConsumer = consumer,
+ Token = response.Token,
+ TokenSecret = response.TokenSecret,
+ IssueDate = DateTime.UtcNow,
+ Scope = scope,
+ };
+
+ Global.DataContext.OAuthTokens.InsertOnSubmit(newToken);
+ Global.DataContext.SubmitChanges();
+ }
+
+ /// <summary>
+ /// Checks whether a given request token has already been authorized
+ /// by some user for use by the Consumer that requested it.
+ /// </summary>
+ /// <param name="requestToken">The Consumer's request token.</param>
+ /// <returns>
+ /// True if the request token has already been fully authorized by the user
+ /// who owns the relevant protected resources. False if the token has not yet
+ /// been authorized, has expired or does not exist.
+ /// </returns>
+ public bool IsRequestTokenAuthorized(string requestToken) {
+ var tokenFound = Global.DataContext.OAuthTokens.SingleOrDefault(
+ token => token.Token == requestToken &&
+ token.State == TokenAuthorizationState.AuthorizedRequestToken);
+ return tokenFound != null;
+ }
+
+ public void ExpireRequestTokenAndStoreNewAccessToken(string consumerKey, string requestToken, string accessToken, string accessTokenSecret) {
+ var data = Global.DataContext;
+ var consumerRow = data.OAuthConsumers.Single(consumer => consumer.ConsumerKey == consumerKey);
+ var tokenRow = data.OAuthTokens.Single(token => token.Token == requestToken && token.OAuthConsumer == consumerRow);
+ Debug.Assert(tokenRow.State == TokenAuthorizationState.AuthorizedRequestToken, "The token should be authorized already!");
+
+ // Update the existing row to be an access token.
+ tokenRow.IssueDate = DateTime.UtcNow;
+ tokenRow.State = TokenAuthorizationState.AccessToken;
+ tokenRow.Token = accessToken;
+ tokenRow.TokenSecret = accessTokenSecret;
+ }
+
+ /// <summary>
+ /// Classifies a token as a request token or an access token.
+ /// </summary>
+ /// <param name="token">The token to classify.</param>
+ /// <returns>Request or Access token, or invalid if the token is not recognized.</returns>
+ public TokenType GetTokenType(string token) {
+ var tokenRow = Global.DataContext.OAuthTokens.SingleOrDefault(tokenCandidate => tokenCandidate.Token == token);
+ if (tokenRow == null) {
+ return TokenType.InvalidToken;
+ } else if (tokenRow.State == TokenAuthorizationState.AccessToken) {
+ return TokenType.AccessToken;
+ } else {
+ return TokenType.RequestToken;
+ }
+ }
+
+ #endregion
+
+ public void AuthorizeRequestToken(string requestToken, User user) {
+ if (requestToken == null) {
+ throw new ArgumentNullException("requestToken");
+ }
+ if (user == null) {
+ throw new ArgumentNullException("user");
+ }
+
+ var tokenRow = Global.DataContext.OAuthTokens.SingleOrDefault(
+ tokenCandidate => tokenCandidate.Token == requestToken &&
+ tokenCandidate.State == TokenAuthorizationState.UnauthorizedRequestToken);
+ if (tokenRow == null) {
+ throw new ArgumentException();
+ }
+
+ tokenRow.State = TokenAuthorizationState.AuthorizedRequestToken;
+ tokenRow.User = user;
+ }
+
+ public OAuthConsumer GetConsumerForToken(string token) {
+ if (string.IsNullOrEmpty(token)) {
+ throw new ArgumentNullException("requestToken");
+ }
+
+ var tokenRow = Global.DataContext.OAuthTokens.SingleOrDefault(
+ tokenCandidate => tokenCandidate.Token == token);
+ if (tokenRow == null) {
+ throw new ArgumentException();
+ }
+
+ return tokenRow.OAuthConsumer;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/Global.cs b/src/OAuth/OAuthServiceProvider/Code/Global.cs
new file mode 100644
index 0000000..60fed9f
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/Global.cs
@@ -0,0 +1,135 @@
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Linq;
+ using System.ServiceModel;
+ using System.Text;
+ using System.Web;
+ using DotNetOpenAuth.OAuth.Messages;
+
+ /// <summary>
+ /// The web application global events and properties.
+ /// </summary>
+ public class Global : HttpApplication {
+ /// <summary>
+ /// An application memory cache of recent log messages.
+ /// </summary>
+ public static StringBuilder LogMessages = new StringBuilder();
+
+ /// <summary>
+ /// The logger for this sample to use.
+ /// </summary>
+ public static log4net.ILog Logger = log4net.LogManager.GetLogger("DotNetOpenAuth.OAuthServiceProvider");
+
+ /// <summary>
+ /// Gets the transaction-protected database connection for the current request.
+ /// </summary>
+ public static DataClassesDataContext DataContext {
+ get {
+ DataClassesDataContext dataContext = dataContextSimple;
+ if (dataContext == null) {
+ dataContext = new DataClassesDataContext();
+ dataContext.Connection.Open();
+ dataContext.Transaction = dataContext.Connection.BeginTransaction();
+ dataContextSimple = dataContext;
+ }
+
+ return dataContext;
+ }
+ }
+
+ public static DatabaseTokenManager TokenManager { get; set; }
+
+ public static DatabaseNonceStore NonceStore { get; set; }
+
+ public static User LoggedInUser {
+ get { return Global.DataContext.Users.SingleOrDefault(user => user.OpenIDClaimedIdentifier == HttpContext.Current.User.Identity.Name); }
+ }
+
+ public static UserAuthorizationRequest PendingOAuthAuthorization {
+ get { return HttpContext.Current.Session["authrequest"] as UserAuthorizationRequest; }
+ set { HttpContext.Current.Session["authrequest"] = value; }
+ }
+
+ private static DataClassesDataContext dataContextSimple {
+ get {
+ if (HttpContext.Current != null) {
+ return HttpContext.Current.Items["DataContext"] as DataClassesDataContext;
+ } else if (OperationContext.Current != null) {
+ object data;
+ if (OperationContext.Current.IncomingMessageProperties.TryGetValue("DataContext", out data)) {
+ return data as DataClassesDataContext;
+ } else {
+ return null;
+ }
+ } else {
+ throw new InvalidOperationException();
+ }
+ }
+
+ set {
+ if (HttpContext.Current != null) {
+ HttpContext.Current.Items["DataContext"] = value;
+ } else if (OperationContext.Current != null) {
+ OperationContext.Current.IncomingMessageProperties["DataContext"] = value;
+ } else {
+ throw new InvalidOperationException();
+ }
+ }
+ }
+
+ public static void AuthorizePendingRequestToken() {
+ ITokenContainingMessage tokenMessage = PendingOAuthAuthorization;
+ TokenManager.AuthorizeRequestToken(tokenMessage.Token, LoggedInUser);
+ PendingOAuthAuthorization = null;
+ }
+
+ private static void CommitAndCloseDatabaseIfNecessary() {
+ var dataContext = dataContextSimple;
+ if (dataContext != null) {
+ dataContext.SubmitChanges();
+ dataContext.Transaction.Commit();
+ dataContext.Connection.Close();
+ }
+ }
+
+ private void Application_Start(object sender, EventArgs e) {
+ log4net.Config.XmlConfigurator.Configure();
+ Logger.Info("Sample starting...");
+ string appPath = HttpContext.Current.Request.ApplicationPath;
+ if (!appPath.EndsWith("/")) {
+ appPath += "/";
+ }
+
+ // This will break in IIS Integrated Pipeline mode, since applications
+ // start before the first incoming request context is available.
+ // TODO: fix this.
+ Constants.WebRootUrl = new Uri(HttpContext.Current.Request.Url, appPath);
+ Global.TokenManager = new DatabaseTokenManager();
+ Global.NonceStore = new DatabaseNonceStore();
+ }
+
+ private void Application_End(object sender, EventArgs e) {
+ Logger.Info("Sample shutting down...");
+
+ // this would be automatic, but in partial trust scenarios it is not.
+ log4net.LogManager.Shutdown();
+ }
+
+ private void Application_Error(object sender, EventArgs e) {
+ Logger.Error("An unhandled exception occurred in ASP.NET processing: " + Server.GetLastError(), Server.GetLastError());
+
+ // In the event of an unhandled exception, reverse any changes that were made to the database to avoid any partial database updates.
+ var dataContext = dataContextSimple;
+ if (dataContext != null) {
+ dataContext.Transaction.Rollback();
+ dataContext.Connection.Close();
+ dataContext.Dispose();
+ dataContextSimple = null;
+ }
+ }
+
+ private void Application_EndRequest(object sender, EventArgs e) {
+ CommitAndCloseDatabaseIfNecessary();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/IDataApi.cs b/src/OAuth/OAuthServiceProvider/Code/IDataApi.cs
new file mode 100644
index 0000000..45853cd
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/IDataApi.cs
@@ -0,0 +1,20 @@
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Runtime.Serialization;
+ using System.ServiceModel;
+ using System.Text;
+
+ [ServiceContract]
+ public interface IDataApi {
+ [OperationContract]
+ int? GetAge();
+
+ [OperationContract]
+ string GetName();
+
+ [OperationContract]
+ string[] GetFavoriteSites();
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs b/src/OAuth/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs
new file mode 100644
index 0000000..917a252
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs
@@ -0,0 +1,65 @@
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.IdentityModel.Policy;
+ using System.Linq;
+ using System.Security.Principal;
+ using System.ServiceModel;
+ using System.ServiceModel.Channels;
+ using System.ServiceModel.Security;
+ using DotNetOpenAuth;
+ using DotNetOpenAuth.OAuth;
+
+ /// <summary>
+ /// A WCF extension to authenticate incoming messages using OAuth.
+ /// </summary>
+ public class OAuthAuthorizationManager : ServiceAuthorizationManager {
+ public OAuthAuthorizationManager() {
+ }
+
+ protected override bool CheckAccessCore(OperationContext operationContext) {
+ if (!base.CheckAccessCore(operationContext)) {
+ return false;
+ }
+
+ HttpRequestMessageProperty httpDetails = operationContext.RequestContext.RequestMessage.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
+ Uri requestUri = operationContext.RequestContext.RequestMessage.Properties.Via;
+ ServiceProvider sp = Constants.CreateServiceProvider();
+ try {
+ var auth = sp.ReadProtectedResourceAuthorization(httpDetails, requestUri);
+ if (auth != null) {
+ var accessToken = Global.DataContext.OAuthTokens.Single(token => token.Token == auth.AccessToken);
+
+ var principal = sp.CreatePrincipal(auth);
+ var policy = new OAuthPrincipalAuthorizationPolicy(principal);
+ var policies = new List<IAuthorizationPolicy> {
+ policy,
+ };
+
+ var securityContext = new ServiceSecurityContext(policies.AsReadOnly());
+ if (operationContext.IncomingMessageProperties.Security != null) {
+ operationContext.IncomingMessageProperties.Security.ServiceSecurityContext = securityContext;
+ } else {
+ operationContext.IncomingMessageProperties.Security = new SecurityMessageProperty {
+ ServiceSecurityContext = securityContext,
+ };
+ }
+
+ securityContext.AuthorizationContext.Properties["Identities"] = new List<IIdentity> {
+ principal.Identity,
+ };
+
+ // Only allow this method call if the access token scope permits it.
+ string[] scopes = accessToken.Scope.Split('|');
+ if (scopes.Contains(operationContext.IncomingMessageHeaders.Action)) {
+ return true;
+ }
+ }
+ } catch (ProtocolException ex) {
+ Global.Logger.Error("Error processing OAuth messages.", ex);
+ }
+
+ return false;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/OAuthConsumer.cs b/src/OAuth/OAuthServiceProvider/Code/OAuthConsumer.cs
new file mode 100644
index 0000000..341afd4
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/OAuthConsumer.cs
@@ -0,0 +1,43 @@
+//-----------------------------------------------------------------------
+// <copyright file="OAuthConsumer.cs" company="Outercurve Foundation">
+// Copyright (c) Outercurve Foundation. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+
+ public partial class OAuthConsumer : IConsumerDescription {
+ #region IConsumerDescription Members
+
+ string IConsumerDescription.Key {
+ get { return this.ConsumerKey; }
+ }
+
+ string IConsumerDescription.Secret {
+ get { return this.ConsumerSecret; }
+ }
+
+ System.Security.Cryptography.X509Certificates.X509Certificate2 IConsumerDescription.Certificate {
+ get { return null; }
+ }
+
+ Uri IConsumerDescription.Callback {
+ get { return string.IsNullOrEmpty(this.Callback) ? null : new Uri(this.Callback); }
+ }
+
+ DotNetOpenAuth.OAuth.VerificationCodeFormat IConsumerDescription.VerificationCodeFormat {
+ get { return this.VerificationCodeFormat; }
+ }
+
+ int IConsumerDescription.VerificationCodeLength {
+ get { return this.VerificationCodeLength; }
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/OAuthPrincipalAuthorizationPolicy.cs b/src/OAuth/OAuthServiceProvider/Code/OAuthPrincipalAuthorizationPolicy.cs
new file mode 100644
index 0000000..a25f4c5
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/OAuthPrincipalAuthorizationPolicy.cs
@@ -0,0 +1,47 @@
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.IdentityModel.Claims;
+ using System.IdentityModel.Policy;
+ using System.Linq;
+ using System.Web;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+
+ public class OAuthPrincipalAuthorizationPolicy : IAuthorizationPolicy {
+ private readonly Guid uniqueId = Guid.NewGuid();
+ private readonly OAuthPrincipal principal;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="OAuthPrincipalAuthorizationPolicy"/> class.
+ /// </summary>
+ /// <param name="principal">The principal.</param>
+ public OAuthPrincipalAuthorizationPolicy(OAuthPrincipal principal) {
+ this.principal = principal;
+ }
+
+ #region IAuthorizationComponent Members
+
+ /// <summary>
+ /// Gets a unique ID for this instance.
+ /// </summary>
+ public string Id {
+ get { return this.uniqueId.ToString(); }
+ }
+
+ #endregion
+
+ #region IAuthorizationPolicy Members
+
+ public ClaimSet Issuer {
+ get { return ClaimSet.System; }
+ }
+
+ public bool Evaluate(EvaluationContext evaluationContext, ref object state) {
+ evaluationContext.AddClaimSet(this, new DefaultClaimSet(Claim.CreateNameClaim(this.principal.Identity.Name)));
+ evaluationContext.Properties["Principal"] = this.principal;
+ return true;
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/OAuthToken.cs b/src/OAuth/OAuthServiceProvider/Code/OAuthToken.cs
new file mode 100644
index 0000000..709b139
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/OAuthToken.cs
@@ -0,0 +1,95 @@
+//-----------------------------------------------------------------------
+// <copyright file="OAuthToken.cs" company="Outercurve Foundation">
+// Copyright (c) Outercurve Foundation. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+
+ public partial class OAuthToken : IServiceProviderRequestToken, IServiceProviderAccessToken {
+ #region IServiceProviderRequestToken Members
+
+ string IServiceProviderRequestToken.Token {
+ get { return this.Token; }
+ }
+
+ string IServiceProviderRequestToken.ConsumerKey {
+ get { return this.OAuthConsumer.ConsumerKey; }
+ }
+
+ DateTime IServiceProviderRequestToken.CreatedOn {
+ get { return this.IssueDate; }
+ }
+
+ Uri IServiceProviderRequestToken.Callback {
+ get { return string.IsNullOrEmpty(this.RequestTokenCallback) ? null : new Uri(this.RequestTokenCallback); }
+ set { this.RequestTokenCallback = value.AbsoluteUri; }
+ }
+
+ string IServiceProviderRequestToken.VerificationCode {
+ get { return this.RequestTokenVerifier; }
+ set { this.RequestTokenVerifier = value; }
+ }
+
+ Version IServiceProviderRequestToken.ConsumerVersion {
+ get { return new Version(this.ConsumerVersion); }
+ set { this.ConsumerVersion = value.ToString(); }
+ }
+
+ #endregion
+
+ #region IServiceProviderAccessToken Members
+
+ string IServiceProviderAccessToken.Token {
+ get { return this.Token; }
+ }
+
+ DateTime? IServiceProviderAccessToken.ExpirationDate {
+ get { return null; }
+ }
+
+ string IServiceProviderAccessToken.Username {
+ get { return this.User.OpenIDClaimedIdentifier; }
+ }
+
+ string[] IServiceProviderAccessToken.Roles {
+ get { return this.Scope.Split('|'); }
+ }
+
+ #endregion
+
+ /// <summary>
+ /// Called by LinqToSql when the <see cref="IssueDate"/> property is about to change.
+ /// </summary>
+ /// <param name="value">The value.</param>
+ partial void OnIssueDateChanging(DateTime value) {
+ if (value.Kind == DateTimeKind.Unspecified) {
+ throw new ArgumentException("The DateTime.Kind cannot be Unspecified to ensure accurate timestamp checks.");
+ }
+ }
+
+ /// <summary>
+ /// Called by LinqToSql when <see cref="IssueDate"/> has changed.
+ /// </summary>
+ partial void OnIssueDateChanged() {
+ if (this.IssueDate.Kind == DateTimeKind.Local) {
+ this._IssueDate = this.IssueDate.ToUniversalTime();
+ }
+ }
+
+ /// <summary>
+ /// Called by LinqToSql when a token instance is deserialized.
+ /// </summary>
+ partial void OnLoaded() {
+ if (this.IssueDate.Kind == DateTimeKind.Unspecified) {
+ // this detail gets lost in db storage, but must be reaffirmed so that expiratoin checks succeed.
+ this._IssueDate = DateTime.SpecifyKind(this.IssueDate, DateTimeKind.Utc);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/RequestScopedTokenMessage.cs b/src/OAuth/OAuthServiceProvider/Code/RequestScopedTokenMessage.cs
new file mode 100644
index 0000000..984d683
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/RequestScopedTokenMessage.cs
@@ -0,0 +1,25 @@
+namespace OAuthServiceProvider.Code {
+ using System;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuth.Messages;
+
+ /// <summary>
+ /// A custom web app version of the message sent to request an unauthorized token.
+ /// </summary>
+ public class RequestScopedTokenMessage : UnauthorizedTokenRequest {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="RequestScopedTokenMessage"/> class.
+ /// </summary>
+ /// <param name="endpoint">The endpoint that will receive the message.</param>
+ /// <param name="version">The OAuth version.</param>
+ public RequestScopedTokenMessage(MessageReceivingEndpoint endpoint, Version version)
+ : base(endpoint, version) {
+ }
+
+ /// <summary>
+ /// Gets or sets the scope of the access being requested.
+ /// </summary>
+ [MessagePart("scope", IsRequired = true)]
+ public string Scope { get; set; }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/TokenAuthorizationState.cs b/src/OAuth/OAuthServiceProvider/Code/TokenAuthorizationState.cs
new file mode 100644
index 0000000..a9cfa4e
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/TokenAuthorizationState.cs
@@ -0,0 +1,26 @@
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+
+ /// <summary>
+ /// Various states an OAuth token can be in.
+ /// </summary>
+ public enum TokenAuthorizationState : int {
+ /// <summary>
+ /// An unauthorized request token.
+ /// </summary>
+ UnauthorizedRequestToken = 0,
+
+ /// <summary>
+ /// An authorized request token.
+ /// </summary>
+ AuthorizedRequestToken = 1,
+
+ /// <summary>
+ /// An authorized access token.
+ /// </summary>
+ AccessToken = 2,
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/TracePageAppender.cs b/src/OAuth/OAuthServiceProvider/Code/TracePageAppender.cs
new file mode 100644
index 0000000..8f97c89
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/TracePageAppender.cs
@@ -0,0 +1,13 @@
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Web;
+
+ public class TracePageAppender : log4net.Appender.AppenderSkeleton {
+ protected override void Append(log4net.Core.LoggingEvent loggingEvent) {
+ StringWriter sw = new StringWriter(Global.LogMessages);
+ Layout.Format(sw, loggingEvent);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/Utilities.cs b/src/OAuth/OAuthServiceProvider/Code/Utilities.cs
new file mode 100644
index 0000000..a225650
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/Utilities.cs
@@ -0,0 +1,28 @@
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Security.Principal;
+ using System.Web;
+
+ /// <summary>
+ /// Extension methods and other helpful utility methods.
+ /// </summary>
+ public static class Utilities {
+ /// <summary>
+ /// Gets the database entity representing the user identified by a given <see cref="IIdentity"/> instance.
+ /// </summary>
+ /// <param name="identity">The identity of the user.</param>
+ /// <returns>
+ /// The database object for that user; or <c>null</c> if the user could not
+ /// be found or if <paramref name="identity"/> is <c>null</c> or represents an anonymous identity.
+ /// </returns>
+ public static User GetUser(this IIdentity identity) {
+ if (identity == null || !identity.IsAuthenticated) {
+ return null;
+ }
+
+ return Global.DataContext.Users.SingleOrDefault(user => user.OpenIDClaimedIdentifier == identity.Name);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/DataApi.cs b/src/OAuth/OAuthServiceProvider/DataApi.cs
new file mode 100644
index 0000000..9d531e6
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/DataApi.cs
@@ -0,0 +1,34 @@
+namespace OAuthServiceProvider {
+ using System.Linq;
+ using System.ServiceModel;
+ using OAuthServiceProvider.Code;
+
+ /// <summary>
+ /// The WCF service API.
+ /// </summary>
+ /// <remarks>
+ /// Note how there is no code here that is bound to OAuth or any other
+ /// credential/authorization scheme. That's all part of the channel/binding elsewhere.
+ /// And the reference to OperationContext.Current.ServiceSecurityContext.PrimaryIdentity
+ /// is the user being impersonated by the WCF client.
+ /// In the OAuth case, it is the user who authorized the OAuth access token that was used
+ /// to gain access to the service.
+ /// </remarks>
+ public class DataApi : IDataApi {
+ private User User {
+ get { return OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.GetUser(); }
+ }
+
+ public int? GetAge() {
+ return User.Age;
+ }
+
+ public string GetName() {
+ return User.FullName;
+ }
+
+ public string[] GetFavoriteSites() {
+ return User.FavoriteSites.Select(site => site.SiteUrl).ToArray();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/DataApi.svc b/src/OAuth/OAuthServiceProvider/DataApi.svc
new file mode 100644
index 0000000..50e952c
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/DataApi.svc
@@ -0,0 +1 @@
+<%@ ServiceHost Language="C#" Debug="true" Service="OAuthServiceProvider.DataApi" CodeBehind="DataApi.cs" %>
diff --git a/src/OAuth/OAuthServiceProvider/Default.aspx b/src/OAuth/OAuthServiceProvider/Default.aspx
new file mode 100644
index 0000000..3e5d820
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Default.aspx
@@ -0,0 +1,13 @@
+<%@ Page Title="DotNetOpenAuth Service Provider Sample" Language="C#" MasterPageFile="~/MasterPage.master" CodeBehind="~/Default.aspx.cs" Inherits="OAuthServiceProvider._Default" AutoEventWireup="True" %>
+
+<%@ Import Namespace="System.IO" %>
+<%@ Import Namespace="System.Data.SqlClient" %>
+
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+ <asp:Button ID="createDatabaseButton" runat="server" Text="(Re)create Database" OnClick="createDatabaseButton_Click" />
+ <asp:Label runat="server" ID="databaseStatus" EnableViewState="false" Text="Database recreated!"
+ Visible="false" />
+ <p>Note that to be useful, you really need to either modify the database to add an
+ account with data that will be accessed by this sample, or modify this very page
+ to inject that data into the database. </p>
+</asp:Content>
diff --git a/src/OAuth/OAuthServiceProvider/Default.aspx.cs b/src/OAuth/OAuthServiceProvider/Default.aspx.cs
new file mode 100644
index 0000000..653046a
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Default.aspx.cs
@@ -0,0 +1,49 @@
+namespace OAuthServiceProvider {
+ using System;
+ using System.Collections.Generic;
+ using System.Configuration;
+ using System.IO;
+ using System.Linq;
+ using System.Web;
+ using OAuthServiceProvider.Code;
+
+ public partial class _Default : System.Web.UI.Page {
+ protected void createDatabaseButton_Click(object sender, EventArgs e) {
+ string databasePath = Path.Combine(Server.MapPath(Request.ApplicationPath), "App_Data");
+ if (!Directory.Exists(databasePath)) {
+ Directory.CreateDirectory(databasePath);
+ }
+ string connectionString = ConfigurationManager.ConnectionStrings["DatabaseConnectionString"].ConnectionString.Replace("|DataDirectory|", databasePath);
+ var dc = new DataClassesDataContext(connectionString);
+ if (dc.DatabaseExists()) {
+ dc.DeleteDatabase();
+ }
+ try {
+ dc.CreateDatabase();
+
+ // Fill with sample data.
+ dc.OAuthConsumers.InsertOnSubmit(new OAuthConsumer {
+ ConsumerKey = "sampleconsumer",
+ ConsumerSecret = "samplesecret",
+ });
+ dc.Users.InsertOnSubmit(new User {
+ OpenIDFriendlyIdentifier = "=arnott",
+ OpenIDClaimedIdentifier = "=!9B72.7DD1.50A9.5CCD",
+ Age = 27,
+ FullName = "Andrew Arnott",
+ FavoriteSites = new System.Data.Linq.EntitySet<FavoriteSite> {
+ new FavoriteSite { SiteUrl = "http://www.microsoft.com" },
+ new FavoriteSite { SiteUrl = "http://www.google.com" },
+ },
+ });
+
+ dc.SubmitChanges();
+ this.databaseStatus.Visible = true;
+ } catch (System.Data.SqlClient.SqlException ex) {
+ foreach (System.Data.SqlClient.SqlError error in ex.Errors) {
+ Response.Write(error.Message);
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Default.aspx.designer.cs b/src/OAuth/OAuthServiceProvider/Default.aspx.designer.cs
new file mode 100644
index 0000000..afa79c0
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Default.aspx.designer.cs
@@ -0,0 +1,33 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthServiceProvider {
+
+
+ public partial class _Default {
+
+ /// <summary>
+ /// createDatabaseButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button createDatabaseButton;
+
+ /// <summary>
+ /// databaseStatus control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label databaseStatus;
+ }
+}
diff --git a/src/OAuth/OAuthServiceProvider/Global.asax b/src/OAuth/OAuthServiceProvider/Global.asax
new file mode 100644
index 0000000..3007bd3
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Global.asax
@@ -0,0 +1 @@
+<%@ Application Inherits="OAuthServiceProvider.Code.Global" CodeBehind="Code\Global.cs" %> \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Login.aspx b/src/OAuth/OAuthServiceProvider/Login.aspx
new file mode 100644
index 0000000..4498ee0
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Login.aspx
@@ -0,0 +1,7 @@
+<%@ Page Title="Login" Language="C#" MasterPageFile="~/MasterPage.master" %>
+
+<%@ Register Assembly="DotNetOpenAuth.OpenId.RelyingParty.UI" Namespace="DotNetOpenAuth.OpenId.RelyingParty" TagPrefix="rp" %>
+
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+ <rp:OpenIdLogin runat="server" TabIndex='1' />
+</asp:Content>
diff --git a/src/OAuth/OAuthServiceProvider/MasterPage.master b/src/OAuth/OAuthServiceProvider/MasterPage.master
new file mode 100644
index 0000000..136dfc9
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/MasterPage.master
@@ -0,0 +1,23 @@
+<%@ Master Language="C#" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<script runat="server">
+
+</script>
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title>DotNetOpenAuth Service Provider sample</title>
+ <asp:ContentPlaceHolder ID="head" runat="server"/>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <h1>DotNetOpenAuth Service Provider sample</h1>
+ <div>
+ <asp:ContentPlaceHolder ID="Body" runat="server">
+ </asp:ContentPlaceHolder>
+ </div>
+ </form>
+</body>
+</html>
diff --git a/src/OAuth/OAuthServiceProvider/Members/Authorize.aspx b/src/OAuth/OAuthServiceProvider/Members/Authorize.aspx
new file mode 100644
index 0000000..b3e2c6a
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Members/Authorize.aspx
@@ -0,0 +1,58 @@
+<%@ Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" Inherits="OAuthServiceProvider.Authorize" Codebehind="Authorize.aspx.cs" %>
+
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+ <asp:MultiView runat="server" ActiveViewIndex="0" ID="multiView">
+ <asp:View runat="server">
+ <div style="background-color: Yellow">
+ <b>Warning</b>: Never give your login credentials to another web site or application.
+ </div>
+ <asp:HiddenField runat="server" ID="OAuthAuthorizationSecToken" EnableViewState="false" />
+ <p>The client web site or application <asp:Label ID="consumerLabel" Font-Bold="true"
+ runat="server" Text="[consumer]" /> wants access to your <asp:Label ID="desiredAccessLabel"
+ Font-Bold="true" runat="server" Text="[protected resource]" />. </p>
+ <p>Do you want to allow this? </p>
+ <div style="display: none" id="responseButtonsDiv">
+ <asp:Button ID="allowAccessButton" runat="server" Text="Yes" OnClick="allowAccessButton_Click" />
+ <asp:Button ID="denyAccessButton" runat="server" Text="No" OnClick="denyAccessButton_Click" />
+ </div>
+ <div id="javascriptDisabled">
+ <b>Javascript appears to be disabled in your browser. </b>This page requires Javascript
+ to be enabled to better protect your security.
+ </div>
+ <p>If you grant access now, you can revoke it at any time by returning to this page.
+ </p>
+ <asp:Panel runat="server" BackColor="Red" ForeColor="White" Font-Bold="true" Visible="false" ID="OAuth10ConsumerWarning">
+ This website is registered with service_PROVIDER_DOMAIN_NAME to make authorization requests, but has not been configured to send requests securely. If you grant access but you did not initiate this request at consumer_DOMAIN_NAME, it may be possible for other users of consumer_DOMAIN_NAME to access your data. We recommend you deny access unless you are certain that you initiated this request directly with consumer_DOMAIN_NAME.
+ </asp:Panel>
+ <script language="javascript" type="text/javascript">
+ //<![CDATA[
+ // we use HTML to hide the action buttons and Javascript to show them
+ // to protect against click-jacking in an iframe whose javascript is disabled.
+ document.getElementById('responseButtonsDiv').style.display = 'block';
+ document.getElementById('javascriptDisabled').style.display = 'none';
+
+ // Frame busting code (to protect us from being hosted in an iframe).
+ // This protects us from click-jacking.
+ if (document.location !== window.top.location) {
+ window.top.location = document.location;
+ }
+ //]]>
+ </script>
+ </asp:View>
+ <asp:View runat="server">
+ <p>Authorization has been granted.</p>
+ <asp:MultiView runat="server" ID="verifierMultiView" ActiveViewIndex="0">
+ <asp:View runat="server">
+ <p>You must enter this verification code at the Consumer: <asp:Label runat="server"
+ ID="verificationCodeLabel" /> </p>
+ </asp:View>
+ <asp:View ID="View1" runat="server">
+ <p>You may now close this window and return to the Consumer. </p>
+ </asp:View>
+ </asp:MultiView>
+ </asp:View>
+ <asp:View runat="server">
+ <p>Authorization has been denied. You're free to do whatever now. </p>
+ </asp:View>
+ </asp:MultiView>
+</asp:Content>
diff --git a/src/OAuth/OAuthServiceProvider/Members/Authorize.aspx.cs b/src/OAuth/OAuthServiceProvider/Members/Authorize.aspx.cs
new file mode 100644
index 0000000..faa2147
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Members/Authorize.aspx.cs
@@ -0,0 +1,80 @@
+namespace OAuthServiceProvider {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Security.Cryptography;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using DotNetOpenAuth;
+ using DotNetOpenAuth.OAuth;
+ using DotNetOpenAuth.OAuth.Messages;
+ using OAuthServiceProvider.Code;
+
+ /// <summary>
+ /// Conducts the user through a Consumer authorization process.
+ /// </summary>
+ public partial class Authorize : System.Web.UI.Page {
+ private static readonly RandomNumberGenerator CryptoRandomDataGenerator = new RNGCryptoServiceProvider();
+
+ private string AuthorizationSecret {
+ get { return Session["OAuthAuthorizationSecret"] as string; }
+ set { Session["OAuthAuthorizationSecret"] = value; }
+ }
+
+ protected void Page_Load(object sender, EventArgs e) {
+ if (!IsPostBack) {
+ if (Global.PendingOAuthAuthorization == null) {
+ Response.Redirect("~/Members/AuthorizedConsumers.aspx");
+ } else {
+ ITokenContainingMessage pendingToken = Global.PendingOAuthAuthorization;
+ var token = Global.DataContext.OAuthTokens.Single(t => t.Token == pendingToken.Token);
+ this.desiredAccessLabel.Text = token.Scope;
+ this.consumerLabel.Text = Global.TokenManager.GetConsumerForToken(token.Token).ConsumerKey;
+
+ // Generate an unpredictable secret that goes to the user agent and must come back
+ // with authorization to guarantee the user interacted with this page rather than
+ // being scripted by an evil Consumer.
+ byte[] randomData = new byte[8];
+ CryptoRandomDataGenerator.GetBytes(randomData);
+ this.AuthorizationSecret = Convert.ToBase64String(randomData);
+ this.OAuthAuthorizationSecToken.Value = this.AuthorizationSecret;
+
+ this.OAuth10ConsumerWarning.Visible = Global.PendingOAuthAuthorization.IsUnsafeRequest;
+ }
+ }
+ }
+
+ protected void allowAccessButton_Click(object sender, EventArgs e) {
+ if (this.AuthorizationSecret != this.OAuthAuthorizationSecToken.Value) {
+ throw new ArgumentException(); // probably someone trying to hack in.
+ }
+ this.AuthorizationSecret = null; // clear one time use secret
+ var pending = Global.PendingOAuthAuthorization;
+ Global.AuthorizePendingRequestToken();
+ this.multiView.ActiveViewIndex = 1;
+
+ ServiceProvider sp = new ServiceProvider(Constants.SelfDescription, Global.TokenManager);
+ var response = sp.PrepareAuthorizationResponse(pending);
+ if (response != null) {
+ sp.Channel.Send(response);
+ } else {
+ if (pending.IsUnsafeRequest) {
+ this.verifierMultiView.ActiveViewIndex = 1;
+ } else {
+ string verifier = ServiceProvider.CreateVerificationCode(VerificationCodeFormat.AlphaNumericNoLookAlikes, 10);
+ this.verificationCodeLabel.Text = verifier;
+ ITokenContainingMessage requestTokenMessage = pending;
+ var requestToken = Global.TokenManager.GetRequestToken(requestTokenMessage.Token);
+ requestToken.VerificationCode = verifier;
+ Global.TokenManager.UpdateToken(requestToken);
+ }
+ }
+ }
+
+ protected void denyAccessButton_Click(object sender, EventArgs e) {
+ // erase the request token.
+ this.multiView.ActiveViewIndex = 2;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Members/Authorize.aspx.designer.cs b/src/OAuth/OAuthServiceProvider/Members/Authorize.aspx.designer.cs
new file mode 100644
index 0000000..8aaf94d
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Members/Authorize.aspx.designer.cs
@@ -0,0 +1,105 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthServiceProvider {
+
+
+ public partial class Authorize {
+
+ /// <summary>
+ /// multiView control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.MultiView multiView;
+
+ /// <summary>
+ /// OAuthAuthorizationSecToken control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.HiddenField OAuthAuthorizationSecToken;
+
+ /// <summary>
+ /// consumerLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label consumerLabel;
+
+ /// <summary>
+ /// desiredAccessLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label desiredAccessLabel;
+
+ /// <summary>
+ /// allowAccessButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button allowAccessButton;
+
+ /// <summary>
+ /// denyAccessButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button denyAccessButton;
+
+ /// <summary>
+ /// OAuth10ConsumerWarning control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Panel OAuth10ConsumerWarning;
+
+ /// <summary>
+ /// verifierMultiView control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.MultiView verifierMultiView;
+
+ /// <summary>
+ /// verificationCodeLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label verificationCodeLabel;
+
+ /// <summary>
+ /// View1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View View1;
+ }
+}
diff --git a/src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx b/src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx
new file mode 100644
index 0000000..3506eb9
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx
@@ -0,0 +1,6 @@
+<%@ Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" Inherits="OAuthServiceProvider.AuthorizedConsumers" Codebehind="AuthorizedConsumers.aspx.cs" %>
+
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+ <h2>The following consumers have access to your data</h2>
+ <p>TODO</p>
+</asp:Content>
diff --git a/src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx.cs b/src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx.cs
new file mode 100644
index 0000000..fe647a8
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx.cs
@@ -0,0 +1,17 @@
+namespace OAuthServiceProvider {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+
+ /// <summary>
+ /// Lists the consumers that have active request or access tokens
+ /// and provides a mechanism for the user to revoke permissions.
+ /// </summary>
+ public partial class AuthorizedConsumers : System.Web.UI.Page {
+ protected void Page_Load(object sender, EventArgs e) {
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx.designer.cs b/src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx.designer.cs
new file mode 100644
index 0000000..419c114
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx.designer.cs
@@ -0,0 +1,15 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthServiceProvider {
+
+
+ public partial class AuthorizedConsumers {
+ }
+}
diff --git a/src/OAuth/OAuthServiceProvider/Members/Logoff.aspx b/src/OAuth/OAuthServiceProvider/Members/Logoff.aspx
new file mode 100644
index 0000000..afa9dd9
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Members/Logoff.aspx
@@ -0,0 +1,8 @@
+<%@ Page Title="Log off" Language="C#" MasterPageFile="~/MasterPage.master" %>
+
+<script runat="server">
+ private void Page_Load(object sender, EventArgs e) {
+ FormsAuthentication.SignOut();
+ Response.Redirect("~/");
+ }
+</script>
diff --git a/src/OAuth/OAuthServiceProvider/Members/Web.config b/src/OAuth/OAuthServiceProvider/Members/Web.config
new file mode 100644
index 0000000..50fab27
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Members/Web.config
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<configuration>
+ <system.web>
+ <authorization>
+ <deny users="?"/>
+ </authorization>
+ </system.web>
+</configuration>
diff --git a/src/OAuth/OAuthServiceProvider/OAuth.ashx b/src/OAuth/OAuthServiceProvider/OAuth.ashx
new file mode 100644
index 0000000..8a74926
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/OAuth.ashx
@@ -0,0 +1,42 @@
+<%@ WebHandler Language="C#" Class="OAuth" %>
+
+using System;
+using System.Linq;
+using System.Web;
+using System.Web.SessionState;
+using DotNetOpenAuth.OAuth;
+using DotNetOpenAuth.OAuth.ChannelElements;
+using DotNetOpenAuth.OAuth.Messages;
+using DotNetOpenAuth.Messaging;
+using OAuthServiceProvider.Code;
+
+public class OAuth : IHttpHandler, IRequiresSessionState {
+ ServiceProvider sp;
+
+ public OAuth() {
+ sp = new ServiceProvider(Constants.SelfDescription, Global.TokenManager, new CustomOAuthMessageFactory(Global.TokenManager));
+ }
+
+ public void ProcessRequest(HttpContext context) {
+ IProtocolMessage request = sp.ReadRequest();
+ RequestScopedTokenMessage requestToken;
+ UserAuthorizationRequest requestAuth;
+ AuthorizedTokenRequest requestAccessToken;
+ if ((requestToken = request as RequestScopedTokenMessage) != null) {
+ var response = sp.PrepareUnauthorizedTokenMessage(requestToken);
+ sp.Channel.Send(response);
+ } else if ((requestAuth = request as UserAuthorizationRequest) != null) {
+ Global.PendingOAuthAuthorization = requestAuth;
+ HttpContext.Current.Response.Redirect("~/Members/Authorize.aspx");
+ } else if ((requestAccessToken = request as AuthorizedTokenRequest) != null) {
+ var response = sp.PrepareAccessTokenMessage(requestAccessToken);
+ sp.Channel.Send(response);
+ } else {
+ throw new InvalidOperationException();
+ }
+ }
+
+ public bool IsReusable {
+ get { return true; }
+ }
+}
diff --git a/src/OAuth/OAuthServiceProvider/OAuthServiceProvider.csproj b/src/OAuth/OAuthServiceProvider/OAuthServiceProvider.csproj
new file mode 100644
index 0000000..f8c1eb5
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/OAuthServiceProvider.csproj
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))\EnlistmentInfo.props" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))' != '' " />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>
+ </ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{CAA2408C-6918-4902-A512-58BCD62216C3}</ProjectGuid>
+ <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>OAuthServiceProvider</RootNamespace>
+ <AssemblyName>OAuthServiceProvider</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <UseIISExpress>false</UseIISExpress>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="log4net">
+ <HintPath>..\..\lib\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Data.Linq" />
+ <Reference Include="System.IdentityModel" />
+ <Reference Include="System.ServiceModel" />
+ <Reference Include="System.Web.Extensions" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Web" />
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Configuration" />
+ <Reference Include="System.Web.Services" />
+ <Reference Include="System.EnterpriseServices" />
+ <Reference Include="System.Web.Mobile" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="DataApi.svc" />
+ <Content Include="Default.aspx" />
+ <Content Include="favicon.ico" />
+ <Content Include="Global.asax" />
+ <Content Include="Login.aspx" />
+ <Content Include="Members\Authorize.aspx" />
+ <Content Include="Members\AuthorizedConsumers.aspx" />
+ <Content Include="Members\Logoff.aspx" />
+ <Content Include="TracePage.aspx" />
+ <Content Include="Web.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Code\DatabaseNonceStore.cs" />
+ <Compile Include="Default.aspx.designer.cs">
+ <DependentUpon>Default.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="DataApi.cs">
+ <DependentUpon>DataApi.svc</DependentUpon>
+ </Compile>
+ <Compile Include="Members\Authorize.aspx.designer.cs">
+ <DependentUpon>Authorize.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Members\AuthorizedConsumers.aspx.designer.cs">
+ <DependentUpon>AuthorizedConsumers.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Code\Constants.cs" />
+ <Compile Include="Code\CustomOAuthTypeProvider.cs" />
+ <Compile Include="Code\DatabaseTokenManager.cs" />
+ <Compile Include="Code\Global.cs" />
+ <Compile Include="Code\IDataApi.cs" />
+ <Compile Include="Code\OAuthAuthorizationManager.cs" />
+ <Compile Include="Code\OAuthConsumer.cs" />
+ <Compile Include="Code\OAuthPrincipalAuthorizationPolicy.cs" />
+ <Compile Include="Code\OAuthToken.cs" />
+ <Compile Include="Code\RequestScopedTokenMessage.cs" />
+ <Compile Include="Code\TokenAuthorizationState.cs" />
+ <Compile Include="Code\TracePageAppender.cs" />
+ <Compile Include="Code\Utilities.cs" />
+ <Compile Include="Code\DataClasses.designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>DataClasses.dbml</DependentUpon>
+ </Compile>
+ <Compile Include="Default.aspx.cs">
+ <DependentUpon>Default.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="Members\Authorize.aspx.cs">
+ <DependentUpon>Authorize.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="Members\AuthorizedConsumers.aspx.cs">
+ <DependentUpon>AuthorizedConsumers.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="TracePage.aspx.cs">
+ <DependentUpon>TracePage.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="TracePage.aspx.designer.cs">
+ <DependentUpon>TracePage.aspx</DependentUpon>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="App_Data\" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="OAuth.ashx" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="MasterPage.master" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Code\DataClasses.dbml">
+ <Generator>MSLinqToSQLGenerator</Generator>
+ <LastGenOutput>DataClasses.designer.cs</LastGenOutput>
+ <SubType>Designer</SubType>
+ </None>
+ <Content Include="Members\Web.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Code\DataClasses.dbml.layout">
+ <DependentUpon>DataClasses.dbml</DependentUpon>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{3259AA49-8AA1-44D3-9025-A0B520596A8C}" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\src\DotNetOpenAuth.Core\DotNetOpenAuth.Core.csproj">
+ <Project>{60426312-6AE5-4835-8667-37EDEA670222}</Project>
+ <Name>DotNetOpenAuth.Core</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\src\DotNetOpenAuth.OAuth.Common\DotNetOpenAuth.OAuth.Common.csproj">
+ <Project>{115217C5-22CD-415C-A292-0DD0238CDD89}</Project>
+ <Name>DotNetOpenAuth.OAuth.Common</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\src\DotNetOpenAuth.OAuth.ServiceProvider\DotNetOpenAuth.OAuth.ServiceProvider.csproj">
+ <Project>{FED1923A-6D70-49B5-A37A-FB744FEC1C86}</Project>
+ <Name>DotNetOpenAuth.OAuth.ServiceProvider</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\src\DotNetOpenAuth.OAuth\DotNetOpenAuth.OAuth.csproj">
+ <Project>{A288FCC8-6FCF-46DA-A45E-5F9281556361}</Project>
+ <Name>DotNetOpenAuth.OAuth</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\src\DotNetOpenAuth.OpenId.RelyingParty.UI\DotNetOpenAuth.OpenId.RelyingParty.UI.csproj">
+ <Project>{1ED8D424-F8AB-4050-ACEB-F27F4F909484}</Project>
+ <Name>DotNetOpenAuth.OpenId.RelyingParty.UI</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\src\DotNetOpenAuth.OpenId.RelyingParty\DotNetOpenAuth.OpenId.RelyingParty.csproj">
+ <Project>{F458AB60-BA1C-43D9-8CEF-EC01B50BE87B}</Project>
+ <Name>DotNetOpenAuth.OpenId.RelyingParty</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\src\DotNetOpenAuth.OpenId\DotNetOpenAuth.OpenId.csproj">
+ <Project>{3896A32A-E876-4C23-B9B8-78E17D134CD3}</Project>
+ <Name>DotNetOpenAuth.OpenId</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
+ <ProjectExtensions>
+ <VisualStudio>
+ <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
+ <WebProjectProperties>
+ <UseIIS>False</UseIIS>
+ <AutoAssignPort>False</AutoAssignPort>
+ <DevelopmentServerPort>65169</DevelopmentServerPort>
+ <DevelopmentServerVPath>/</DevelopmentServerVPath>
+ <IISUrl>
+ </IISUrl>
+ <NTLMAuthentication>False</NTLMAuthentication>
+ <UseCustomServer>False</UseCustomServer>
+ <CustomServerUrl>
+ </CustomServerUrl>
+ <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
+ </WebProjectProperties>
+ </FlavorProperties>
+ </VisualStudio>
+ </ProjectExtensions>
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))\EnlistmentInfo.targets" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))' != '' " />
+</Project> \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Properties/AssemblyInfo.cs b/src/OAuth/OAuthServiceProvider/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..09d299c
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("OAuthServiceProvider")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("OAuthServiceProvider")]
+[assembly: AssemblyCopyright("Copyright © 2010")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("B6206451-6557-4568-8D25-84AF93EC8B7B")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/OAuth/OAuthServiceProvider/Settings.StyleCop b/src/OAuth/OAuthServiceProvider/Settings.StyleCop
new file mode 100644
index 0000000..7f55ce6
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Settings.StyleCop
@@ -0,0 +1 @@
+<StyleCopSettings Version="4.3" /> \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/TracePage.aspx b/src/OAuth/OAuthServiceProvider/TracePage.aspx
new file mode 100644
index 0000000..e83adc3
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/TracePage.aspx
@@ -0,0 +1,18 @@
+<%@ Page Language="C#" AutoEventWireup="true" Inherits="OAuthServiceProvider.TracePage" Codebehind="TracePage.aspx.cs" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title></title>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <p align="right">
+ <asp:Button runat="server" Text="Clear log" ID="clearLogButton" OnClick="clearLogButton_Click" />
+ </p>
+ <pre>
+ <asp:PlaceHolder runat="server" ID="placeHolder1" />
+ </pre>
+ </form>
+</body>
+</html>
diff --git a/src/OAuth/OAuthServiceProvider/TracePage.aspx.cs b/src/OAuth/OAuthServiceProvider/TracePage.aspx.cs
new file mode 100644
index 0000000..fcfade5
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/TracePage.aspx.cs
@@ -0,0 +1,24 @@
+namespace OAuthServiceProvider {
+ using System;
+ using System.Collections.Generic;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using OAuthServiceProvider.Code;
+
+ /// <summary>
+ /// A page to display recent log messages.
+ /// </summary>
+ public partial class TracePage : System.Web.UI.Page {
+ protected void Page_Load(object sender, EventArgs e) {
+ this.placeHolder1.Controls.Add(new Label { Text = HttpUtility.HtmlEncode(Global.LogMessages.ToString()) });
+ }
+
+ protected void clearLogButton_Click(object sender, EventArgs e) {
+ Global.LogMessages.Length = 0;
+
+ // clear the page immediately, and allow for F5 without a Postback warning.
+ Response.Redirect(Request.Url.AbsoluteUri);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/TracePage.aspx.designer.cs b/src/OAuth/OAuthServiceProvider/TracePage.aspx.designer.cs
new file mode 100644
index 0000000..3cd04be
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/TracePage.aspx.designer.cs
@@ -0,0 +1,42 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthServiceProvider {
+
+
+ public partial class TracePage {
+
+ /// <summary>
+ /// form1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlForm form1;
+
+ /// <summary>
+ /// clearLogButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button clearLogButton;
+
+ /// <summary>
+ /// placeHolder1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.PlaceHolder placeHolder1;
+ }
+}
diff --git a/src/OAuth/OAuthServiceProvider/Web.config b/src/OAuth/OAuthServiceProvider/Web.config
new file mode 100644
index 0000000..60a4d86
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Web.config
@@ -0,0 +1,180 @@
+<?xml version="1.0"?>
+<configuration>
+ <configSections>
+ <section name="uri" type="System.Configuration.UriSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
+ <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler" requirePermission="false"/>
+ <sectionGroup name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection, DotNetOpenAuth.Core">
+ <section name="oauth" type="DotNetOpenAuth.Configuration.OAuthElement, DotNetOpenAuth.OAuth" requirePermission="false" allowLocation="true" />
+ <section name="messaging" type="DotNetOpenAuth.Configuration.MessagingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true" />
+ <section name="reporting" type="DotNetOpenAuth.Configuration.ReportingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true" />
+ </sectionGroup>
+ <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+ <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+ <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
+ <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+ <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
+ <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
+ <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
+ <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
+ </sectionGroup>
+ </sectionGroup>
+ </sectionGroup>
+ </configSections>
+
+ <!-- The uri section is necessary to turn on .NET 3.5 support for IDN (international domain names),
+ which is necessary for OpenID urls with unicode characters in the domain/host name.
+ It is also required to put the Uri class into RFC 3986 escaping mode, which OpenID and OAuth require. -->
+ <uri>
+ <idn enabled="All"/>
+ <iriParsing enabled="true"/>
+ </uri>
+
+ <system.net>
+ <defaultProxy enabled="true" />
+ <settings>
+ <!-- This setting causes .NET to check certificate revocation lists (CRL)
+ before trusting HTTPS certificates. But this setting tends to not
+ be allowed in shared hosting environments. -->
+ <!--<servicePointManager checkCertificateRevocationList="true"/>-->
+ </settings>
+ </system.net>
+
+ <!-- this is an optional configuration section where aspects of dotnetopenauth can be customized -->
+ <dotNetOpenAuth>
+ <!-- Allow DotNetOpenAuth to publish usage statistics to library authors to improve the library. -->
+ <reporting enabled="true" />
+ <messaging>
+ <untrustedWebRequest>
+ <whitelistHosts>
+ <add name="localhost"/>
+ </whitelistHosts>
+ </untrustedWebRequest>
+ </messaging>
+ </dotNetOpenAuth>
+
+ <appSettings/>
+ <connectionStrings>
+ <add name="DatabaseConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True"
+ providerName="System.Data.SqlClient" />
+ </connectionStrings>
+
+ <system.web>
+ <!--
+ Set compilation debug="true" to insert debugging
+ symbols into the compiled page. Because this
+ affects performance, set this value to true only
+ during development.
+ -->
+ <compilation debug="true">
+ <assemblies>
+ <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
+ <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ <add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
+ <add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
+ <add assembly="System.Data.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
+ <remove assembly="DotNetOpenAuth.Contracts"/>
+ </assemblies>
+ </compilation>
+ <authentication mode="Forms">
+ <forms name="oauthSP" />
+ </authentication>
+ <pages>
+ <controls>
+ <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ </controls>
+ </pages>
+ <httpHandlers>
+ <remove verb="*" path="*.asmx"/>
+ <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
+ </httpHandlers>
+ <httpModules>
+ <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ </httpModules>
+ </system.web>
+ <system.codedom>
+ <compilers>
+ <compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <providerOption name="CompilerVersion" value="v3.5"/>
+ <providerOption name="WarnAsError" value="false"/>
+ </compiler>
+ <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" warningLevel="4" type="Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <providerOption name="CompilerVersion" value="v3.5"/>
+ <providerOption name="OptionInfer" value="true"/>
+ <providerOption name="WarnAsError" value="false"/>
+ </compiler>
+ </compilers>
+ </system.codedom>
+ <!--
+ The system.webServer section is required for running ASP.NET AJAX under Internet
+ Information Services 7.0. It is not necessary for previous version of IIS.
+ -->
+ <system.webServer>
+ <validation validateIntegratedModeConfiguration="false"/>
+ <modules>
+ <remove name="ScriptModule"/>
+ <add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ </modules>
+ <handlers>
+ <remove name="WebServiceHandlerFactory-Integrated"/>
+ <remove name="ScriptHandlerFactory"/>
+ <remove name="ScriptHandlerFactoryAppServices"/>
+ <remove name="ScriptResource"/>
+ <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ </handlers>
+ </system.webServer>
+ <runtime>
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/>
+ <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/>
+ <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+ <log4net>
+ <appender name="TracePageAppender" type="OAuthServiceProvider.Code.TracePageAppender, OAuthServiceProvider">
+ <layout type="log4net.Layout.PatternLayout">
+ <conversionPattern value="%date (GMT%date{%z}) [%thread] %-5level %logger - %message%newline"/>
+ </layout>
+ </appender>
+ <!-- Setup the root category, add the appenders and set the default level -->
+ <root>
+ <level value="INFO"/>
+ <!--<appender-ref ref="RollingFileAppender" />-->
+ <appender-ref ref="TracePageAppender"/>
+ </root>
+ <!-- Specify the level for some specific categories -->
+ <logger name="DotNetOpenAuth">
+ <level value="ALL"/>
+ </logger>
+ </log4net>
+ <system.serviceModel>
+ <behaviors>
+ <serviceBehaviors>
+ <behavior name="DataApiBehavior">
+ <serviceMetadata httpGetEnabled="true"/>
+ <serviceDebug includeExceptionDetailInFaults="true"/>
+ <serviceAuthorization serviceAuthorizationManagerType="OAuthServiceProvider.Code.OAuthAuthorizationManager, OAuthServiceProvider" principalPermissionMode="Custom"/>
+ </behavior>
+ </serviceBehaviors>
+ </behaviors>
+ <services>
+ <service behaviorConfiguration="DataApiBehavior" name="OAuthServiceProvider.DataApi">
+ <endpoint address="" binding="wsHttpBinding" contract="OAuthServiceProvider.Code.IDataApi">
+ <identity>
+ <dns value="localhost"/>
+ </identity>
+ </endpoint>
+ <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
+ </service>
+ </services>
+ </system.serviceModel>
+</configuration>
diff --git a/src/OAuth/OAuthServiceProvider/favicon.ico b/src/OAuth/OAuthServiceProvider/favicon.ico
new file mode 100644
index 0000000..e227dbe
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/favicon.ico
Binary files differ