From abd9ebbfb6eb4a2874d58402308f26c392763645 Mon Sep 17 00:00:00 2001 From: David Long Date: Fri, 8 Aug 2014 16:04:07 -0700 Subject: [PATCH 01/28] yolo-ing in a gitignore from the gods: https://raw.githubusercontent.com/github/gitignore/master/VisualStudio.gitignore --- src/.gitignore | 182 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 src/.gitignore diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..16b413c --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,182 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ + +# Roslyn cache directories +*.ide/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +#NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding addin-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# If using the old MSBuild-Integrated Package Restore, uncomment this: +#!**/packages/repositories.config + +# Windows Azure Build Output +csx/ +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ \ No newline at end of file From 5e074c782007bd107dff54c454c6e3bc34c17c73 Mon Sep 17 00:00:00 2001 From: David Long Date: Fri, 8 Aug 2014 16:10:44 -0700 Subject: [PATCH 02/28] roughing out the solution structure - this commit is useless other than to show distinct steps that I'm about to make --- src/notesy/Class1.cs | 12 ++++++ src/notesy/Notesy.Core.csproj | 53 +++++++++++++++++++++++++++ src/notesy/Properties/AssemblyInfo.cs | 36 ++++++++++++++++++ src/notesy/notesy.sln | 20 ++++++++++ 4 files changed, 121 insertions(+) create mode 100644 src/notesy/Class1.cs create mode 100644 src/notesy/Notesy.Core.csproj create mode 100644 src/notesy/Properties/AssemblyInfo.cs create mode 100644 src/notesy/notesy.sln diff --git a/src/notesy/Class1.cs b/src/notesy/Class1.cs new file mode 100644 index 0000000..6b7e145 --- /dev/null +++ b/src/notesy/Class1.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace notesy +{ + public class Class1 + { + } +} diff --git a/src/notesy/Notesy.Core.csproj b/src/notesy/Notesy.Core.csproj new file mode 100644 index 0000000..34022fe --- /dev/null +++ b/src/notesy/Notesy.Core.csproj @@ -0,0 +1,53 @@ + + + + + Debug + AnyCPU + {5DD8FFDA-34C8-4F81-8740-20E29BFC4E90} + Library + Properties + notesy + notesy + v4.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/notesy/Properties/AssemblyInfo.cs b/src/notesy/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..9ce2c37 --- /dev/null +++ b/src/notesy/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +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("notesy")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("notesy")] +[assembly: AssemblyCopyright("Copyright © 2014")] +[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("90973b19-9c9b-4347-9217-bd533cea0d45")] + +// 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 Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/notesy/notesy.sln b/src/notesy/notesy.sln new file mode 100644 index 0000000..543a4bc --- /dev/null +++ b/src/notesy/notesy.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Notesy.Core", "Notesy.Core.csproj", "{5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal From c90c2e0089154eea31f6c9b69a4b13276ad1e5ee Mon Sep 17 00:00:00 2001 From: David Long Date: Fri, 8 Aug 2014 16:14:23 -0700 Subject: [PATCH 03/28] Here's what I just did: [renamed: src/notesy/notesy.sln -> src/notesy.sln] --- src/{notesy => }/notesy.sln | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/{notesy => }/notesy.sln (91%) diff --git a/src/notesy/notesy.sln b/src/notesy.sln similarity index 91% rename from src/notesy/notesy.sln rename to src/notesy.sln index 543a4bc..f99c9ea 100644 --- a/src/notesy/notesy.sln +++ b/src/notesy.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Notesy.Core", "Notesy.Core.csproj", "{5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Notesy.Core", "notesy\Notesy.Core.csproj", "{5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution From 51450543c82fec108c793e0d620a035facb05344 Mon Sep 17 00:00:00 2001 From: David Long Date: Fri, 8 Aug 2014 16:15:35 -0700 Subject: [PATCH 04/28] removing boilerplate class --- src/notesy/Class1.cs | 12 ------------ src/notesy/Notesy.Core.csproj | 1 - 2 files changed, 13 deletions(-) delete mode 100644 src/notesy/Class1.cs diff --git a/src/notesy/Class1.cs b/src/notesy/Class1.cs deleted file mode 100644 index 6b7e145..0000000 --- a/src/notesy/Class1.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace notesy -{ - public class Class1 - { - } -} diff --git a/src/notesy/Notesy.Core.csproj b/src/notesy/Notesy.Core.csproj index 34022fe..b068aa3 100644 --- a/src/notesy/Notesy.Core.csproj +++ b/src/notesy/Notesy.Core.csproj @@ -39,7 +39,6 @@ - From 534651831113c4b2b58aa5ad7d1062747629aa9d Mon Sep 17 00:00:00 2001 From: David Long Date: Fri, 8 Aug 2014 16:17:17 -0700 Subject: [PATCH 05/28] Fixing up namespaces --- src/notesy/Notesy.Core.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/notesy/Notesy.Core.csproj b/src/notesy/Notesy.Core.csproj index b068aa3..901e1d8 100644 --- a/src/notesy/Notesy.Core.csproj +++ b/src/notesy/Notesy.Core.csproj @@ -7,8 +7,8 @@ {5DD8FFDA-34C8-4F81-8740-20E29BFC4E90} Library Properties - notesy - notesy + Notesy.Core + Notesy.Core v4.5 512 From 0801052441fe8684f674e65034df46dad59950ba Mon Sep 17 00:00:00 2001 From: David Long Date: Fri, 8 Aug 2014 16:24:14 -0700 Subject: [PATCH 06/28] setting things up - we don't need a .Web project for this task but it can be used to illustrate something later --- src/Notesy.Api/App_Start/RouteConfig.cs | 23 ++++ src/Notesy.Api/Global.asax | 1 + src/Notesy.Api/Global.asax.cs | 18 +++ src/Notesy.Api/Notesy.Api.csproj | 141 ++++++++++++++++++++++ src/Notesy.Api/Properties/AssemblyInfo.cs | 35 ++++++ src/Notesy.Api/Views/web.config | 34 ++++++ src/Notesy.Api/Web.Debug.config | 30 +++++ src/Notesy.Api/Web.Release.config | 31 +++++ src/Notesy.Api/Web.config | 17 +++ src/Notesy.Api/packages.config | 7 ++ src/Notesy.Web/App_Start/RouteConfig.cs | 23 ++++ src/Notesy.Web/Global.asax | 1 + src/Notesy.Web/Global.asax.cs | 18 +++ src/Notesy.Web/Notesy.Web.csproj | 141 ++++++++++++++++++++++ src/Notesy.Web/Properties/AssemblyInfo.cs | 35 ++++++ src/Notesy.Web/Views/web.config | 34 ++++++ src/Notesy.Web/Web.Debug.config | 30 +++++ src/Notesy.Web/Web.Release.config | 31 +++++ src/Notesy.Web/Web.config | 17 +++ src/Notesy.Web/packages.config | 7 ++ src/notesy.sln | 12 ++ 21 files changed, 686 insertions(+) create mode 100644 src/Notesy.Api/App_Start/RouteConfig.cs create mode 100644 src/Notesy.Api/Global.asax create mode 100644 src/Notesy.Api/Global.asax.cs create mode 100644 src/Notesy.Api/Notesy.Api.csproj create mode 100644 src/Notesy.Api/Properties/AssemblyInfo.cs create mode 100644 src/Notesy.Api/Views/web.config create mode 100644 src/Notesy.Api/Web.Debug.config create mode 100644 src/Notesy.Api/Web.Release.config create mode 100644 src/Notesy.Api/Web.config create mode 100644 src/Notesy.Api/packages.config create mode 100644 src/Notesy.Web/App_Start/RouteConfig.cs create mode 100644 src/Notesy.Web/Global.asax create mode 100644 src/Notesy.Web/Global.asax.cs create mode 100644 src/Notesy.Web/Notesy.Web.csproj create mode 100644 src/Notesy.Web/Properties/AssemblyInfo.cs create mode 100644 src/Notesy.Web/Views/web.config create mode 100644 src/Notesy.Web/Web.Debug.config create mode 100644 src/Notesy.Web/Web.Release.config create mode 100644 src/Notesy.Web/Web.config create mode 100644 src/Notesy.Web/packages.config diff --git a/src/Notesy.Api/App_Start/RouteConfig.cs b/src/Notesy.Api/App_Start/RouteConfig.cs new file mode 100644 index 0000000..18a7f45 --- /dev/null +++ b/src/Notesy.Api/App_Start/RouteConfig.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using System.Web.Routing; + +namespace Notesy.Api +{ + public class RouteConfig + { + public static void RegisterRoutes(RouteCollection routes) + { + routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); + + routes.MapRoute( + name: "Default", + url: "{controller}/{action}/{id}", + defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } + ); + } + } +} diff --git a/src/Notesy.Api/Global.asax b/src/Notesy.Api/Global.asax new file mode 100644 index 0000000..606815a --- /dev/null +++ b/src/Notesy.Api/Global.asax @@ -0,0 +1 @@ +<%@ Application Codebehind="Global.asax.cs" Inherits="Notesy.Api.MvcApplication" Language="C#" %> diff --git a/src/Notesy.Api/Global.asax.cs b/src/Notesy.Api/Global.asax.cs new file mode 100644 index 0000000..0e4389c --- /dev/null +++ b/src/Notesy.Api/Global.asax.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using System.Web.Routing; + +namespace Notesy.Api +{ + public class MvcApplication : System.Web.HttpApplication + { + protected void Application_Start() + { + AreaRegistration.RegisterAllAreas(); + RouteConfig.RegisterRoutes(RouteTable.Routes); + } + } +} diff --git a/src/Notesy.Api/Notesy.Api.csproj b/src/Notesy.Api/Notesy.Api.csproj new file mode 100644 index 0000000..621a676 --- /dev/null +++ b/src/Notesy.Api/Notesy.Api.csproj @@ -0,0 +1,141 @@ + + + + + Debug + AnyCPU + + + 2.0 + 9b2a07d7-fc53-4df0-8fe2-12587391fa1f + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + Notesy.Api + Notesy.Api + v4.5 + false + + + + + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + True + ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll + + + ..\packages\Microsoft.AspNet.Razor.3.0.0\lib\net45\System.Web.Razor.dll + + + ..\packages\Microsoft.AspNet.Webpages.3.0.0\lib\net45\System.Web.Webpages.dll + + + ..\packages\Microsoft.AspNet.Webpages.3.0.0\lib\net45\System.Web.Webpages.Deployment.dll + + + ..\packages\Microsoft.AspNet.Webpages.3.0.0\lib\net45\System.Web.Webpages.Razor.dll + + + ..\packages\Microsoft.AspNet.Webpages.3.0.0\lib\net45\System.Web.Helpers.dll + + + ..\packages\Microsoft.AspNet.Mvc.5.0.0\lib\net45\System.Web.Mvc.dll + + + + + + + + + + Global.asax + + + + + + + Web.config + + + Web.config + + + + + + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + False + True + 0 + / + + + False + False + + + False + + + + + + \ No newline at end of file diff --git a/src/Notesy.Api/Properties/AssemblyInfo.cs b/src/Notesy.Api/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..6e121e3 --- /dev/null +++ b/src/Notesy.Api/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("Notesy.Api")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Notesy.Api")] +[assembly: AssemblyCopyright("Copyright © 2014")] +[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("86bfb859-2218-496a-b8e5-e250645b26ba")] + +// 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/Notesy.Api/Views/web.config b/src/Notesy.Api/Views/web.config new file mode 100644 index 0000000..09da0d0 --- /dev/null +++ b/src/Notesy.Api/Views/web.config @@ -0,0 +1,34 @@ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Notesy.Api/Web.Debug.config b/src/Notesy.Api/Web.Debug.config new file mode 100644 index 0000000..f7c5612 --- /dev/null +++ b/src/Notesy.Api/Web.Debug.config @@ -0,0 +1,30 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/Notesy.Api/Web.Release.config b/src/Notesy.Api/Web.Release.config new file mode 100644 index 0000000..52c6bbe --- /dev/null +++ b/src/Notesy.Api/Web.Release.config @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/Notesy.Api/Web.config b/src/Notesy.Api/Web.config new file mode 100644 index 0000000..67ea100 --- /dev/null +++ b/src/Notesy.Api/Web.config @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + diff --git a/src/Notesy.Api/packages.config b/src/Notesy.Api/packages.config new file mode 100644 index 0000000..57f2336 --- /dev/null +++ b/src/Notesy.Api/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/Notesy.Web/App_Start/RouteConfig.cs b/src/Notesy.Web/App_Start/RouteConfig.cs new file mode 100644 index 0000000..ac4ee7d --- /dev/null +++ b/src/Notesy.Web/App_Start/RouteConfig.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using System.Web.Routing; + +namespace Notesy.Web +{ + public class RouteConfig + { + public static void RegisterRoutes(RouteCollection routes) + { + routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); + + routes.MapRoute( + name: "Default", + url: "{controller}/{action}/{id}", + defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } + ); + } + } +} diff --git a/src/Notesy.Web/Global.asax b/src/Notesy.Web/Global.asax new file mode 100644 index 0000000..5dbaa50 --- /dev/null +++ b/src/Notesy.Web/Global.asax @@ -0,0 +1 @@ +<%@ Application Codebehind="Global.asax.cs" Inherits="Notesy.Web.MvcApplication" Language="C#" %> diff --git a/src/Notesy.Web/Global.asax.cs b/src/Notesy.Web/Global.asax.cs new file mode 100644 index 0000000..c5b4c06 --- /dev/null +++ b/src/Notesy.Web/Global.asax.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using System.Web.Routing; + +namespace Notesy.Web +{ + public class MvcApplication : System.Web.HttpApplication + { + protected void Application_Start() + { + AreaRegistration.RegisterAllAreas(); + RouteConfig.RegisterRoutes(RouteTable.Routes); + } + } +} diff --git a/src/Notesy.Web/Notesy.Web.csproj b/src/Notesy.Web/Notesy.Web.csproj new file mode 100644 index 0000000..4e87ddd --- /dev/null +++ b/src/Notesy.Web/Notesy.Web.csproj @@ -0,0 +1,141 @@ + + + + + Debug + AnyCPU + + + 2.0 + {7CAD7D06-49CF-4143-BBB0-1A884EC20D57} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + Notesy.Web + Notesy.Web + v4.5 + true + + + + + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + True + ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll + + + ..\packages\Microsoft.AspNet.Razor.3.0.0\lib\net45\System.Web.Razor.dll + + + ..\packages\Microsoft.AspNet.Webpages.3.0.0\lib\net45\System.Web.Webpages.dll + + + ..\packages\Microsoft.AspNet.Webpages.3.0.0\lib\net45\System.Web.Webpages.Deployment.dll + + + ..\packages\Microsoft.AspNet.Webpages.3.0.0\lib\net45\System.Web.Webpages.Razor.dll + + + ..\packages\Microsoft.AspNet.Webpages.3.0.0\lib\net45\System.Web.Helpers.dll + + + ..\packages\Microsoft.AspNet.Mvc.5.0.0\lib\net45\System.Web.Mvc.dll + + + + + + + + + + Global.asax + + + + + + + + Web.config + + + Web.config + + + + + + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + True + True + 0 + / + http://localhost:63163/ + False + False + + + False + + + + + + \ No newline at end of file diff --git a/src/Notesy.Web/Properties/AssemblyInfo.cs b/src/Notesy.Web/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..be59c62 --- /dev/null +++ b/src/Notesy.Web/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("Notesy.Web")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Notesy.Web")] +[assembly: AssemblyCopyright("Copyright © 2014")] +[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("eb19e232-c2d1-46aa-b227-d5acba68b72d")] + +// 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/Notesy.Web/Views/web.config b/src/Notesy.Web/Views/web.config new file mode 100644 index 0000000..6dd92c5 --- /dev/null +++ b/src/Notesy.Web/Views/web.config @@ -0,0 +1,34 @@ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Notesy.Web/Web.Debug.config b/src/Notesy.Web/Web.Debug.config new file mode 100644 index 0000000..f7c5612 --- /dev/null +++ b/src/Notesy.Web/Web.Debug.config @@ -0,0 +1,30 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/Notesy.Web/Web.Release.config b/src/Notesy.Web/Web.Release.config new file mode 100644 index 0000000..52c6bbe --- /dev/null +++ b/src/Notesy.Web/Web.Release.config @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/Notesy.Web/Web.config b/src/Notesy.Web/Web.config new file mode 100644 index 0000000..67ea100 --- /dev/null +++ b/src/Notesy.Web/Web.config @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + diff --git a/src/Notesy.Web/packages.config b/src/Notesy.Web/packages.config new file mode 100644 index 0000000..57f2336 --- /dev/null +++ b/src/Notesy.Web/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/notesy.sln b/src/notesy.sln index f99c9ea..e96f33e 100644 --- a/src/notesy.sln +++ b/src/notesy.sln @@ -3,6 +3,10 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Notesy.Core", "notesy\Notesy.Core.csproj", "{5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Notesy.Api", "..\Notesy.Api\Notesy.Api.csproj", "{93DB8BA4-A51E-4963-9148-023DF9AE71A6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Notesy.Web", "Notesy.Web\Notesy.Web.csproj", "{7CAD7D06-49CF-4143-BBB0-1A884EC20D57}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -13,6 +17,14 @@ Global {5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}.Debug|Any CPU.Build.0 = Debug|Any CPU {5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}.Release|Any CPU.ActiveCfg = Release|Any CPU {5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}.Release|Any CPU.Build.0 = Release|Any CPU + {93DB8BA4-A51E-4963-9148-023DF9AE71A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {93DB8BA4-A51E-4963-9148-023DF9AE71A6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {93DB8BA4-A51E-4963-9148-023DF9AE71A6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {93DB8BA4-A51E-4963-9148-023DF9AE71A6}.Release|Any CPU.Build.0 = Release|Any CPU + {7CAD7D06-49CF-4143-BBB0-1A884EC20D57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7CAD7D06-49CF-4143-BBB0-1A884EC20D57}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7CAD7D06-49CF-4143-BBB0-1A884EC20D57}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7CAD7D06-49CF-4143-BBB0-1A884EC20D57}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From bccd6109b35dce30c25f26f0b3b767fd920acc66 Mon Sep 17 00:00:00 2001 From: David Long Date: Fri, 8 Aug 2014 16:25:20 -0700 Subject: [PATCH 07/28] forgot to build after setting things up... oops --- src/Notesy.Api/Notesy.Api.csproj | 10 +++++----- src/notesy.sln | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Notesy.Api/Notesy.Api.csproj b/src/Notesy.Api/Notesy.Api.csproj index 621a676..d95f2dc 100644 --- a/src/Notesy.Api/Notesy.Api.csproj +++ b/src/Notesy.Api/Notesy.Api.csproj @@ -7,14 +7,14 @@ 2.0 - 9b2a07d7-fc53-4df0-8fe2-12587391fa1f + {291D09DB-7DCB-41DB-B634-942B1F8BC545} {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} Library Properties Notesy.Api Notesy.Api v4.5 - false + true @@ -93,6 +93,7 @@ + Web.config @@ -116,12 +117,11 @@ - False + True True 0 / - - + http://localhost:63185/ False False diff --git a/src/notesy.sln b/src/notesy.sln index e96f33e..17544d2 100644 --- a/src/notesy.sln +++ b/src/notesy.sln @@ -3,10 +3,10 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Notesy.Core", "notesy\Notesy.Core.csproj", "{5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Notesy.Api", "..\Notesy.Api\Notesy.Api.csproj", "{93DB8BA4-A51E-4963-9148-023DF9AE71A6}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Notesy.Web", "Notesy.Web\Notesy.Web.csproj", "{7CAD7D06-49CF-4143-BBB0-1A884EC20D57}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Notesy.Api", "Notesy.Api\Notesy.Api.csproj", "{291D09DB-7DCB-41DB-B634-942B1F8BC545}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -17,14 +17,14 @@ Global {5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}.Debug|Any CPU.Build.0 = Debug|Any CPU {5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}.Release|Any CPU.ActiveCfg = Release|Any CPU {5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}.Release|Any CPU.Build.0 = Release|Any CPU - {93DB8BA4-A51E-4963-9148-023DF9AE71A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {93DB8BA4-A51E-4963-9148-023DF9AE71A6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {93DB8BA4-A51E-4963-9148-023DF9AE71A6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {93DB8BA4-A51E-4963-9148-023DF9AE71A6}.Release|Any CPU.Build.0 = Release|Any CPU {7CAD7D06-49CF-4143-BBB0-1A884EC20D57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7CAD7D06-49CF-4143-BBB0-1A884EC20D57}.Debug|Any CPU.Build.0 = Debug|Any CPU {7CAD7D06-49CF-4143-BBB0-1A884EC20D57}.Release|Any CPU.ActiveCfg = Release|Any CPU {7CAD7D06-49CF-4143-BBB0-1A884EC20D57}.Release|Any CPU.Build.0 = Release|Any CPU + {291D09DB-7DCB-41DB-B634-942B1F8BC545}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {291D09DB-7DCB-41DB-B634-942B1F8BC545}.Debug|Any CPU.Build.0 = Debug|Any CPU + {291D09DB-7DCB-41DB-B634-942B1F8BC545}.Release|Any CPU.ActiveCfg = Release|Any CPU + {291D09DB-7DCB-41DB-B634-942B1F8BC545}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 47486e73ac211d51cf8efc096a599ea8345e81e6 Mon Sep 17 00:00:00 2001 From: David Long Date: Fri, 8 Aug 2014 16:30:08 -0700 Subject: [PATCH 08/28] More project setup/cleanup. As with most platforms, setup is where a lot of people make mistakes that plague the rest of development. Take your time and do it right. I've been doing .Net for almost 15 years at this point and I still have to manually fix this (every. stinking. time.). --- src/{notesy => Notesy.Core}/Notesy.Core.csproj | 0 .../Properties/AssemblyInfo.cs | 0 src/notesy.sln | 12 ++++++------ 3 files changed, 6 insertions(+), 6 deletions(-) rename src/{notesy => Notesy.Core}/Notesy.Core.csproj (100%) rename src/{notesy => Notesy.Core}/Properties/AssemblyInfo.cs (100%) diff --git a/src/notesy/Notesy.Core.csproj b/src/Notesy.Core/Notesy.Core.csproj similarity index 100% rename from src/notesy/Notesy.Core.csproj rename to src/Notesy.Core/Notesy.Core.csproj diff --git a/src/notesy/Properties/AssemblyInfo.cs b/src/Notesy.Core/Properties/AssemblyInfo.cs similarity index 100% rename from src/notesy/Properties/AssemblyInfo.cs rename to src/Notesy.Core/Properties/AssemblyInfo.cs diff --git a/src/notesy.sln b/src/notesy.sln index 17544d2..f05c66e 100644 --- a/src/notesy.sln +++ b/src/notesy.sln @@ -1,22 +1,18 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Notesy.Core", "notesy\Notesy.Core.csproj", "{5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Notesy.Web", "Notesy.Web\Notesy.Web.csproj", "{7CAD7D06-49CF-4143-BBB0-1A884EC20D57}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Notesy.Api", "Notesy.Api\Notesy.Api.csproj", "{291D09DB-7DCB-41DB-B634-942B1F8BC545}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Notesy.Core", "Notesy.Core\Notesy.Core.csproj", "{5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}.Release|Any CPU.Build.0 = Release|Any CPU {7CAD7D06-49CF-4143-BBB0-1A884EC20D57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7CAD7D06-49CF-4143-BBB0-1A884EC20D57}.Debug|Any CPU.Build.0 = Debug|Any CPU {7CAD7D06-49CF-4143-BBB0-1A884EC20D57}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -25,6 +21,10 @@ Global {291D09DB-7DCB-41DB-B634-942B1F8BC545}.Debug|Any CPU.Build.0 = Debug|Any CPU {291D09DB-7DCB-41DB-B634-942B1F8BC545}.Release|Any CPU.ActiveCfg = Release|Any CPU {291D09DB-7DCB-41DB-B634-942B1F8BC545}.Release|Any CPU.Build.0 = Release|Any CPU + {5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 29cad3fe21aaa2d80cfdf72d2b979b427a85b4d1 Mon Sep 17 00:00:00 2001 From: David Long Date: Fri, 8 Aug 2014 16:51:02 -0700 Subject: [PATCH 09/28] What is a note? Here's a model to help define it --- src/Notesy.Core/Note.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/Notesy.Core/Note.cs diff --git a/src/Notesy.Core/Note.cs b/src/Notesy.Core/Note.cs new file mode 100644 index 0000000..1c02deb --- /dev/null +++ b/src/Notesy.Core/Note.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Notesy.Core +{ + public class Note + { + public string Contents { get; set; } + public bool IsComplete { get; set; } + } +} From d510f3983ad30e2ecd323edf8249f48cc0cc87d7 Mon Sep 17 00:00:00 2001 From: David Long Date: Fri, 8 Aug 2014 16:52:57 -0700 Subject: [PATCH 10/28] super hard to program while trying to be overly atomic for illustrative purposes --- src/Notesy.Core/{ => Models}/Note.cs | 2 +- src/Notesy.Core/Notesy.Core.csproj | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) rename src/Notesy.Core/{ => Models}/Note.cs (89%) diff --git a/src/Notesy.Core/Note.cs b/src/Notesy.Core/Models/Note.cs similarity index 89% rename from src/Notesy.Core/Note.cs rename to src/Notesy.Core/Models/Note.cs index 1c02deb..5d8bd66 100644 --- a/src/Notesy.Core/Note.cs +++ b/src/Notesy.Core/Models/Note.cs @@ -4,7 +4,7 @@ using System.Text; using System.Threading.Tasks; -namespace Notesy.Core +namespace Notesy.Core.Models { public class Note { diff --git a/src/Notesy.Core/Notesy.Core.csproj b/src/Notesy.Core/Notesy.Core.csproj index 901e1d8..6ccf8c8 100644 --- a/src/Notesy.Core/Notesy.Core.csproj +++ b/src/Notesy.Core/Notesy.Core.csproj @@ -39,6 +39,7 @@ + From eb94a732cd213f5d91565eeaf0233f67ff3e2abd Mon Sep 17 00:00:00 2001 From: David Long Date: Fri, 8 Aug 2014 16:59:53 -0700 Subject: [PATCH 11/28] A lot going on here: 1) forgot an id on note model, 2) scafolding out service interface, 3) create/update are basically the same so let's call that Save for now. 4) also adding get and delete calls --- src/Notesy.Core/Models/Note.cs | 1 + .../Services/Interfaces/INoteService.cs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 src/Notesy.Core/Services/Interfaces/INoteService.cs diff --git a/src/Notesy.Core/Models/Note.cs b/src/Notesy.Core/Models/Note.cs index 5d8bd66..aca3269 100644 --- a/src/Notesy.Core/Models/Note.cs +++ b/src/Notesy.Core/Models/Note.cs @@ -8,6 +8,7 @@ namespace Notesy.Core.Models { public class Note { + public string Id { get; set; } public string Contents { get; set; } public bool IsComplete { get; set; } } diff --git a/src/Notesy.Core/Services/Interfaces/INoteService.cs b/src/Notesy.Core/Services/Interfaces/INoteService.cs new file mode 100644 index 0000000..ad2e07c --- /dev/null +++ b/src/Notesy.Core/Services/Interfaces/INoteService.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Notesy.Core.Models; + +namespace Notesy.Core.Services.Interfaces +{ + public interface INoteService + { + Note GetNote(int id); + Note SaveNote(Note input); + Note DeleteNote(int id); + } +} From 715759489b62f88e4bf535f3d2bc74a86e2b8510 Mon Sep 17 00:00:00 2001 From: David Long Date: Fri, 8 Aug 2014 17:06:12 -0700 Subject: [PATCH 12/28] Let's start stubbing out the service with simple fake data --- src/Notesy.Core/Models/Note.cs | 7 +++- src/Notesy.Core/Notesy.Core.csproj | 5 +++ .../Services/Stubs/NoteServiceStub.cs | 33 +++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 src/Notesy.Core/Services/Stubs/NoteServiceStub.cs diff --git a/src/Notesy.Core/Models/Note.cs b/src/Notesy.Core/Models/Note.cs index aca3269..5b35c50 100644 --- a/src/Notesy.Core/Models/Note.cs +++ b/src/Notesy.Core/Models/Note.cs @@ -8,8 +8,13 @@ namespace Notesy.Core.Models { public class Note { - public string Id { get; set; } + public int Id { get; set; } public string Contents { get; set; } public bool IsComplete { get; set; } + + public Note() + { + IsComplete = false; // this defaults to false but let's be explicit + } } } diff --git a/src/Notesy.Core/Notesy.Core.csproj b/src/Notesy.Core/Notesy.Core.csproj index 6ccf8c8..930c1a4 100644 --- a/src/Notesy.Core/Notesy.Core.csproj +++ b/src/Notesy.Core/Notesy.Core.csproj @@ -41,6 +41,11 @@ + + + + + + + 10.0 + + True + 10.0 + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Notesy.Database/dbo/Tables/ApiUser.sql b/src/Notesy.Database/dbo/Tables/ApiUser.sql new file mode 100644 index 0000000..902375b --- /dev/null +++ b/src/Notesy.Database/dbo/Tables/ApiUser.sql @@ -0,0 +1,9 @@ +CREATE TABLE [dbo].[ApiUser] ( + [Id] INT IDENTITY (1, 1) NOT NULL, + [Name] NVARCHAR (256) NOT NULL, + [ApiKey] NVARCHAR (1024) NOT NULL, + [ApiSecret] NVARCHAR (1024) NOT NULL, + [DateCreated] DATETIME CONSTRAINT [DF_ApiUser_DateCreated] DEFAULT (getutcdate()) NOT NULL, + CONSTRAINT [PK_ApiUser] PRIMARY KEY CLUSTERED ([Id] ASC) +); + diff --git a/src/Notesy.Database/dbo/Tables/Note.sql b/src/Notesy.Database/dbo/Tables/Note.sql new file mode 100644 index 0000000..f408b2d --- /dev/null +++ b/src/Notesy.Database/dbo/Tables/Note.sql @@ -0,0 +1,11 @@ +CREATE TABLE [dbo].[Note] ( + [Id] INT IDENTITY (1, 1) NOT NULL, + [Title] NVARCHAR (512) NULL, + [Description] NVARCHAR (2048) NULL, + [IsComplete] BIT CONSTRAINT [DF_Note_IsComplete] DEFAULT ((0)) NOT NULL, + [ApiUserId] INT NOT NULL, + [DateCreated] DATETIME CONSTRAINT [DF_Note_DateCreated] DEFAULT (getutcdate()) NOT NULL, + CONSTRAINT [PK_Note] PRIMARY KEY CLUSTERED ([Id] ASC), + CONSTRAINT [FK_Note_ApiUser] FOREIGN KEY ([ApiUserId]) REFERENCES [dbo].[ApiUser] ([Id]) +); + From 6bae8c30b9133bdc78cb9e1f486ef40eb6d54e59 Mon Sep 17 00:00:00 2001 From: David Long Date: Sat, 9 Aug 2014 16:43:30 -0700 Subject: [PATCH 23/28] Woohoo! We're lucky our test passed. :sunglasses: --- src/Notesy.Tests/App.config | 6 ++ .../Core/Services/NoteServiceTests.cs | 25 +++++ src/Notesy.Tests/Notesy.Tests.csproj | 97 +++++++++++++++++++ src/Notesy.Tests/Properties/AssemblyInfo.cs | 36 +++++++ src/notesy.sln | 6 ++ 5 files changed, 170 insertions(+) create mode 100644 src/Notesy.Tests/App.config create mode 100644 src/Notesy.Tests/Core/Services/NoteServiceTests.cs create mode 100644 src/Notesy.Tests/Notesy.Tests.csproj create mode 100644 src/Notesy.Tests/Properties/AssemblyInfo.cs diff --git a/src/Notesy.Tests/App.config b/src/Notesy.Tests/App.config new file mode 100644 index 0000000..1801f64 --- /dev/null +++ b/src/Notesy.Tests/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/Notesy.Tests/Core/Services/NoteServiceTests.cs b/src/Notesy.Tests/Core/Services/NoteServiceTests.cs new file mode 100644 index 0000000..4779669 --- /dev/null +++ b/src/Notesy.Tests/Core/Services/NoteServiceTests.cs @@ -0,0 +1,25 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Notesy.Core.Models; +using Notesy.Core.Services.Concrete; + +namespace Notesy.Tests.Core.Services +{ + [TestClass] + public class NoteServiceTests + { + private NoteService svc = new NoteService(); + + [TestMethod] + public void TestNoteInsert() + { + var n = new Note() { ApiUserId = 1, Description = "Go to Santa Monica Pier and watch Dr. Who", Title = "Dr Who @ the beach." }; + + var result = svc.SaveNote(n); + + Assert.IsNotNull(result); + Assert.IsTrue(result.Id != 0); + } + } +} diff --git a/src/Notesy.Tests/Notesy.Tests.csproj b/src/Notesy.Tests/Notesy.Tests.csproj new file mode 100644 index 0000000..f8d5d95 --- /dev/null +++ b/src/Notesy.Tests/Notesy.Tests.csproj @@ -0,0 +1,97 @@ + + + + Debug + AnyCPU + {AE724AF0-7C54-427D-87F8-AD0E9056EE25} + Library + Properties + Notesy.Tests + Notesy.Tests + v4.5 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + {291d09db-7dcb-41db-b634-942b1f8bc545} + Notesy.Api + + + {5dd8ffda-34c8-4f81-8740-20e29bfc4e90} + Notesy.Core + + + + + + + False + + + False + + + False + + + False + + + + + + + + \ No newline at end of file diff --git a/src/Notesy.Tests/Properties/AssemblyInfo.cs b/src/Notesy.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f6a834a --- /dev/null +++ b/src/Notesy.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +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("Notesy.Tests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Notesy.Tests")] +[assembly: AssemblyCopyright("Copyright © 2014")] +[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("94535b77-6e32-47d2-bd23-959d5aaa29ef")] + +// 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 Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/notesy.sln b/src/notesy.sln index f05c66e..2e240d3 100644 --- a/src/notesy.sln +++ b/src/notesy.sln @@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Notesy.Api", "Notesy.Api\No EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Notesy.Core", "Notesy.Core\Notesy.Core.csproj", "{5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Notesy.Tests", "Notesy.Tests\Notesy.Tests.csproj", "{AE724AF0-7C54-427D-87F8-AD0E9056EE25}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -25,6 +27,10 @@ Global {5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}.Debug|Any CPU.Build.0 = Debug|Any CPU {5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}.Release|Any CPU.ActiveCfg = Release|Any CPU {5DD8FFDA-34C8-4F81-8740-20E29BFC4E90}.Release|Any CPU.Build.0 = Release|Any CPU + {AE724AF0-7C54-427D-87F8-AD0E9056EE25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AE724AF0-7C54-427D-87F8-AD0E9056EE25}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AE724AF0-7C54-427D-87F8-AD0E9056EE25}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AE724AF0-7C54-427D-87F8-AD0E9056EE25}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 8139aa1498611ccff259e63dcd811ef657501c8b Mon Sep 17 00:00:00 2001 From: David Long Date: Sat, 9 Aug 2014 16:59:08 -0700 Subject: [PATCH 24/28] Fixed the id issue when creating a new Note. --- src/Notesy.Core/Services/Concrete/NoteService.cs | 8 +++++--- src/Notesy.Tests/Core/Services/NoteServiceTests.cs | 2 +- src/Notesy.Tests/Notesy.Tests.csproj | 4 +++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Notesy.Core/Services/Concrete/NoteService.cs b/src/Notesy.Core/Services/Concrete/NoteService.cs index 6c6aa05..79f0f11 100644 --- a/src/Notesy.Core/Services/Concrete/NoteService.cs +++ b/src/Notesy.Core/Services/Concrete/NoteService.cs @@ -67,7 +67,9 @@ public Note SaveNote(Note input) @Description, @IsComplete, @ApiUserId, - @DateCreated)"; + @DateCreated) + + SELECT SCOPE_IDENTITY()"; var update = @"UPDATE [dbo].[Note] @@ -86,9 +88,9 @@ public Note SaveNote(Note input) using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["NOTESY_CORE"].ConnectionString)) { connection.Open(); - var result = connection.Execute(insert, new { Title = input.Title, Description = input.Description, IsComplete = input.IsComplete, ApiUserId = input.ApiUserId, DateCreated = input.DateCreated }); + var result = connection.Query(insert, new { Title = input.Title, Description = input.Description, IsComplete = input.IsComplete, ApiUserId = input.ApiUserId, DateCreated = input.DateCreated }); output = input; - // TODO: need to pop new ID into model and set to output; + output.Id = result.First(); } } else diff --git a/src/Notesy.Tests/Core/Services/NoteServiceTests.cs b/src/Notesy.Tests/Core/Services/NoteServiceTests.cs index 4779669..1a3ac3c 100644 --- a/src/Notesy.Tests/Core/Services/NoteServiceTests.cs +++ b/src/Notesy.Tests/Core/Services/NoteServiceTests.cs @@ -14,7 +14,7 @@ public class NoteServiceTests [TestMethod] public void TestNoteInsert() { - var n = new Note() { ApiUserId = 1, Description = "Go to Santa Monica Pier and watch Dr. Who", Title = "Dr Who @ the beach." }; + var n = new Note() { ApiUserId = 1, Description = "Go to Santa Monica Pier and watch Dr. Who", Title = string.Format("[{0}] Dr Who @ the beach.", DateTime.UtcNow.Ticks) }; var result = svc.SaveNote(n); diff --git a/src/Notesy.Tests/Notesy.Tests.csproj b/src/Notesy.Tests/Notesy.Tests.csproj index f8d5d95..5fcabc3 100644 --- a/src/Notesy.Tests/Notesy.Tests.csproj +++ b/src/Notesy.Tests/Notesy.Tests.csproj @@ -50,7 +50,6 @@ - @@ -67,6 +66,9 @@ Notesy.Core + + + From c39680d286d0db0856d8c7f83a0fe36d4ac16129 Mon Sep 17 00:00:00 2001 From: David Long Date: Sat, 9 Aug 2014 17:42:38 -0700 Subject: [PATCH 25/28] finished up the api user service --- .../Services/Concrete/ApiUserService.cs | 90 ++++++++++++++++++- 1 file changed, 86 insertions(+), 4 deletions(-) diff --git a/src/Notesy.Core/Services/Concrete/ApiUserService.cs b/src/Notesy.Core/Services/Concrete/ApiUserService.cs index d30a1f0..d679e70 100644 --- a/src/Notesy.Core/Services/Concrete/ApiUserService.cs +++ b/src/Notesy.Core/Services/Concrete/ApiUserService.cs @@ -1,9 +1,13 @@ using System; using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Data.SqlClient; using System.Linq; using System.Text; using System.Threading.Tasks; +using Dapper; using Notesy.Core.Models; using Notesy.Core.Services.Interfaces; @@ -11,20 +15,98 @@ namespace Notesy.Core.Services.Concrete { public class ApiUserService : IApiUserService { - public ApiUser GetApiUser(int id) { - throw new NotImplementedException(); + var output = new ApiUser(); + + var sql = @"SELECT + [Id] + ,[Name] + ,[ApiKey] + ,[ApiSecret] + ,[DateCreated] + FROM + [dbo].[ApiUser]"; + + using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["NOTESY_CORE"].ConnectionString)) + { + connection.Open(); + var users = connection.Query(sql, new { Id = id }); + output = users.First(); + } + + return output; } public ApiUser SaveApiUser(ApiUser input) { - throw new NotImplementedException(); + var output = new ApiUser(); + + var insert = @"INSERT INTO + [dbo].[ApiUser] + ([Name] + ,[ApiKey] + ,[ApiSecret] + ,[DateCreated]) + VALUES + (@Name, + @ApiKey, + @ApiSecret, + @DateCreated) + + SELECT SCOPE_IDENTITY()"; + + var update = @"UPDATE + [dbo].[ApiUser] + SET + [Name] = @Name, + [ApiKey] = @ApiKey, + [ApiSecret] = @ApiSecret, + [DateCreated] = @DateCreated + WHERE + [Id] = @Id"; + + if (input.Id == 0) + { + // insert + using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["NOTESY_CORE"].ConnectionString)) + { + connection.Open(); + var result = connection.Query(insert, new { Name = input.Name, ApiKey = input.ApiKey, ApiSecret = input.ApiSecret, DateCreated = input.DateCreated }); + output = input; + output.Id = result.First(); + } + } + else + { + // update + using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["NOTESY_CORE"].ConnectionString)) + { + connection.Open(); + var result = connection.Execute(update, new { Name = input.Name, ApiKey = input.ApiKey, ApiSecret = input.ApiSecret, DateCreated = input.DateCreated }); + output = input; + } + } + + return output; } public ApiUser DeleteApiUser(int id) { - throw new NotImplementedException(); + var output = GetApiUser(id); + + var sql = @"DELETE FROM + [dbo].[ApiUser] + WHERE + [Id] = @Id"; + + using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["NOTESY_CORE"].ConnectionString)) + { + connection.Open(); + var result = connection.Execute(sql, new { Id = id }); + } + + return output; } } } From b96ad607a5f3d6db39ef29bb5e678f9efcbd9271 Mon Sep 17 00:00:00 2001 From: David Long Date: Sat, 9 Aug 2014 18:18:45 -0700 Subject: [PATCH 26/28] Added GetApiUserByApiKey() call. Quick bug fix in GetApiUser(). --- src/Notesy.Api/Controllers/NoteController.cs | 15 ++++++++-- .../Services/Concrete/ApiUserService.cs | 29 ++++++++++++++++++- .../Services/Interfaces/IApiUserService.cs | 1 + .../Services/Stubs/ApiUserServiceStub.cs | 5 ++++ 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/Notesy.Api/Controllers/NoteController.cs b/src/Notesy.Api/Controllers/NoteController.cs index fd93302..89965fc 100644 --- a/src/Notesy.Api/Controllers/NoteController.cs +++ b/src/Notesy.Api/Controllers/NoteController.cs @@ -55,9 +55,20 @@ public ActionResult Save(Note input, string apikey = null, int? callId = null, s return Json(input, JsonRequestBehavior.AllowGet); } - public ActionResult Get(int id) + public ActionResult Get(int id, string apikey = null, int? callId = null, string signature = null) { - // TODO: add auth stuff + // basic logic for this architecture (could be different) + // 1) validate the auth on the incoming request + // 2) next we need to get the api user by apikey (oops - we need to write that!) + // 3) next we need to get the note + // 4) last we need to check that the api user is the owner of this note + + // obviously lots of decisions here... this might have been easier if we used + // an orm. we also could have pushed this logic one level lower so we could + // reuse it. this will be good for now though. + + if (!ValidateAuth(id.ToString(), apikey, callId.Value.ToString(), signature)) { return new HttpNotFoundResult(); } + var result = noteService.GetNote(id); return Json(result, JsonRequestBehavior.AllowGet); diff --git a/src/Notesy.Core/Services/Concrete/ApiUserService.cs b/src/Notesy.Core/Services/Concrete/ApiUserService.cs index d679e70..9c3a5e0 100644 --- a/src/Notesy.Core/Services/Concrete/ApiUserService.cs +++ b/src/Notesy.Core/Services/Concrete/ApiUserService.cs @@ -26,7 +26,9 @@ public ApiUser GetApiUser(int id) ,[ApiSecret] ,[DateCreated] FROM - [dbo].[ApiUser]"; + [dbo].[ApiUser] + WHERE + [Id] = @Id"; using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["NOTESY_CORE"].ConnectionString)) { @@ -108,5 +110,30 @@ public ApiUser DeleteApiUser(int id) return output; } + + + public ApiUser GetApiUserByApiKey(string apiKey) + { + var output = new ApiUser(); + + var sql = @"SELECT + [Id] + ,[Name] + ,[ApiKey] + ,[ApiSecret] + ,[DateCreated] + FROM + [dbo].[ApiUser] + WHERE + [ApiKey] = @ApiKey"; + + using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["NOTESY_CORE"].ConnectionString)) + { + connection.Open(); + var result = connection.Execute(sql, new { ApiKey = apiKey }); + } + + return output; + } } } diff --git a/src/Notesy.Core/Services/Interfaces/IApiUserService.cs b/src/Notesy.Core/Services/Interfaces/IApiUserService.cs index b489cc9..cdb950a 100644 --- a/src/Notesy.Core/Services/Interfaces/IApiUserService.cs +++ b/src/Notesy.Core/Services/Interfaces/IApiUserService.cs @@ -13,5 +13,6 @@ public interface IApiUserService ApiUser GetApiUser(int id); ApiUser SaveApiUser(ApiUser input); ApiUser DeleteApiUser(int id); + ApiUser GetApiUserByApiKey(string apiKey); } } diff --git a/src/Notesy.Core/Services/Stubs/ApiUserServiceStub.cs b/src/Notesy.Core/Services/Stubs/ApiUserServiceStub.cs index 61f219a..3b109e1 100644 --- a/src/Notesy.Core/Services/Stubs/ApiUserServiceStub.cs +++ b/src/Notesy.Core/Services/Stubs/ApiUserServiceStub.cs @@ -41,5 +41,10 @@ public ApiUser DeleteApiUser(int id) Name = "Famous Dave" }; } + + public ApiUser GetApiUserByApiKey(string apiKey) + { + throw new NotImplementedException(); + } } } From f61b47786938c2d69fc924c95d4fd9c667a8ae1e Mon Sep 17 00:00:00 2001 From: David Long Date: Sat, 9 Aug 2014 18:51:03 -0700 Subject: [PATCH 27/28] Logic updates in Save Note call. --- src/Notesy.Api/App_Start/NinjectWebCommon.cs | 4 +- src/Notesy.Api/Controllers/NoteController.cs | 44 ++++++++++++++++---- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/Notesy.Api/App_Start/NinjectWebCommon.cs b/src/Notesy.Api/App_Start/NinjectWebCommon.cs index ccc3afa..c4d5d17 100644 --- a/src/Notesy.Api/App_Start/NinjectWebCommon.cs +++ b/src/Notesy.Api/App_Start/NinjectWebCommon.cs @@ -50,7 +50,7 @@ private static IKernel CreateKernel() kernel.Bind().To(); // Note: Look how easy that is to swap out the fake services (which might not hit a real db) for real ones. I bet we could - // even do that a config setting or db setting too (or not)! + // even do that with a config setting or db setting too (or not)! //RegisterServices(kernel); RegisterStubServices(kernel); @@ -70,11 +70,13 @@ private static IKernel CreateKernel() private static void RegisterServices(IKernel kernel) { kernel.Bind().To().InRequestScope(); + kernel.Bind().To().InRequestScope(); } private static void RegisterStubServices(IKernel kernel) { kernel.Bind().To().InRequestScope(); + kernel.Bind().To().InRequestScope(); } } } diff --git a/src/Notesy.Api/Controllers/NoteController.cs b/src/Notesy.Api/Controllers/NoteController.cs index 89965fc..4c23bcf 100644 --- a/src/Notesy.Api/Controllers/NoteController.cs +++ b/src/Notesy.Api/Controllers/NoteController.cs @@ -29,10 +29,12 @@ namespace Notesy.Api.Controllers public class NoteController : Controller { private readonly INoteService noteService; + private readonly IApiUserService apiUserService; - public NoteController(INoteService noteService) + public NoteController(INoteService noteService, IApiUserService apiUserService) { this.noteService = noteService; + this.apiUserService = apiUserService; } // Note: This will be at something like: http://localhost:63185/note/save @@ -41,10 +43,10 @@ public NoteController(INoteService noteService) /// /// Save a Note. /// - /// - /// - /// - /// + /// The note to save. + /// The api key of the user request. + /// A rotating integer to uniquely identify this request. Usually just use current ticks count. There are a number of ways to do this. + /// Signature for this api request. /// public ActionResult Save(Note input, string apikey = null, int? callId = null, string signature = null) { @@ -69,9 +71,16 @@ public ActionResult Get(int id, string apikey = null, int? callId = null, string if (!ValidateAuth(id.ToString(), apikey, callId.Value.ToString(), signature)) { return new HttpNotFoundResult(); } - var result = noteService.GetNote(id); + var user = apiUserService.GetApiUserByApiKey(apikey); + var note = noteService.GetNote(id); - return Json(result, JsonRequestBehavior.AllowGet); + if (user.Id == note.ApiUserId) + { + return Json(note, JsonRequestBehavior.AllowGet); + } + + // TODO: Have to think about what to do with errors. + return Json(note, JsonRequestBehavior.AllowGet); } public ActionResult Delete(int id) @@ -82,8 +91,9 @@ public ActionResult Delete(int id) return Json(result, JsonRequestBehavior.AllowGet); } + // TODO: the following methods would be good candidates for relocation to a helper or other logical place. - private static bool ValidateAuth(string signatureToCheck, params string[] args) + private static bool ValidateAuth(string apiKey, string signatureToCheck, params string[] args) { // TODO: actual auth stuff // 1) lookup api user @@ -94,9 +104,25 @@ private static bool ValidateAuth(string signatureToCheck, params string[] args) return true; } + /// + /// + /// + /// + /// + /// + private static bool DoSignaturesMatch(ApiUser apiUser, string signature, params string[] args) + { + // how to generate a signature: + // 1) concat all the call parameters into one string (see string array above) + // 2) run some agreed upon encryption algorithm on concat string using the shared secret associated with the apikey => apiuser for this request + // 3) TODO: i think i got that right, double-check once implemented and document any changes here + + return true; + } + private static string ToJsonString(object input) { - // here is where we'd serialize to the object out to a string containing a json object + // here is where we'd serialize the object out to a string containing a json object return ""; } } From 642e50bfc37e37ce771e36b684ec2f9440a93c45 Mon Sep 17 00:00:00 2001 From: David Long Date: Sun, 10 Aug 2014 12:37:32 -0700 Subject: [PATCH 28/28] Added in some tests for ApiHelper, more roughing out of auth helper methods --- src/Notesy.Api/Controllers/NoteController.cs | 66 +++++++++++++++++--- src/Notesy.Tests/Api/ApiHelperTests.cs | 50 +++++++++++++++ src/Notesy.Tests/Notesy.Tests.csproj | 5 +- 3 files changed, 108 insertions(+), 13 deletions(-) create mode 100644 src/Notesy.Tests/Api/ApiHelperTests.cs diff --git a/src/Notesy.Api/Controllers/NoteController.cs b/src/Notesy.Api/Controllers/NoteController.cs index 4c23bcf..039ff42 100644 --- a/src/Notesy.Api/Controllers/NoteController.cs +++ b/src/Notesy.Api/Controllers/NoteController.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Security.Cryptography; +using System.Text; using System.Web; using System.Web.Mvc; @@ -50,7 +52,7 @@ public NoteController(INoteService noteService, IApiUserService apiUserService) /// public ActionResult Save(Note input, string apikey = null, int? callId = null, string signature = null) { - if (!ValidateAuth(ToJsonString(input), apikey, signature)) { return new HttpNotFoundResult(); } + if (!ApiHelper.ValidateAuth(ApiHelper.ToJsonString(input), apikey, signature)) { return new HttpUnauthorizedResult(); } var result = noteService.SaveNote(input); @@ -69,7 +71,7 @@ public ActionResult Get(int id, string apikey = null, int? callId = null, string // an orm. we also could have pushed this logic one level lower so we could // reuse it. this will be good for now though. - if (!ValidateAuth(id.ToString(), apikey, callId.Value.ToString(), signature)) { return new HttpNotFoundResult(); } + if (!ApiHelper.ValidateAuth(id.ToString(), apikey, callId.Value.ToString(), signature)) { return new HttpUnauthorizedResult(); } var user = apiUserService.GetApiUserByApiKey(apikey); var note = noteService.GetNote(id); @@ -83,22 +85,28 @@ public ActionResult Get(int id, string apikey = null, int? callId = null, string return Json(note, JsonRequestBehavior.AllowGet); } - public ActionResult Delete(int id) + public ActionResult Delete(int id, string apikey = null, int? callId = null, string signature = null) { - // TODO: add auth stuff + if (!ApiHelper.ValidateAuth(id.ToString(), apikey, callId.Value.ToString(), signature)) { return new HttpUnauthorizedResult(); } + var result = noteService.DeleteNote(id); return Json(result, JsonRequestBehavior.AllowGet); } + } + public static class ApiHelper + { // TODO: the following methods would be good candidates for relocation to a helper or other logical place. + // NOTE: Need to start making these public now for testing. It would be better to put this is in it's own + // helper class or something but we're running low on time (for now at least). - private static bool ValidateAuth(string apiKey, string signatureToCheck, params string[] args) + public static bool ValidateAuth(string apiKey, string signatureToCheck, params string[] args) { // TODO: actual auth stuff // 1) lookup api user // 2) generate signature of inputs - // 3) compare generated signature to incomming signatue + // 3) compare generated signature to incoming signature // 4) if valid, return true, otherwise false - note there could be a number of other things to check here: api usage, incoming IP, etc. return true; @@ -110,20 +118,58 @@ private static bool ValidateAuth(string apiKey, string signatureToCheck, params /// /// /// - private static bool DoSignaturesMatch(ApiUser apiUser, string signature, params string[] args) + public static bool DoSignaturesMatch(ApiUser apiUser, string signature, params string[] args) { // how to generate a signature: // 1) concat all the call parameters into one string (see string array above) // 2) run some agreed upon encryption algorithm on concat string using the shared secret associated with the apikey => apiuser for this request - // 3) TODO: i think i got that right, double-check once implemented and document any changes here + + // IMPORTANT: for this to actually work correctly we need to store the call id so that api calls cannot be replayed + // NOTE: remember this is just sort of a quick homebrew system. you'd almost certainly want to reuse an appropriate auth library. + // TODO: i think i got that right, double-check once implemented and document any changes here - return true; + var sb = new StringBuilder(); + foreach (var arg in args) + { + sb.Append(arg); + } + sb.Append(apiUser.ApiSecret); + var gen = ApiHelper.GetHash(sb.ToString()); + + return gen == signature; } - private static string ToJsonString(object input) + public static string ToJsonString(object input) { // here is where we'd serialize the object out to a string containing a json object return ""; } + + private static HashAlgorithm HashProvider = new SHA1Managed(); + + public static string GetHash(string input) + { + byte[] inputBytes = Encoding.UTF8.GetBytes(input); + byte[] data = HashProvider.ComputeHash(inputBytes); + var output = ByteArrayToHex(data); + + return output; + } + + // http://stackoverflow.com/questions/311165/how-do-you-convert-byte-array-to-hexadecimal-string-and-vice-versa + public static string ByteArrayToHex(byte[] barray) + { + char[] c = new char[barray.Length * 2]; + byte b; + for (int i = 0; i < barray.Length; ++i) + { + b = ((byte)(barray[i] >> 4)); + c[i * 2] = (char)(b > 9 ? b + 0x37 : b + 0x30); + b = ((byte)(barray[i] & 0xF)); + c[i * 2 + 1] = (char)(b > 9 ? b + 0x37 : b + 0x30); + } + + return new string(c); + } } } \ No newline at end of file diff --git a/src/Notesy.Tests/Api/ApiHelperTests.cs b/src/Notesy.Tests/Api/ApiHelperTests.cs new file mode 100644 index 0000000..9a8ce35 --- /dev/null +++ b/src/Notesy.Tests/Api/ApiHelperTests.cs @@ -0,0 +1,50 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Notesy.Api.Controllers; // helper in a controler... starting to get wonky +using Notesy.Core.Models; + +namespace Notesy.Tests.Api +{ + [TestClass] + public class ApiHelperTests + { + [TestMethod] + public void TestDoSignaturesMatch() + { + int id = 1; + string apikey = "BEF0A331-C388-43D2-96A0-6B94838F87E0"; + int? callId = 123; + string apisecret = "01D25503-C5C4-46A3-B99A-8BE8BB2AF0D7"; + + string inputs = string.Format("{0}{1}{2}{3}", id, apikey, callId, apisecret); + string signature = ApiHelper.GetHash(inputs); + var user = new ApiUser() + { + Id = id, + ApiKey = apikey, + ApiSecret = apisecret, + Name = "Does not matter" + }; + + var result = ApiHelper.DoSignaturesMatch(user, signature, id.ToString(), apikey, callId.ToString()); + + Assert.IsTrue(result); + } + + [TestMethod] + public void TestGetHash() + { + int id = 1; + string apikey = "BEF0A331-C388-43D2-96A0-6B94838F87E0"; + int? callId = 123; + string apisecret = "01D25503-C5C4-46A3-B99A-8BE8BB2AF0D7"; + + string inputs = string.Format("{0}{1}{2}{3}", id, apikey, callId, apisecret); + string signature = ApiHelper.GetHash(inputs); + + Assert.IsNotNull(signature); + Assert.AreEqual("9660A2B557FB0E3D8110C69F197944EBECCD8FFB", signature); + } + } +} diff --git a/src/Notesy.Tests/Notesy.Tests.csproj b/src/Notesy.Tests/Notesy.Tests.csproj index 5fcabc3..416f251 100644 --- a/src/Notesy.Tests/Notesy.Tests.csproj +++ b/src/Notesy.Tests/Notesy.Tests.csproj @@ -50,6 +50,7 @@ + @@ -66,9 +67,7 @@ Notesy.Core - - - +