Surprise MongoDB Move, PWestminster App
Shock move to MongoDB (issue #18) started with integrating the MongoDB MemberProvider from checkHashes. Still to complete, though user registration and role setup confirmed working. I've also started a Project Westminster App to tide us over til we get the chance to do a proper application with a new API that will be much easier once the MongoDB switch is complete.
@ -171,7 +171,7 @@
|
||||
</site>
|
||||
<site name="BuildFeed(1)" id="3">
|
||||
<application path="/" applicationPool="Clr4IntegratedAppPool">
|
||||
<virtualDirectory path="/" physicalPath="C:\Users\Thomas\Documents\Visual Studio 14\Projects\BuildFeed\BuildFeed" />
|
||||
<virtualDirectory path="/" physicalPath="D:\Thomas\My Documents\Visual Studio 2015\Projects\BuildFeed\BuildFeed" />
|
||||
</application>
|
||||
<bindings>
|
||||
<binding protocol="http" bindingInformation="*:50505:localhost" />
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.22609.0
|
||||
VisualStudioVersion = 14.0.23107.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BuildFeed", "BuildFeed\BuildFeed.csproj", "{CDDCF754-ECAA-4A66-ADAA-62957A57A51B}"
|
||||
EndProject
|
||||
@ -12,20 +12,94 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{5AA81F
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RedisAuth", "RedisAuth\RedisAuth.csproj", "{C6A16CF0-41DA-4B90-918A-CB84A8C3F1E2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MongoAuth", "MongoAuth\MongoAuth.csproj", "{7C67BFB9-1B3B-4676-A58D-10573DA82CFE}"
|
||||
EndProject
|
||||
Project("{262852C6-CD72-467D-83FE-5EEB1973A190}") = "BuildFeedApp-Westminster", "BuildFeedApp-Westminster\BuildFeedApp-Westminster.jsproj", "{5CAADB66-1FC2-4492-B766-36354687120D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|ARM = Debug|ARM
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|ARM = Release|ARM
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{CDDCF754-ECAA-4A66-ADAA-62957A57A51B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CDDCF754-ECAA-4A66-ADAA-62957A57A51B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CDDCF754-ECAA-4A66-ADAA-62957A57A51B}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{CDDCF754-ECAA-4A66-ADAA-62957A57A51B}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{CDDCF754-ECAA-4A66-ADAA-62957A57A51B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{CDDCF754-ECAA-4A66-ADAA-62957A57A51B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{CDDCF754-ECAA-4A66-ADAA-62957A57A51B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{CDDCF754-ECAA-4A66-ADAA-62957A57A51B}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{CDDCF754-ECAA-4A66-ADAA-62957A57A51B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CDDCF754-ECAA-4A66-ADAA-62957A57A51B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CDDCF754-ECAA-4A66-ADAA-62957A57A51B}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{CDDCF754-ECAA-4A66-ADAA-62957A57A51B}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{CDDCF754-ECAA-4A66-ADAA-62957A57A51B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{CDDCF754-ECAA-4A66-ADAA-62957A57A51B}.Release|x64.Build.0 = Release|Any CPU
|
||||
{CDDCF754-ECAA-4A66-ADAA-62957A57A51B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{CDDCF754-ECAA-4A66-ADAA-62957A57A51B}.Release|x86.Build.0 = Release|Any CPU
|
||||
{C6A16CF0-41DA-4B90-918A-CB84A8C3F1E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C6A16CF0-41DA-4B90-918A-CB84A8C3F1E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C6A16CF0-41DA-4B90-918A-CB84A8C3F1E2}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{C6A16CF0-41DA-4B90-918A-CB84A8C3F1E2}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{C6A16CF0-41DA-4B90-918A-CB84A8C3F1E2}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{C6A16CF0-41DA-4B90-918A-CB84A8C3F1E2}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{C6A16CF0-41DA-4B90-918A-CB84A8C3F1E2}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C6A16CF0-41DA-4B90-918A-CB84A8C3F1E2}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{C6A16CF0-41DA-4B90-918A-CB84A8C3F1E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C6A16CF0-41DA-4B90-918A-CB84A8C3F1E2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C6A16CF0-41DA-4B90-918A-CB84A8C3F1E2}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{C6A16CF0-41DA-4B90-918A-CB84A8C3F1E2}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{C6A16CF0-41DA-4B90-918A-CB84A8C3F1E2}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{C6A16CF0-41DA-4B90-918A-CB84A8C3F1E2}.Release|x64.Build.0 = Release|Any CPU
|
||||
{C6A16CF0-41DA-4B90-918A-CB84A8C3F1E2}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{C6A16CF0-41DA-4B90-918A-CB84A8C3F1E2}.Release|x86.Build.0 = Release|Any CPU
|
||||
{7C67BFB9-1B3B-4676-A58D-10573DA82CFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7C67BFB9-1B3B-4676-A58D-10573DA82CFE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7C67BFB9-1B3B-4676-A58D-10573DA82CFE}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{7C67BFB9-1B3B-4676-A58D-10573DA82CFE}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{7C67BFB9-1B3B-4676-A58D-10573DA82CFE}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{7C67BFB9-1B3B-4676-A58D-10573DA82CFE}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{7C67BFB9-1B3B-4676-A58D-10573DA82CFE}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{7C67BFB9-1B3B-4676-A58D-10573DA82CFE}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{7C67BFB9-1B3B-4676-A58D-10573DA82CFE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7C67BFB9-1B3B-4676-A58D-10573DA82CFE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7C67BFB9-1B3B-4676-A58D-10573DA82CFE}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{7C67BFB9-1B3B-4676-A58D-10573DA82CFE}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{7C67BFB9-1B3B-4676-A58D-10573DA82CFE}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{7C67BFB9-1B3B-4676-A58D-10573DA82CFE}.Release|x64.Build.0 = Release|Any CPU
|
||||
{7C67BFB9-1B3B-4676-A58D-10573DA82CFE}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{7C67BFB9-1B3B-4676-A58D-10573DA82CFE}.Release|x86.Build.0 = Release|Any CPU
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Debug|ARM.Deploy.0 = Debug|ARM
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Debug|x64.Build.0 = Debug|x64
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Debug|x86.Build.0 = Debug|x86
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Debug|x86.Deploy.0 = Debug|x86
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Release|ARM.Build.0 = Release|ARM
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Release|ARM.Deploy.0 = Release|ARM
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Release|x64.ActiveCfg = Release|x64
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Release|x64.Build.0 = Release|x64
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Release|x64.Deploy.0 = Release|x64
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Release|x86.ActiveCfg = Release|x86
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Release|x86.Build.0 = Release|x86
|
||||
{5CAADB66-1FC2-4492-B766-36354687120D}.Release|x86.Deploy.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using MongoAuth;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Security;
|
||||
using RedisAuth;
|
||||
|
||||
namespace BuildFeed.Areas.admin.Controllers
|
||||
{
|
||||
@ -41,28 +41,28 @@ namespace BuildFeed.Areas.admin.Controllers
|
||||
|
||||
public ActionResult approve(Guid id)
|
||||
{
|
||||
RedisMembershipProvider provider = (Membership.Provider as RedisMembershipProvider);
|
||||
MongoMembershipProvider provider = (Membership.Provider as MongoMembershipProvider);
|
||||
provider?.ChangeApproval(id, true);
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
public ActionResult unapprove(Guid id)
|
||||
{
|
||||
RedisMembershipProvider provider = (Membership.Provider as RedisMembershipProvider);
|
||||
MongoMembershipProvider provider = (Membership.Provider as MongoMembershipProvider);
|
||||
provider?.ChangeApproval(id, false);
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
public ActionResult @lock(Guid id)
|
||||
{
|
||||
RedisMembershipProvider provider = (Membership.Provider as RedisMembershipProvider);
|
||||
MongoMembershipProvider provider = (Membership.Provider as MongoMembershipProvider);
|
||||
provider?.ChangeLockStatus(id, true);
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
public ActionResult unlock(Guid id)
|
||||
{
|
||||
RedisMembershipProvider provider = (Membership.Provider as RedisMembershipProvider);
|
||||
MongoMembershipProvider provider = (Membership.Provider as MongoMembershipProvider);
|
||||
provider?.ChangeLockStatus(id, false);
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
@ -393,12 +393,6 @@
|
||||
<ItemGroup>
|
||||
<Service Include="{4A0DDDB5-7A95-4FBF-97CC-616D07737A77}" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\RedisAuth\RedisAuth.csproj">
|
||||
<Project>{c6a16cf0-41da-4b90-918a-cb84a8c3f1e2}</Project>
|
||||
<Name>RedisAuth</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Local\Common.qps-ploc.resx">
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
@ -431,6 +425,12 @@
|
||||
<LastGenOutput>Support.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MongoAuth\MongoAuth.csproj">
|
||||
<Project>{7c67bfb9-1b3b-4676-a58d-10573da82cfe}</Project>
|
||||
<Name>MongoAuth</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
|
@ -115,7 +115,7 @@ namespace BuildFeed.Controllers
|
||||
gr.SmoothingMode = SmoothingMode.HighQuality;
|
||||
gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||
|
||||
gr.FillRectangle(new SolidBrush(Color.FromArgb(0x30, 0x30, 0x30)), 0, 0, 560, 300);
|
||||
gr.FillRectangle(new SolidBrush(Color.FromArgb(0x27, 0x2b, 0x30)), 0, 0, 560, 300);
|
||||
gp.AddString("BUILDFEED", new FontFamily("Segoe UI"), (int) FontStyle.Bold, 16, new Point(20, 20), StringFormat.GenericTypographic);
|
||||
gp.AddString($"Windows NT {b.MajorVersion}.{b.MinorVersion} build", new FontFamily("Segoe UI"), 0, 24, new Point(20, 40), StringFormat.GenericTypographic);
|
||||
gp.AddString(b.Number.ToString(), new FontFamily("Segoe UI Light"), 0, 180, new Point(12, 20), StringFormat.GenericTypographic);
|
||||
|
@ -13,6 +13,7 @@
|
||||
<add key="data:ServerHost" value="localhost" />
|
||||
<add key="data:ServerPort" value="6379" />
|
||||
<add key="data:ServerDB" value="1" />
|
||||
<add key="data:MongoDB" value="BuildFeed" />
|
||||
<add key="RouteDebugger:Enabled" value="false" />
|
||||
</appSettings>
|
||||
<system.web>
|
||||
@ -28,13 +29,13 @@
|
||||
<membership defaultProvider="BuildFeedMemberProvider">
|
||||
<providers>
|
||||
<clear />
|
||||
<add name="BuildFeedMemberProvider" type="RedisAuth.RedisMembershipProvider,RedisAuth" />
|
||||
<add name="BuildFeedMemberProvider" type="MongoAuth.MongoMembershipProvider,MongoAuth" />
|
||||
</providers>
|
||||
</membership>
|
||||
<roleManager defaultProvider="BuildFeedRoleProvider" enabled="true">
|
||||
<providers>
|
||||
<clear />
|
||||
<add name="BuildFeedRoleProvider" type="RedisAuth.RedisRoleProvider,RedisAuth" />
|
||||
<add name="BuildFeedRoleProvider" type="MongoAuth.MongoRoleProvider,MongoAuth" />
|
||||
</providers>
|
||||
</roleManager>
|
||||
</system.web>
|
||||
|
97
BuildFeedApp-Westminster/BuildFeedApp-Westminster.jsproj
Normal file
@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|AnyCPU">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>AnyCPU</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x86">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x86</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|AnyCPU">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>AnyCPU</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x86">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x86</Platform>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>5caadb66-1fc2-4492-b766-36354687120d</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0'">
|
||||
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).Default.props" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).props" />
|
||||
<PropertyGroup>
|
||||
<EnableDotNetNativeCompatibleProfile>true</EnableDotNetNativeCompatibleProfile>
|
||||
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
||||
<TargetPlatformVersion>10.0.10240.0</TargetPlatformVersion>
|
||||
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
|
||||
<MinimumVisualStudioVersion>$(VersionNumberMajor).$(VersionNumberMinor)</MinimumVisualStudioVersion>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<PackageCertificateKeyFile>BuildFeedApp-Westminster_TemporaryKey.pfx</PackageCertificateKeyFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="package.appxmanifest">
|
||||
<SubType>Designer</SubType>
|
||||
</AppxManifest>
|
||||
<None Include="BuildFeedApp-Westminster_TemporaryKey.pfx" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="images\splashscreen.scale-125.png" />
|
||||
<Content Include="images\splashscreen.scale-150.png" />
|
||||
<Content Include="images\splashscreen.scale-200.png" />
|
||||
<Content Include="images\splashscreen.scale-400.png" />
|
||||
<Content Include="images\tiles\square\150px.scale-100.png" />
|
||||
<Content Include="images\tiles\square\150px.scale-125.png" />
|
||||
<Content Include="images\tiles\square\150px.scale-150.png" />
|
||||
<Content Include="images\tiles\square\150px.scale-200.png" />
|
||||
<Content Include="images\tiles\square\150px.scale-400.png" />
|
||||
<Content Include="images\tiles\square\71px.scale-100.png" />
|
||||
<Content Include="images\tiles\square\71px.scale-125.png" />
|
||||
<Content Include="images\tiles\square\71px.scale-150.png" />
|
||||
<Content Include="images\tiles\square\71px.scale-200.png" />
|
||||
<Content Include="images\tiles\square\71px.scale-400.png" />
|
||||
<Content Include="images\tiles\wide\620px.scale-100.png" />
|
||||
<Content Include="images\tiles\wide\620px.scale-125.png" />
|
||||
<Content Include="images\tiles\wide\620px.scale-150.png" />
|
||||
<Content Include="images\tiles\wide\620px.scale-200.png" />
|
||||
<Content Include="images\tiles\wide\620px.scale-400.png" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below then uncomment
|
||||
that target and the DisableFastUpToDateCheck PropertyGroup.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
<PropertyGroup>
|
||||
<DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
|
||||
</PropertyGroup>
|
||||
-->
|
||||
</Project>
|
BIN
BuildFeedApp-Westminster/images/splashscreen.scale-125.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
BuildFeedApp-Westminster/images/splashscreen.scale-150.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
BuildFeedApp-Westminster/images/splashscreen.scale-200.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
BuildFeedApp-Westminster/images/splashscreen.scale-400.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
BuildFeedApp-Westminster/images/tiles/square/150px.scale-100.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
BuildFeedApp-Westminster/images/tiles/square/150px.scale-125.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
BuildFeedApp-Westminster/images/tiles/square/150px.scale-150.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
BuildFeedApp-Westminster/images/tiles/square/150px.scale-200.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
BuildFeedApp-Westminster/images/tiles/square/150px.scale-400.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
BuildFeedApp-Westminster/images/tiles/square/71px.scale-100.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
BuildFeedApp-Westminster/images/tiles/square/71px.scale-125.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
BuildFeedApp-Westminster/images/tiles/square/71px.scale-150.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
BuildFeedApp-Westminster/images/tiles/square/71px.scale-200.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
BuildFeedApp-Westminster/images/tiles/square/71px.scale-400.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
BuildFeedApp-Westminster/images/tiles/wide/620px.scale-100.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
BuildFeedApp-Westminster/images/tiles/wide/620px.scale-125.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
BuildFeedApp-Westminster/images/tiles/wide/620px.scale-150.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
BuildFeedApp-Westminster/images/tiles/wide/620px.scale-200.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
BuildFeedApp-Westminster/images/tiles/wide/620px.scale-400.png
Normal file
After Width: | Height: | Size: 48 KiB |
31
BuildFeedApp-Westminster/package.appxmanifest
Normal file
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" IgnorableNamespaces="uap mp">
|
||||
<Identity Name="5caadb66-1fc2-4492-b766-36354687120d" Version="0.1.0.0" Publisher="CN=Thomas" />
|
||||
<mp:PhoneIdentity PhoneProductId="5caadb66-1fc2-4492-b766-36354687120d" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
|
||||
<Properties>
|
||||
<DisplayName>BuildFeedAppWestminster</DisplayName>
|
||||
<PublisherDisplayName>Thomas Hounsell</PublisherDisplayName>
|
||||
<Logo>images\storelogo.png</Logo>
|
||||
</Properties>
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
|
||||
</Dependencies>
|
||||
<Resources>
|
||||
<Resource Language="x-generate" />
|
||||
</Resources>
|
||||
<Applications>
|
||||
<Application Id="App" StartPage="https://buildfeed.net/">
|
||||
<uap:VisualElements DisplayName="BuildFeed" Description="BuildFeed is a service which tracks known builds of Microsoft Windows." BackgroundColor="transparent" Square150x150Logo="images\tiles\square\150px.png" Square44x44Logo="images\Square44x44Logo.png">
|
||||
<uap:DefaultTile Wide310x150Logo="images\Wide310x150Logo.png" ShortName="BuildFeed" Square71x71Logo="images\tiles\square\71px.png">
|
||||
</uap:DefaultTile>
|
||||
<uap:SplashScreen Image="images\tiles\wide\620px.png" BackgroundColor="#272b30" />
|
||||
</uap:VisualElements>
|
||||
<uap:ApplicationContentUriRules>
|
||||
<uap:Rule Match="https://buildfeed.net/" Type="include" WindowsRuntimeAccess="none" />
|
||||
</uap:ApplicationContentUriRules>
|
||||
</Application>
|
||||
</Applications>
|
||||
<Capabilities>
|
||||
<Capability Name="internetClient" />
|
||||
</Capabilities>
|
||||
</Package>
|
26
MongoAuth/DatabaseConfig.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using System.Configuration;
|
||||
|
||||
namespace MongoAuth
|
||||
{
|
||||
internal static class DatabaseConfig
|
||||
{
|
||||
public static string Host { get; private set; }
|
||||
public static int Port { get; private set; }
|
||||
public static string Database { get; private set; }
|
||||
|
||||
static DatabaseConfig()
|
||||
{
|
||||
Host = !string.IsNullOrEmpty(ConfigurationManager.AppSettings["data:MongoHost"]) ? ConfigurationManager.AppSettings["data:MongoHost"] : "localhost";
|
||||
|
||||
int _port;
|
||||
bool success = int.TryParse(ConfigurationManager.AppSettings["data:MongoPort"], out _port);
|
||||
if (!success)
|
||||
{
|
||||
_port = 27017; // mongo default port
|
||||
}
|
||||
Port = _port;
|
||||
|
||||
Database = !string.IsNullOrEmpty(ConfigurationManager.AppSettings["data:MongoDB"]) ? ConfigurationManager.AppSettings["data:MongoDB"] : "MongoAuth";
|
||||
}
|
||||
}
|
||||
}
|
73
MongoAuth/MongoAuth.csproj
Normal file
@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{7C67BFB9-1B3B-4676-A58D-10573DA82CFE}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>MongoAuth</RootNamespace>
|
||||
<AssemblyName>MongoAuth</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</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\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="MongoDB.Bson, Version=2.0.1.27, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\MongoDB.Bson.2.0.1\lib\net45\MongoDB.Bson.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="MongoDB.Driver, Version=2.0.1.27, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\MongoDB.Driver.2.0.1\lib\net45\MongoDB.Driver.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="MongoDB.Driver.Core, Version=2.0.1.27, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\MongoDB.Driver.Core.2.0.1\lib\net45\MongoDB.Driver.Core.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.configuration" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Web.ApplicationServices" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="DatabaseConfig.cs" />
|
||||
<Compile Include="MongoMembershipProvider.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="MongoRoleProvider.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- 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>
|
||||
-->
|
||||
</Project>
|
457
MongoAuth/MongoMembershipProvider.cs
Normal file
@ -0,0 +1,457 @@
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
using MongoDB.Driver;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Security;
|
||||
|
||||
namespace MongoAuth
|
||||
{
|
||||
public class MongoMembershipProvider : MembershipProvider
|
||||
{
|
||||
private const string _CollectionName = "members";
|
||||
|
||||
private bool _enablePasswordReset = true;
|
||||
private int _maxInvalidPasswordAttempts = 5;
|
||||
private int _minRequiredNonAlphanumericCharacters = 1;
|
||||
private int _minRequriedPasswordLength = 12;
|
||||
private int _passwordAttemptWindow = 60;
|
||||
private bool _requiresUniqueEmail = true;
|
||||
|
||||
private MongoClient _dbClient;
|
||||
|
||||
public override string ApplicationName { get; set; }
|
||||
|
||||
public override bool EnablePasswordReset
|
||||
{
|
||||
get { return _enablePasswordReset; }
|
||||
}
|
||||
|
||||
public override bool EnablePasswordRetrieval
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override int MaxInvalidPasswordAttempts
|
||||
{
|
||||
get { return _maxInvalidPasswordAttempts; }
|
||||
}
|
||||
|
||||
public override int MinRequiredNonAlphanumericCharacters
|
||||
{
|
||||
get { return _minRequiredNonAlphanumericCharacters; }
|
||||
}
|
||||
|
||||
public override int MinRequiredPasswordLength
|
||||
{
|
||||
get { return _minRequriedPasswordLength; }
|
||||
}
|
||||
|
||||
public override int PasswordAttemptWindow
|
||||
{
|
||||
get { return _passwordAttemptWindow; }
|
||||
}
|
||||
|
||||
public override MembershipPasswordFormat PasswordFormat
|
||||
{
|
||||
get { return MembershipPasswordFormat.Hashed; }
|
||||
}
|
||||
|
||||
public override string PasswordStrengthRegularExpression
|
||||
{
|
||||
get { return ""; }
|
||||
}
|
||||
|
||||
public override bool RequiresQuestionAndAnswer
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override bool RequiresUniqueEmail
|
||||
{
|
||||
get { return _requiresUniqueEmail; }
|
||||
}
|
||||
|
||||
public override void Initialize(string name, NameValueCollection config)
|
||||
{
|
||||
if (config == null)
|
||||
{
|
||||
throw new ArgumentNullException("config");
|
||||
}
|
||||
|
||||
base.Initialize(name, config);
|
||||
|
||||
_enablePasswordReset = tryReadBool(config["enablePasswordReset"], _enablePasswordReset);
|
||||
_maxInvalidPasswordAttempts = tryReadInt(config["maxInvalidPasswordAttempts"], _maxInvalidPasswordAttempts);
|
||||
_minRequiredNonAlphanumericCharacters = tryReadInt(config["minRequiredNonAlphanumericCharacters"], _minRequiredNonAlphanumericCharacters);
|
||||
_minRequriedPasswordLength = tryReadInt(config["minRequriedPasswordLength"], _minRequriedPasswordLength);
|
||||
_passwordAttemptWindow = tryReadInt(config["passwordAttemptWindow"], _passwordAttemptWindow);
|
||||
_requiresUniqueEmail = tryReadBool(config["requiresUniqueEmail"], _requiresUniqueEmail);
|
||||
|
||||
_dbClient = new MongoClient(new MongoClientSettings()
|
||||
{
|
||||
Server = new MongoServerAddress(DatabaseConfig.Host, DatabaseConfig.Port)
|
||||
});
|
||||
}
|
||||
|
||||
public override bool ChangePassword(string username, string oldPassword, string newPassword)
|
||||
{
|
||||
bool isAuthenticated = ValidateUser(username, oldPassword);
|
||||
|
||||
if (isAuthenticated)
|
||||
{
|
||||
var collection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoMember>(_CollectionName);
|
||||
|
||||
var mmTask = collection.Find(m => m.UserName.ToLower() == username.ToLower()).SingleOrDefaultAsync();
|
||||
mmTask.Wait();
|
||||
var mm = mmTask.Result;
|
||||
|
||||
if (mm == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
byte[] salt = new byte[24];
|
||||
byte[] hash = calculateHash(newPassword, ref salt);
|
||||
|
||||
mm.PassSalt = salt;
|
||||
mm.PassHash = hash;
|
||||
|
||||
var replaceTask = collection.ReplaceOneAsync(m => m.Id == mm.Id, mm);
|
||||
replaceTask.Wait();
|
||||
|
||||
if (replaceTask.IsCompleted)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
|
||||
{
|
||||
if (password.Length < MinRequiredPasswordLength)
|
||||
{
|
||||
status = MembershipCreateStatus.InvalidPassword;
|
||||
return null;
|
||||
}
|
||||
|
||||
MembershipUser mu = null;
|
||||
|
||||
var collection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoMember>(_CollectionName);
|
||||
|
||||
var dupeUsers = collection.Find(m => m.UserName.ToLower() == username.ToLower()).CountAsync();
|
||||
var dupeEmails = collection.Find(m => m.EmailAddress.ToLower() == email.ToLower()).CountAsync();
|
||||
|
||||
dupeUsers.Wait();
|
||||
dupeEmails.Wait();
|
||||
|
||||
if (dupeUsers.Result > 0)
|
||||
{
|
||||
status = MembershipCreateStatus.DuplicateUserName;
|
||||
}
|
||||
else if (dupeEmails.Result > 0)
|
||||
{
|
||||
status = MembershipCreateStatus.DuplicateEmail;
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] salt = new byte[24];
|
||||
byte[] hash = calculateHash(password, ref salt);
|
||||
|
||||
MongoMember mm = new MongoMember()
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
UserName = username,
|
||||
PassHash = hash,
|
||||
PassSalt = salt,
|
||||
EmailAddress = email,
|
||||
|
||||
IsApproved = false,
|
||||
IsLockedOut = false,
|
||||
|
||||
CreationDate = DateTime.Now,
|
||||
LastLoginDate = DateTime.MinValue,
|
||||
LastActivityDate = DateTime.MinValue,
|
||||
LastLockoutDate = DateTime.MinValue
|
||||
};
|
||||
|
||||
var insertTask = collection.InsertOneAsync(mm);
|
||||
insertTask.Wait();
|
||||
|
||||
if (insertTask.Status == TaskStatus.RanToCompletion)
|
||||
{
|
||||
|
||||
status = MembershipCreateStatus.Success;
|
||||
mu = new MembershipUser(this.Name, mm.UserName, mm.Id, mm.EmailAddress, "", "", mm.IsApproved, mm.IsLockedOut, mm.CreationDate, mm.LastLoginDate, mm.LastActivityDate, DateTime.MinValue, mm.LastLockoutDate);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MembershipCreateStatus.ProviderError;
|
||||
}
|
||||
}
|
||||
|
||||
return mu;
|
||||
}
|
||||
|
||||
public override bool DeleteUser(string username, bool deleteAllRelatedData)
|
||||
{
|
||||
var collection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoMember>(_CollectionName);
|
||||
|
||||
var deleteTask = collection.DeleteOneAsync(m => m.UserName.ToLower() == m.UserName.ToLower());
|
||||
deleteTask.Wait();
|
||||
|
||||
if (deleteTask.Result.IsAcknowledged && deleteTask.Result.DeletedCount == 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
|
||||
{
|
||||
MembershipUserCollection muc = new MembershipUserCollection();
|
||||
|
||||
var collection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoMember>(_CollectionName);
|
||||
|
||||
var users = collection.Find(new BsonDocument());
|
||||
|
||||
var totalRecordsTask = users.CountAsync();
|
||||
totalRecordsTask.Wait();
|
||||
totalRecords = Convert.ToInt32(totalRecordsTask.Result);
|
||||
|
||||
users = users.Skip(pageIndex * pageSize).Limit(pageSize);
|
||||
|
||||
var pageItemsTask = users.ToListAsync();
|
||||
pageItemsTask.Wait();
|
||||
|
||||
foreach (var mm in pageItemsTask.Result)
|
||||
{
|
||||
muc.Add(new MembershipUser(this.Name, mm.UserName, mm.Id, mm.EmailAddress, "", "", mm.IsApproved, mm.IsLockedOut, mm.CreationDate, mm.LastLoginDate, mm.LastActivityDate, DateTime.MinValue, mm.LastLockoutDate));
|
||||
}
|
||||
|
||||
return muc;
|
||||
|
||||
}
|
||||
|
||||
public override int GetNumberOfUsersOnline()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override string GetPassword(string username, string answer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override MembershipUser GetUser(string username, bool userIsOnline)
|
||||
{
|
||||
var collection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoMember>(_CollectionName);
|
||||
|
||||
var mmTask = collection.Find(f => f.UserName.ToLower() == username.ToLower()).FirstOrDefaultAsync();
|
||||
mmTask.Wait();
|
||||
|
||||
var mm = mmTask.Result;
|
||||
|
||||
return mm == null ? null : new MembershipUser(this.Name, mm.UserName, mm.Id, mm.EmailAddress, "", "", mm.IsApproved, mm.IsLockedOut, mm.CreationDate, mm.LastLoginDate, mm.LastActivityDate, DateTime.MinValue, mm.LastLockoutDate);
|
||||
}
|
||||
|
||||
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
|
||||
{
|
||||
var collection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoMember>(_CollectionName);
|
||||
|
||||
var mmTask = collection.Find(f => f.Id == (Guid)providerUserKey).FirstOrDefaultAsync();
|
||||
mmTask.Wait();
|
||||
|
||||
var mm = mmTask.Result;
|
||||
|
||||
return mm == null ? null : new MembershipUser(this.Name, mm.UserName, mm.Id, mm.EmailAddress, "", "", mm.IsApproved, mm.IsLockedOut, mm.CreationDate, mm.LastLoginDate, mm.LastActivityDate, DateTime.MinValue, mm.LastLockoutDate);
|
||||
}
|
||||
|
||||
public override string GetUserNameByEmail(string email)
|
||||
{
|
||||
var collection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoMember>(_CollectionName);
|
||||
|
||||
var mmTask = collection.Find(f => f.EmailAddress.ToLower() == email.ToLower()).FirstOrDefaultAsync();
|
||||
mmTask.Wait();
|
||||
|
||||
var mm = mmTask.Result;
|
||||
|
||||
return mm.UserName;
|
||||
}
|
||||
|
||||
public override string ResetPassword(string username, string answer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ChangeApproval(Guid Id, bool newStatus)
|
||||
{
|
||||
var collection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoMember>(_CollectionName);
|
||||
var task = collection.UpdateOneAsync(
|
||||
Builders<MongoMember>.Filter.Eq(u => u.Id, Id),
|
||||
Builders<MongoMember>.Update.Set(u => u.IsApproved, newStatus)
|
||||
);
|
||||
task.Wait();
|
||||
}
|
||||
|
||||
public void ChangeLockStatus(Guid Id, bool newStatus)
|
||||
{
|
||||
var collection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoMember>(_CollectionName);
|
||||
|
||||
|
||||
var updateDefinition = new List<UpdateDefinition<MongoMember>>();
|
||||
updateDefinition.Add(Builders<MongoMember>.Update.Set(u => u.IsLockedOut, newStatus));
|
||||
|
||||
if (newStatus)
|
||||
{
|
||||
updateDefinition.Add(Builders<MongoMember>.Update.Set(u => u.LastLockoutDate, DateTime.Now));
|
||||
}
|
||||
else
|
||||
{
|
||||
updateDefinition.Add(Builders<MongoMember>.Update.Set(u => u.LockoutWindowAttempts, 0));
|
||||
updateDefinition.Add(Builders<MongoMember>.Update.Set(u => u.LastLockoutDate, DateTime.MinValue));
|
||||
}
|
||||
|
||||
var task = collection.UpdateOneAsync(
|
||||
Builders<MongoMember>.Filter.Eq(u => u.Id, Id),
|
||||
Builders<MongoMember>.Update.Combine(updateDefinition)
|
||||
);
|
||||
task.Wait();
|
||||
}
|
||||
|
||||
public override bool UnlockUser(string userName)
|
||||
{
|
||||
var collection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoMember>(_CollectionName);
|
||||
var updTask = collection.UpdateOneAsync(Builders<MongoMember>.Filter.Eq(m => m.UserName.ToLower(), userName.ToLower()), Builders<MongoMember>.Update.Set(m => m.IsLockedOut, false));
|
||||
|
||||
updTask.Wait();
|
||||
|
||||
return updTask.Result.IsAcknowledged && updTask.Result.ModifiedCount == 1;
|
||||
}
|
||||
|
||||
public override void UpdateUser(MembershipUser user)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool ValidateUser(string username, string password)
|
||||
{
|
||||
var collection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoMember>(_CollectionName);
|
||||
|
||||
var mmTask = collection.Find(f => f.UserName.ToLower() == username.ToLower()).FirstOrDefaultAsync();
|
||||
mmTask.Wait();
|
||||
|
||||
var mm = mmTask.Result;
|
||||
|
||||
|
||||
if (mm == null || !(mm.IsApproved && !mm.IsLockedOut))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
byte[] salt = mm.PassSalt;
|
||||
byte[] hash = calculateHash(password, ref salt);
|
||||
|
||||
bool isFail = false;
|
||||
|
||||
for (int i = 0; i > hash.Length; i++)
|
||||
{
|
||||
isFail |= (hash[i] != mm.PassHash[i]);
|
||||
}
|
||||
|
||||
if (isFail)
|
||||
{
|
||||
// increment failed counter and lock out if required.
|
||||
}
|
||||
else
|
||||
{
|
||||
// reset failed counter
|
||||
}
|
||||
|
||||
return !isFail;
|
||||
}
|
||||
|
||||
private static byte[] calculateHash(string password, ref byte[] salt)
|
||||
{
|
||||
if (!salt.Any(v => v != 0))
|
||||
{
|
||||
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
|
||||
rng.GetBytes(salt);
|
||||
}
|
||||
|
||||
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
|
||||
|
||||
byte[] hashPlaintext = new byte[salt.Length + passwordBytes.Length];
|
||||
|
||||
passwordBytes.CopyTo(hashPlaintext, 0);
|
||||
salt.CopyTo(hashPlaintext, passwordBytes.Length);
|
||||
|
||||
SHA512CryptoServiceProvider sha = new SHA512CryptoServiceProvider();
|
||||
byte[] hash = sha.ComputeHash(hashPlaintext);
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
private static bool tryReadBool(string config, bool defaultValue)
|
||||
{
|
||||
bool temp = false;
|
||||
bool success = bool.TryParse(config, out temp);
|
||||
return success ? temp : defaultValue;
|
||||
}
|
||||
|
||||
private static int tryReadInt(string config, int defaultValue)
|
||||
{
|
||||
int temp = 0;
|
||||
bool success = int.TryParse(config, out temp);
|
||||
return success ? temp : defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public class MongoMember
|
||||
{
|
||||
[BsonId]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
public string UserName { get; set; }
|
||||
public byte[] PassHash { get; set; }
|
||||
public byte[] PassSalt { get; set; }
|
||||
public string EmailAddress { get; set; }
|
||||
|
||||
public bool IsApproved { get; set; }
|
||||
public bool IsLockedOut { get; set; }
|
||||
|
||||
public DateTime CreationDate { get; set; }
|
||||
public DateTime LastActivityDate { get; set; }
|
||||
public DateTime LastLockoutDate { get; set; }
|
||||
public DateTime LastLoginDate { get; set; }
|
||||
|
||||
public DateTime LockoutWindowStart { get; set; }
|
||||
public int LockoutWindowAttempts { get; set; }
|
||||
}
|
||||
|
||||
}
|
247
MongoAuth/MongoRoleProvider.cs
Normal file
@ -0,0 +1,247 @@
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
using MongoDB.Driver;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Web.Security;
|
||||
using System.Collections.Specialized;
|
||||
|
||||
namespace MongoAuth
|
||||
{
|
||||
public class MongoRoleProvider : RoleProvider
|
||||
{
|
||||
private const string _RoleCollectionName = "roles";
|
||||
private const string _MemberCollectionName = "members";
|
||||
private MongoClient _dbClient;
|
||||
|
||||
public override string ApplicationName
|
||||
{
|
||||
get { return ""; }
|
||||
set { }
|
||||
}
|
||||
|
||||
public override void Initialize(string name, NameValueCollection config)
|
||||
{
|
||||
base.Initialize(name, config);
|
||||
|
||||
_dbClient = new MongoClient(new MongoClientSettings()
|
||||
{
|
||||
Server = new MongoServerAddress(DatabaseConfig.Host, DatabaseConfig.Port)
|
||||
});
|
||||
}
|
||||
|
||||
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
|
||||
{
|
||||
var roleCollection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoRole>(_RoleCollectionName);
|
||||
var memberCollection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoMember>(_MemberCollectionName);
|
||||
|
||||
var roleTask = roleCollection.Find(r => roleNames.Contains(r.RoleName)).ToListAsync();
|
||||
roleTask.Wait();
|
||||
List<MongoRole> roles = roleTask.Result;
|
||||
|
||||
var userTask = memberCollection.Find(u => usernames.Contains(u.UserName)).ToListAsync();
|
||||
userTask.Wait();
|
||||
List<MongoMember> users = userTask.Result;
|
||||
|
||||
for (int i = 0; i < roles.Count; i++)
|
||||
{
|
||||
List<Guid> newUsers = new List<Guid>();
|
||||
|
||||
if (roles[i].Users != null)
|
||||
{
|
||||
newUsers.AddRange(roles[i].Users);
|
||||
}
|
||||
|
||||
var usersToAdd = from u in users
|
||||
where !newUsers.Any(v => v == u.Id)
|
||||
select u.Id;
|
||||
|
||||
newUsers.AddRange(usersToAdd);
|
||||
|
||||
roles[i].Users = newUsers.ToArray();
|
||||
|
||||
var update = roleCollection.ReplaceOneAsync(Builders<MongoRole>.Filter.Eq(r => r.Id, roles[i].Id), roles[i]);
|
||||
update.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
public override void CreateRole(string roleName)
|
||||
{
|
||||
var roleCollection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoRole>(_RoleCollectionName);
|
||||
|
||||
MongoRole r = new MongoRole()
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
RoleName = roleName
|
||||
};
|
||||
|
||||
var task = roleCollection.InsertOneAsync(r);
|
||||
task.Wait();
|
||||
}
|
||||
|
||||
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
|
||||
{
|
||||
var roleCollection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoRole>(_RoleCollectionName);
|
||||
|
||||
var role = roleCollection.Find(r => r.RoleName == roleName).SingleOrDefaultAsync();
|
||||
role.Wait();
|
||||
|
||||
if (role.Result != null && role.Result.Users.Length > 0 && throwOnPopulatedRole)
|
||||
{
|
||||
throw new Exception("This role still has users");
|
||||
}
|
||||
|
||||
roleCollection.DeleteOneAsync(r => r.RoleName == roleName);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string[] FindUsersInRole(string roleName, string usernameToMatch)
|
||||
{
|
||||
var roleCollection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoRole>(_RoleCollectionName);
|
||||
var memberCollection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoMember>(_MemberCollectionName);
|
||||
|
||||
var role = roleCollection.Find(r => r.RoleName == roleName).SingleOrDefaultAsync();
|
||||
role.Wait();
|
||||
|
||||
if (role == null)
|
||||
{
|
||||
throw new Exception("Role does not exist");
|
||||
}
|
||||
|
||||
var users = memberCollection.Find(u => role.Result.Users.Contains(u.Id) && u.UserName.ToLower().Contains(usernameToMatch.ToLower())).ToListAsync();
|
||||
users.Wait();
|
||||
|
||||
return users.Result
|
||||
.Select(r => r.UserName)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
public override string[] GetAllRoles()
|
||||
{
|
||||
var roleCollection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoRole>(_RoleCollectionName);
|
||||
var roles = roleCollection.Find(new BsonDocument()).ToListAsync();
|
||||
roles.Wait();
|
||||
return roles.Result
|
||||
.Select(r => r.RoleName)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
public override string[] GetRolesForUser(string username)
|
||||
{
|
||||
var roleCollection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoRole>(_RoleCollectionName);
|
||||
var memberCollection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoMember>(_MemberCollectionName);
|
||||
|
||||
var user = memberCollection.Find(u => u.UserName.ToLower() == username.ToLower()).SingleOrDefaultAsync();
|
||||
user.Wait();
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
throw new Exception("User does not exist");
|
||||
}
|
||||
|
||||
var role = roleCollection.Find(new BsonDocument()).ToListAsync();
|
||||
role.Wait();
|
||||
|
||||
return (from r in role.Result
|
||||
where r.Users != null
|
||||
where r.Users.Any(u => u == user.Result.Id)
|
||||
select r.RoleName).ToArray();
|
||||
}
|
||||
|
||||
public override string[] GetUsersInRole(string roleName)
|
||||
{
|
||||
var roleCollection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoRole>(_RoleCollectionName);
|
||||
var memberCollection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoMember>(_MemberCollectionName);
|
||||
|
||||
var role = roleCollection.Find(r => r.RoleName == roleName).SingleOrDefaultAsync();
|
||||
role.Wait();
|
||||
|
||||
if (role == null)
|
||||
{
|
||||
throw new Exception("Role does not exist");
|
||||
}
|
||||
|
||||
var users = memberCollection.Find(u => role.Result.Users.Contains(u.Id)).ToListAsync();
|
||||
users.Wait();
|
||||
|
||||
return users.Result
|
||||
.Select(u => u.UserName)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
public override bool IsUserInRole(string username, string roleName)
|
||||
{
|
||||
var roleCollection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoRole>(_RoleCollectionName);
|
||||
var memberCollection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoMember>(_MemberCollectionName);
|
||||
|
||||
var user = memberCollection.Find(u => u.UserName.ToLower() == username.ToLower()).SingleOrDefaultAsync();
|
||||
user.Wait();
|
||||
|
||||
if (user.Result == null)
|
||||
{
|
||||
throw new Exception("User does not exist");
|
||||
}
|
||||
|
||||
var role = roleCollection.Find(r => r.RoleName == roleName).SingleOrDefaultAsync();
|
||||
|
||||
if (role.Result == null)
|
||||
{
|
||||
throw new Exception("Role does not exist");
|
||||
}
|
||||
|
||||
if (role.Result.Users == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return role.Result.Users.Any(u => u == user.Result.Id);
|
||||
}
|
||||
|
||||
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
|
||||
{
|
||||
var roleCollection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoRole>(_RoleCollectionName);
|
||||
var memberCollection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoMember>(_MemberCollectionName);
|
||||
|
||||
var roleTask = roleCollection.Find(r => roleNames.Any(n => n == r.RoleName)).ToListAsync();
|
||||
roleTask.Wait();
|
||||
List<MongoRole> roles = roleTask.Result;
|
||||
|
||||
var userTask = memberCollection.Find(u => usernames.Any(n => n == u.UserName)).ToListAsync();
|
||||
userTask.Wait();
|
||||
List<MongoMember> users = userTask.Result;
|
||||
|
||||
for (int i = 0; i < roles.Count; i++)
|
||||
{
|
||||
roles[i].Users = (from u in roles[i].Users
|
||||
where !users.Any(v => v.Id == u)
|
||||
select u).ToArray();
|
||||
|
||||
var update = roleCollection.ReplaceOneAsync(Builders<MongoRole>.Filter.Eq(r => r.Id, roles[i].Id), roles[i]);
|
||||
update.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool RoleExists(string roleName)
|
||||
{
|
||||
var roleCollection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoRole>(_RoleCollectionName);
|
||||
|
||||
var role = roleCollection.Find(r => r.RoleName == roleName).SingleOrDefaultAsync();
|
||||
role.Wait();
|
||||
|
||||
return role.Result != null;
|
||||
}
|
||||
}
|
||||
|
||||
[DataObject]
|
||||
public class MongoRole
|
||||
{
|
||||
[BsonId]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
public string RoleName { get; set; }
|
||||
|
||||
public Guid[] Users { get; set; }
|
||||
}
|
||||
}
|
36
MongoAuth/Properties/AssemblyInfo.cs
Normal file
@ -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("MongoAuth")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("MongoAuth")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2015")]
|
||||
[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("7c67bfb9-1b3b-4676-a58d-10573da82cfe")]
|
||||
|
||||
// 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")]
|
6
MongoAuth/packages.config
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="MongoDB.Bson" version="2.0.1" targetFramework="net452" />
|
||||
<package id="MongoDB.Driver" version="2.0.1" targetFramework="net452" />
|
||||
<package id="MongoDB.Driver.Core" version="2.0.1" targetFramework="net452" />
|
||||
</packages>
|