From e4c5c3cc23da48f836ffac1ae79cbc2ae287bf68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20M=C3=A1t=C3=A9?= Date: Fri, 8 Dec 2023 18:30:30 +0100 Subject: [PATCH 01/16] Creating skeleton for the OC version --- .gitattributes | 9 +- ...e-jira-issues-for-community-activities.yml | 24 +++ .github/workflows/publish-nuget.yml | 13 ++ .github/workflows/validate-pull-request.yml | 9 + .gitignore | 10 + .hgignore | 4 - AdminMenu.cs | 25 --- Controllers/AdminController.cs | 59 ------ Licence.md => License.md | 26 ++- Lombiq.LoginAsAnybody.csproj | 172 ------------------ Lombiq.LoginAsAnybody.sln | 25 +++ Lombiq.LoginAsAnybody/FeatureIds.cs | 8 + Lombiq.LoginAsAnybody/License.md | 13 ++ .../Lombiq.LoginAsAnybody.csproj | 45 +++++ Lombiq.LoginAsAnybody/Manifest.cs | 21 +++ Lombiq.LoginAsAnybody/NuGetIcon.png | Bin 0 -> 4657 bytes Module.txt | 12 -- Properties/AssemblyInfo.cs | 37 ---- Readme.md | 15 +- Views/Admin/Index.cshtml | 15 -- Web.config | 59 ------ packages.config | 7 - 22 files changed, 195 insertions(+), 413 deletions(-) create mode 100644 .github/workflows/create-jira-issues-for-community-activities.yml create mode 100644 .github/workflows/publish-nuget.yml create mode 100644 .github/workflows/validate-pull-request.yml delete mode 100644 .hgignore delete mode 100644 AdminMenu.cs delete mode 100644 Controllers/AdminController.cs rename Licence.md => License.md (76%) delete mode 100644 Lombiq.LoginAsAnybody.csproj create mode 100644 Lombiq.LoginAsAnybody.sln create mode 100644 Lombiq.LoginAsAnybody/FeatureIds.cs create mode 100644 Lombiq.LoginAsAnybody/License.md create mode 100644 Lombiq.LoginAsAnybody/Lombiq.LoginAsAnybody.csproj create mode 100644 Lombiq.LoginAsAnybody/Manifest.cs create mode 100644 Lombiq.LoginAsAnybody/NuGetIcon.png delete mode 100644 Module.txt delete mode 100644 Properties/AssemblyInfo.cs delete mode 100644 Views/Admin/Index.cshtml delete mode 100644 Web.config delete mode 100644 packages.config diff --git a/.gitattributes b/.gitattributes index d7c444c..9aa44dd 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,8 @@ -* -crlf \ No newline at end of file +* text=auto + +# Enforce Windows newlines for C# files to avoid false positives with IDE0055 warning. +# See https://github.com/Lombiq/Open-Source-Orchard-Core-Extensions/issues/106 for more information. +*.cs text eol=crlf + +# Keep LF line endings in pnpm-lock.yaml files to prevent Git from reporting this file as changed after pnpm touches it. +pnpm-lock.yaml text eol=lf \ No newline at end of file diff --git a/.github/workflows/create-jira-issues-for-community-activities.yml b/.github/workflows/create-jira-issues-for-community-activities.yml new file mode 100644 index 0000000..bd9d695 --- /dev/null +++ b/.github/workflows/create-jira-issues-for-community-activities.yml @@ -0,0 +1,24 @@ +name: Create Jira issues for community activities + +on: + discussion: + types: [created] + issues: + types: [opened] + pull_request_target: + types: [opened] + +jobs: + create-jira-issues-for-community-activities: + name: Create Jira issues for community activities + uses: Lombiq/GitHub-Actions/.github/workflows/create-jira-issues-for-community-activities.yml@dev + secrets: + JIRA_BASE_URL: ${{ secrets.DEFAULT_JIRA_BASE_URL }} + JIRA_USER_EMAIL: ${{ secrets.DEFAULT_JIRA_USER_EMAIL }} + JIRA_API_TOKEN: ${{ secrets.DEFAULT_JIRA_API_TOKEN }} + JIRA_PROJECT_KEY: ${{ secrets.DEFAULT_JIRA_PROJECT_KEY }} + DISCUSSION_JIRA_ISSUE_DESCRIPTION: ${{ secrets.DEFAULT_DISCUSSION_JIRA_ISSUE_DESCRIPTION }} + ISSUE_JIRA_ISSUE_DESCRIPTION: ${{ secrets.DEFAULT_ISSUE_JIRA_ISSUE_DESCRIPTION }} + PULL_REQUEST_JIRA_ISSUE_DESCRIPTION: ${{ secrets.DEFAULT_PULL_REQUEST_JIRA_ISSUE_DESCRIPTION }} + with: + issue-component: Lombiq.MyProject \ No newline at end of file diff --git a/.github/workflows/publish-nuget.yml b/.github/workflows/publish-nuget.yml new file mode 100644 index 0000000..6d69e55 --- /dev/null +++ b/.github/workflows/publish-nuget.yml @@ -0,0 +1,13 @@ +name: Publish to NuGet + +on: + push: + tags: + - v* + +jobs: + publish-nuget: + name: Publish to NuGet + uses: Lombiq/GitHub-Actions/.github/workflows/publish-nuget.yml@dev + secrets: + API_KEY: ${{ secrets.DEFAULT_NUGET_PUBLISH_API_KEY }} \ No newline at end of file diff --git a/.github/workflows/validate-pull-request.yml b/.github/workflows/validate-pull-request.yml new file mode 100644 index 0000000..9e05214 --- /dev/null +++ b/.github/workflows/validate-pull-request.yml @@ -0,0 +1,9 @@ +name: Validate Pull Request + +on: + pull_request: + +jobs: + validate-pull-request: + name: Validate Pull Request + uses: Lombiq/GitHub-Actions/.github/workflows/validate-submodule-pull-request.yml@dev \ No newline at end of file diff --git a/.gitignore b/.gitignore index 9bce83a..d091319 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,13 @@ +.vs/ +.idea/ +.vscode/ obj/ bin/ +artifacts/ +wwwroot/ +node_modules/ *.user +.pnpm-debug.log + +# Mac +.DS_Store \ No newline at end of file diff --git a/.hgignore b/.hgignore deleted file mode 100644 index 9b9a60f..0000000 --- a/.hgignore +++ /dev/null @@ -1,4 +0,0 @@ -syntax: glob -bin/ -obj/ -*.user diff --git a/AdminMenu.cs b/AdminMenu.cs deleted file mode 100644 index bd06ea9..0000000 --- a/AdminMenu.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using Orchard.Localization; -using Orchard.Security; -using Orchard.UI.Navigation; - -namespace Lombiq.LoginAsAnybody -{ - public class AdminMenu : INavigationProvider - { - public Localizer T { get; set; } - public string MenuName { get { return "admin"; } } - - public void GetNavigation(NavigationBuilder builder) - { - builder - .Add(T("Users"), "11", - menu => menu - .Add(T("Login as anybody"), "5.0", item => item.Action("Index", "Admin", new { area = "Lombiq.LoginAsAnybody" }) - .LocalNav().Permission(StandardPermissions.SiteOwner))); - } - } -} \ No newline at end of file diff --git a/Controllers/AdminController.cs b/Controllers/AdminController.cs deleted file mode 100644 index 0ac2e1e..0000000 --- a/Controllers/AdminController.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using System.Web.Mvc; -using Orchard.Security; -using Orchard.Mvc.Extensions; -using Orchard.UI.Admin; -using Orchard.Users.Events; - -namespace Lombiq.LoginAsAnybody.Controllers -{ - [Admin] - public class AdminController : Controller - { - private readonly IAuthorizer _authorizer; - private readonly IMembershipService _membershipService; - private readonly IAuthenticationService _authenticationService; - // Orchard.Users is not a dependency in the module manifest because it needn't be turned on. - private readonly IUserEventHandler _userEventHandler; - - - public AdminController( - IAuthorizer authorizer, - IMembershipService membershipService, - IAuthenticationService authenticationService, - IUserEventHandler userEventHandler) - { - _authorizer = authorizer; - _membershipService = membershipService; - _authenticationService = authenticationService; - _userEventHandler = userEventHandler; - } - - - public ActionResult Index() - { - return View(); - } - - [HttpPost] - public ActionResult Index(string userName, string returnUrl = null) - { - if (!_authorizer.Authorize(StandardPermissions.SiteOwner)) return new HttpUnauthorizedResult(); - - var user = _membershipService.GetUser(userName); - - if (user == null) return HttpNotFound(); - - _authenticationService.SignIn(user, false); - - _userEventHandler.LoggedIn(user); - - if (string.IsNullOrEmpty(returnUrl)) returnUrl = "~/"; - - return this.RedirectLocal(returnUrl); - } - } -} \ No newline at end of file diff --git a/Licence.md b/License.md similarity index 76% rename from Licence.md rename to License.md index 3a36cf4..53b7c51 100644 --- a/Licence.md +++ b/License.md @@ -1,15 +1,13 @@ -Copyright © 2015, [Lombiq Technologies Ltd.](https://lombiq.com) - -All rights reserved. - -For more information and requests about licensing please [contact us through our website](https://lombiq.com/contact-us). - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -* Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - +Copyright © 2023, [Lombiq Technologies Ltd.](https://lombiq.com) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +- Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/Lombiq.LoginAsAnybody.csproj b/Lombiq.LoginAsAnybody.csproj deleted file mode 100644 index 150fc6d..0000000 --- a/Lombiq.LoginAsAnybody.csproj +++ /dev/null @@ -1,172 +0,0 @@ - - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {6858714C-450F-4E3C-A49B-729716138E28} - {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} - Library - Properties - Lombiq.LoginAsAnybody - Lombiq.LoginAsAnybody - v4.5.2 - true - - - 4.0 - - - false - - - - - - - - true - full - false - bin\ - DEBUG;TRACE - prompt - 4 - ..\..\..\OrchardBasicCorrectness.ruleset - false - - - pdbonly - true - bin\ - TRACE - prompt - 4 - AllRules.ruleset - false - - - - - - - 3.5 - - - - - - - - - - - ..\..\..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll - True - - - ..\..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll - True - - - ..\..\..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll - True - - - ..\..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll - True - - - ..\..\..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll - True - - - ..\..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll - True - - - ..\..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll - True - - - - - - - - - - {2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6} - Orchard.Framework - false - - - {9916839C-39FC-4CEB-A5AF-89CA7E87119F} - Orchard.Core - false - - - {79aed36e-abd0-4747-93d3-8722b042454b} - Orchard.Users - - - - - - - - - - - - - - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - - - - $(ProjectDir)\..\Manifests - - - - - - - - - - - - False - True - 45979 - / - - - False - True - http://orchard.codeplex.com - False - - - - - - - - \ No newline at end of file diff --git a/Lombiq.LoginAsAnybody.sln b/Lombiq.LoginAsAnybody.sln new file mode 100644 index 0000000..237c081 --- /dev/null +++ b/Lombiq.LoginAsAnybody.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34322.80 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lombiq.LoginAsAnybody", "Lombiq.LoginAsAnybody.csproj", "{D35DE919-3D8A-494C-8A33-B272D61C9956}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D35DE919-3D8A-494C-8A33-B272D61C9956}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D35DE919-3D8A-494C-8A33-B272D61C9956}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D35DE919-3D8A-494C-8A33-B272D61C9956}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D35DE919-3D8A-494C-8A33-B272D61C9956}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {882A318E-192C-4671-8397-4D6B5030D0EB} + EndGlobalSection +EndGlobal diff --git a/Lombiq.LoginAsAnybody/FeatureIds.cs b/Lombiq.LoginAsAnybody/FeatureIds.cs new file mode 100644 index 0000000..61536a1 --- /dev/null +++ b/Lombiq.LoginAsAnybody/FeatureIds.cs @@ -0,0 +1,8 @@ +namespace Lombiq.LoginAsAnybody; + +public static class FeatureIds +{ + public const string Area = "Lombiq.LoginAsAnybody"; + + public const string Default = Area; +} diff --git a/Lombiq.LoginAsAnybody/License.md b/Lombiq.LoginAsAnybody/License.md new file mode 100644 index 0000000..afc7cc7 --- /dev/null +++ b/Lombiq.LoginAsAnybody/License.md @@ -0,0 +1,13 @@ +Copyright © 2023, [Lombiq Technologies Ltd.](https://lombiq.com) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +- Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/Lombiq.LoginAsAnybody/Lombiq.LoginAsAnybody.csproj b/Lombiq.LoginAsAnybody/Lombiq.LoginAsAnybody.csproj new file mode 100644 index 0000000..d4f2db8 --- /dev/null +++ b/Lombiq.LoginAsAnybody/Lombiq.LoginAsAnybody.csproj @@ -0,0 +1,45 @@ + + + + net6.0 + true + $(DefaultItemExcludes);.git*;node_modules\**;Tests\** + + + + Lombiq Login as Anybody for Orchard Core + Lombiq Technologies + Copyright © 2023, Lombiq Technologies Ltd. + Lombiq Login as Anybody for Orchard Core: An Orchard Core module that allows administrators to log in as any user. + NuGetIcon.png + OrchardCore;Lombiq;AspNetCore + https://github.com/Lombiq/Orchard-Login-as-Anybody + https://github.com/Lombiq/Orchard-Login-as-Anybody + License.md + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Lombiq.LoginAsAnybody/Manifest.cs b/Lombiq.LoginAsAnybody/Manifest.cs new file mode 100644 index 0000000..401081a --- /dev/null +++ b/Lombiq.LoginAsAnybody/Manifest.cs @@ -0,0 +1,21 @@ +using OrchardCore.Modules.Manifest; +using static Lombiq.LoginAsAnybody.FeatureIds; + +[assembly: Module( + Name = "Lombiq Login as Anybody", + Author = "Lombiq Technologies", + Version = "0.0.1", + Description = "Module that allows administrators to log in as any user.", + Website = "https://github.com/Lombiq/Orchard-Login-as-Anybody" +)] + +[assembly: Feature( + Id = Default, + Name = "Lombiq Login as Anybody", + Category = "Security", + Description = "Module that allows administrators to log in as any user.", + Dependencies = new[] + { + "OrchardCore.Users", + } +)] \ No newline at end of file diff --git a/Lombiq.LoginAsAnybody/NuGetIcon.png b/Lombiq.LoginAsAnybody/NuGetIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..162a00508d8041833604d427216238c1b23b2d47 GIT binary patch literal 4657 zcmV-163*?3P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!Thn=~eB5))%gn$#O#QK7n$s4=L-h!O=vF^a;>Ff(Vme>2-ILt$p`^By>#th3Jf zo%mwTcYcq(e|sM=Ffi!HnCMv&IXStx>whD37Ty5YY(6YhyZU* z`lOOYjz@!+Y#0L27(o!^cm}spNxZ;7dL0%+0GcCv2#O=eyx?Vc`gIPV2NX&{?xE+f z^lJ~Gha`}M044qbL+Cjyh5$6L0{q&ILJ^D{pl{-(=dc(#fX0vrAa*1$6xZoFEQSZr z7(wvK@eI17ssIcRAOVts$TB0_jdpqtOTYI3UN3XFj3f*Ju%dMh;Pd&EP@s_mL<&Rz zN`wG)1dx-Hi@zU-9u4$`Y9Szs9MQo`12K>gq(l@_Ed*c%po9zSHwZo@h5^*`01;mT z`ZTTr{2)t5P^2*{ z(gugaA-4-MJOC@WCeUuzc2!$!Tr9nk4OKlrL<=A$CPveRp~&DtgXxuQsOkYCIs_yq zi&{?^z~AA7u04mq{oY>iHJqn+`58HKgxn#(@Bplg966F+@!_re3a*ts4jq4d89JYP z9onnbLFfOxj>C%dSFkgE`n~i@HjEsAm1)zb(JOZRolfXjw;uf0ZqPdf^4#6;?gjV% z*U%g6Oqw*&Muh00rW_a^fQ3PW2Eoi3GpNOmYs&{9eADxn%=PE(0fF#fA}n9NT+Rsz zbv!^$PAKcLm^UY6aK!J=FSVgm12cYx7^I#ZE!NeYVupRJo=lRr3H? zKy$4{*9(~ZJ^0`Q)MCfEVJmLwL9L!~y}JhlA`~9XX0xfHqCze&pqc=%6)fU5hC)h8 zN+3F#uaU{~X&rd}cAQ!v@c5u}JrN2gd3pER#*ZH_M=qdR5*U#sU|L!l+<*TZYBA#T zfs^B*dJY{A2!;oe3c%X6k6=n5)f1>DfQU-~@k4&(k!l=&r+3(JzrPQBjV;t-BOn;g zUW1H`3~OOwq10SJwGa?-0+=;x7AdDH$H1CrGW$J@o54 zdjZ@Z9H16IC>-a;9n@lH$&$sEl#~>)p}-J8cZLri4vQ8oq!v4!FT6=qAZ@xH1%yK4 zAu1}$OhSQ}WY9&9uHYpb{UQWZRjuJ3^yxZy1iVMBmOMCLd^;d49`3wzf-OHkkLNdWRRBnz7Qp=Z^I`PpQPg5X zXuAroH~va3`9MLTuz0DgtTfqdHr7N$RS%%+93UYf0ZK|%Qi~nu%kO~S$=p`Y1qurV z#>3E|L#+!IEMSf6h6lJwX=y3M$Mb2_d#VAtb|0pe{GhNOXG>Zs~8~_gd-5!`6aMlE#+CYv~L$Id; z=GCiLbx#KSR|vq>y%iPZ)M7_WtCrGW=MV~$hgq{`Su-;;Z_Qv;6M!y40JeDz9?ZAA z+Sk|&?)N{YmVWTJ6R$*s$pZ;{CK~?G6X3zE>WK9K!-frm;^IZrVkgk9E&6r6%7Vf~ zf$}hZe3otI%o&&q;HVOJJsYtCShI$|&CC0FJ$ODnK`k9Zgo$0qysTcm+C)B!>%8q? zNJI)CJ3AYfQc;T?&tZn8T^i&4q>jWXzUO$`ZMRuVOH1%|^4vsR4uG?KxVlFSzGl8r zH!bkHxUfnSdjEAUs`P9-M=0OP%H8+o1 z+^FUOu=wVica=z9ULGm^rcg^7jvvnjYt|TQ=?9bD3b8+30Vd8V?ORYy02qYj-rTTP z#I||$ip>gfkF5gxy?lLxN@7k0Jp?*a&jLf zr{4rE`Eih#zh(0#(R=x~IIlp>r4!KD(F$I{2g%V1aA)FZm_QCu9>wDY*VdijdUGfE zUF^%oZFhYa9OVm%fWAZT@Nu!z4WD0b51a)*KvJ{~?nsJ*F$q0}C+r4_AwM7AQX_&G z0sN7i{w-+9PkDK{sLa2qvkjg-^)Bpd{hWMY_<4Mr^Z~=*;q*B$HCfy@5qk*TAJu~A zz-Qq7vJraf;x!LW2vipKSve%j7dK;x5B#mu&2aeQ)gIp}ojSk)3(|%{)}U|g(~Vn{ z4a9P);O|Nlx`W$Ti0vxA;vt^ngLAF$^Zh4aN5e(#hmUMK(-QC;1W^?LqKhg(Y@64fmZR|5m9MD9 zkIyf__Vcw+{P7d;{HYyq-6L*GSRODx+23>p{`0^|*izpFH^RJsAQUdI09#4EKoC^{ zAiD4XMMXup>Xlk-boo5+3`zRrz)k+FjSahC(Z1ioYiD)^Y$f=t^&0%D<`iuBq7m9$ zTpN1!%7Nx9aO`q>caw-+k=C%3k9%v>dpPaONobYV@4p>Y)!bi<~8#{*L{BSzO8=-{r@LW23?v&YVgRxFnQNCJrYldK^C-`;^+y76$C#Oznj@b9_DN-O#E zA3OR=AV2W>r7a>kNWP)JIaCi{UgcZ%#RJJ7_})}?3%nixw}z2zc1CQQ*Yo6C>h#Iu zLPLT1!DC1M9LN>Ku>0%Fu>N=>N%+E-brMl636%9cLDkh&+^=q}yLt{jZ2FX1%Cq<4 z=kUzQ?bKoiNAWhEI^W}9jsmDA0NLU{Zs3d?IrHEr|NZI2w!m3U-Z-}p4qZM;t?*!G zzn&y|%75|yf#{{qng{?#`fv+(UjEwj34C$w9JSN~pW~A!-ewL3?|jt)?Oo!_I}xbn z0c1%4@#PKp5(gffJ~ye=wcFI8vEvf#ZaG4&-oXdI_kz4TjWZBAApl?5itGA$d6i`S zm)z=)*xkyG^M9jPy;DQ7eif3wZ$U~k)y4rN3jo`^@C8mh;1utshP~9%jw4sjK!-PU z9e?DK=r5yah}={YfTR$RnVBi7%?qb_-GVZsb3EXfKz;jpYW*`fDAUlc{BUv)=syHt zGX}2iF`N1R$|G04BC%Jyz5Kd!p|kf@*w?x|q9%2u5)mPwpr8P^Gocn60?E3cI*DbU zeh4)HrNzTXbRPm74hO7SwTfEoyhoC*`gXoot|^Vp)cZJ?RqZBLirJ*|5U_07Qb5EVvz^aV^I$kQ6D0<3LQ4cVA z@?=qMUQeHV2RwqbX;`JOn|t>FR#M?;AOX<{AflK6u+0nK-Gk*H4>;*^;8Gp6^hYQU zfIq1QVL;NzlVTxY-n@B`mNu4JZ20^>_;2#<*E696fS?yp8Ff5BPEIb?KTKQ0V4GK2 zSt+&H+17Xv8g5*qmOcrU1R@$#0;+`o=Jy1xT=@_T9LTpwqP?pFHk{^vhmP7rg~$OA zoBCq`s)Yci_&;jYD0tw32dKr)hSMKFy9#aDQn7^z0e#s6FbP0Rn^(j2X4v+14Yl-5 z*bvZ%lfbYE;IwJeVCvMV)MDo;lK6>jyi}X0a2`N?0qDa6*ladYZC?9ZkHg`%dTQyP za8-b-2)21u zbGLcjWSoRuI@DxZawe?Je2`kY|Ev_cpZ#XZBU z8qpRzl&8;uCnh}Rs9 zN??l;(X_eSVawS)aN^q6x)}?Iu|&aLNn>Enuxv<@C{SD@aJc0gIC8liuDLyO_c!{R zJKV`n&loRyC5mVPl$Di<%KQyv1;@^DcQDc49G(!+LeG$xlmttb@V9vx$WDiphmY_G z;4nQy0g3&*ZC(b7ASnSvcm#m2v<$3^nmBPHo(!}{QUZuD3!t{P28Zl6;B{hRBAyJi zM^z7i;6A~PZEdPAe>UhD^*jJVya2wRcHaI2`y*!nzi%Vi1Be=|nlWQ$`b#hU-^;0~ nsrq~UR{!D^QUyrZxEtW_r%bs;&;Z{U00000NkvXXu0mjfi0rae literal 0 HcmV?d00001 diff --git a/Module.txt b/Module.txt deleted file mode 100644 index a2bfe07..0000000 --- a/Module.txt +++ /dev/null @@ -1,12 +0,0 @@ -Name: Login as Anybody -AntiForgery: enabled -Author: Lombiq -Website: https://github.com/Lombiq/Orchard-Login-as-Anybody -Version: 1.0 -OrchardVersion: 1.10.1 -Description: Allows administrators to log in as any user. -Features: - Lombiq.LoginAsAnybody: - Name: Login as Anybody - Description: Allows administrators to log in as any user. - Category: Administration \ No newline at end of file diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs deleted file mode 100644 index c06207d..0000000 --- a/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Security; - -// 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("Lombiq.LoginAsAnybody")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyProduct("Orchard")] -[assembly: AssemblyCopyright("")] -[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("7415db4b-a1eb-4b6b-858d-11371439f7d7")] - -// 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/Readme.md b/Readme.md index 7cdafb3..c0bd942 100644 --- a/Readme.md +++ b/Readme.md @@ -1,10 +1,9 @@ -# Login as Anybody readme - +# Login as Anybody ## About -Orchard module for administrators to be able to log in as any user. +Orchard Core module for administrators to be able to log in as any user. ## Documentation @@ -13,9 +12,9 @@ After enabling the module you'll see a new tab under Users. You can log in as an This feature is only available to site owners, thus it's not way to get around security. - -## Contributing and support - -Bug reports, feature requests, comments, questions, code contributions, and love letters are warmly welcome, please do so via GitHub issues and pull requests. Please adhere to our [open-source guidelines](https://lombiq.com/open-source-guidelines) while doing so. - + +## Contributing and support + +Bug reports, feature requests, comments, questions, code contributions, and love letters are warmly welcome, please do so via GitHub issues and pull requests. Please adhere to our [open-source guidelines](https://lombiq.com/open-source-guidelines) while doing so. + This project is developed by [Lombiq Technologies](https://lombiq.com/). Commercial-grade support is available through Lombiq. \ No newline at end of file diff --git a/Views/Admin/Index.cshtml b/Views/Admin/Index.cshtml deleted file mode 100644 index 35d2a3a..0000000 --- a/Views/Admin/Index.cshtml +++ /dev/null @@ -1,15 +0,0 @@ -@using Orchard.Utility.Extensions; - -@using (Html.BeginFormAntiForgeryPost()) -{ - @Html.Hint(T("Log in as any user in the system here. Note that once you log in as another user your current user session will be lost.")) - -
    -
  1. - @Html.Label("userName", T("Username").Text) - @Html.TextBox("userName") -
  2. -
- - -} \ No newline at end of file diff --git a/Web.config b/Web.config deleted file mode 100644 index d6076a4..0000000 --- a/Web.config +++ /dev/null @@ -1,59 +0,0 @@ - - - - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages.config b/packages.config deleted file mode 100644 index ce8a876..0000000 --- a/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file From 07e6c032eae46d63ed0abbc7a109b527217bf30f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20M=C3=A1t=C3=A9?= Date: Fri, 8 Dec 2023 18:31:52 +0100 Subject: [PATCH 02/16] Moving solution file --- Lombiq.LoginAsAnybody.sln | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Lombiq.LoginAsAnybody.sln b/Lombiq.LoginAsAnybody.sln index 237c081..0cbb0cc 100644 --- a/Lombiq.LoginAsAnybody.sln +++ b/Lombiq.LoginAsAnybody.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.8.34322.80 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lombiq.LoginAsAnybody", "Lombiq.LoginAsAnybody.csproj", "{D35DE919-3D8A-494C-8A33-B272D61C9956}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lombiq.LoginAsAnybody", "Lombiq.LoginAsAnybody\Lombiq.LoginAsAnybody.csproj", "{44C41A2B-9D65-4448-87E1-00256C60899C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,10 +11,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D35DE919-3D8A-494C-8A33-B272D61C9956}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D35DE919-3D8A-494C-8A33-B272D61C9956}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D35DE919-3D8A-494C-8A33-B272D61C9956}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D35DE919-3D8A-494C-8A33-B272D61C9956}.Release|Any CPU.Build.0 = Release|Any CPU + {44C41A2B-9D65-4448-87E1-00256C60899C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {44C41A2B-9D65-4448-87E1-00256C60899C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {44C41A2B-9D65-4448-87E1-00256C60899C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {44C41A2B-9D65-4448-87E1-00256C60899C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From cf705d23e3a9663e0cdae68a54c8129da235a48b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20M=C3=A1t=C3=A9?= Date: Fri, 8 Dec 2023 19:35:29 +0100 Subject: [PATCH 03/16] Adding display driver, registering it --- Lombiq.LoginAsAnybody/Constants/FeatureIds.cs | 6 ++++++ .../Drivers/ImpersonationDisplayDriver.cs | 13 +++++++++++++ Lombiq.LoginAsAnybody/FeatureIds.cs | 8 -------- .../Lombiq.LoginAsAnybody.csproj | 12 +----------- Lombiq.LoginAsAnybody/Manifest.cs | 8 ++++---- Lombiq.LoginAsAnybody/Startup.cs | 15 +++++++++++++++ .../Views/ImpersonationButton.cshtml | 11 +++++++++++ Lombiq.LoginAsAnybody/Views/_ViewImports.cshtml | 6 ++++++ 8 files changed, 56 insertions(+), 23 deletions(-) create mode 100644 Lombiq.LoginAsAnybody/Constants/FeatureIds.cs create mode 100644 Lombiq.LoginAsAnybody/Drivers/ImpersonationDisplayDriver.cs delete mode 100644 Lombiq.LoginAsAnybody/FeatureIds.cs create mode 100644 Lombiq.LoginAsAnybody/Startup.cs create mode 100644 Lombiq.LoginAsAnybody/Views/ImpersonationButton.cshtml create mode 100644 Lombiq.LoginAsAnybody/Views/_ViewImports.cshtml diff --git a/Lombiq.LoginAsAnybody/Constants/FeatureIds.cs b/Lombiq.LoginAsAnybody/Constants/FeatureIds.cs new file mode 100644 index 0000000..8454472 --- /dev/null +++ b/Lombiq.LoginAsAnybody/Constants/FeatureIds.cs @@ -0,0 +1,6 @@ +namespace Lombiq.LoginAsAnybody.Constants; + +public static class FeatureIds +{ + public const string LoginAsAnybody = "Lombiq.LoginAsAnybody"; +} diff --git a/Lombiq.LoginAsAnybody/Drivers/ImpersonationDisplayDriver.cs b/Lombiq.LoginAsAnybody/Drivers/ImpersonationDisplayDriver.cs new file mode 100644 index 0000000..24f1d82 --- /dev/null +++ b/Lombiq.LoginAsAnybody/Drivers/ImpersonationDisplayDriver.cs @@ -0,0 +1,13 @@ +using OrchardCore.DisplayManagement.Handlers; +using OrchardCore.DisplayManagement.Views; +using OrchardCore.Users.Models; +using OrchardCore.Users.ViewModels; + +namespace Lombiq.LoginAsAnybody.Drivers; + +public class ImpersonationDisplayDriver : DisplayDriver +{ + public override IDisplayResult Display(User model) + => Initialize("ImpersonationButton", summaryModel => summaryModel.User = model) + .Location("SummaryAdmin", "Actions:2"); +} diff --git a/Lombiq.LoginAsAnybody/FeatureIds.cs b/Lombiq.LoginAsAnybody/FeatureIds.cs deleted file mode 100644 index 61536a1..0000000 --- a/Lombiq.LoginAsAnybody/FeatureIds.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Lombiq.LoginAsAnybody; - -public static class FeatureIds -{ - public const string Area = "Lombiq.LoginAsAnybody"; - - public const string Default = Area; -} diff --git a/Lombiq.LoginAsAnybody/Lombiq.LoginAsAnybody.csproj b/Lombiq.LoginAsAnybody/Lombiq.LoginAsAnybody.csproj index d4f2db8..5077bf1 100644 --- a/Lombiq.LoginAsAnybody/Lombiq.LoginAsAnybody.csproj +++ b/Lombiq.LoginAsAnybody/Lombiq.LoginAsAnybody.csproj @@ -28,18 +28,8 @@ - - - - - - - - - - - + diff --git a/Lombiq.LoginAsAnybody/Manifest.cs b/Lombiq.LoginAsAnybody/Manifest.cs index 401081a..4d76b82 100644 --- a/Lombiq.LoginAsAnybody/Manifest.cs +++ b/Lombiq.LoginAsAnybody/Manifest.cs @@ -1,5 +1,5 @@ -using OrchardCore.Modules.Manifest; -using static Lombiq.LoginAsAnybody.FeatureIds; +using OrchardCore.Modules.Manifest; +using static Lombiq.LoginAsAnybody.Constants.FeatureIds; [assembly: Module( Name = "Lombiq Login as Anybody", @@ -10,7 +10,7 @@ )] [assembly: Feature( - Id = Default, + Id = LoginAsAnybody, Name = "Lombiq Login as Anybody", Category = "Security", Description = "Module that allows administrators to log in as any user.", @@ -18,4 +18,4 @@ { "OrchardCore.Users", } -)] \ No newline at end of file +)] diff --git a/Lombiq.LoginAsAnybody/Startup.cs b/Lombiq.LoginAsAnybody/Startup.cs new file mode 100644 index 0000000..036d8f3 --- /dev/null +++ b/Lombiq.LoginAsAnybody/Startup.cs @@ -0,0 +1,15 @@ +using Lombiq.LoginAsAnybody.Drivers; +using Microsoft.Extensions.DependencyInjection; +using OrchardCore.DisplayManagement.Handlers; +using OrchardCore.Modules; +using OrchardCore.Users.Models; + +namespace Lombiq.LoginAsAnybody; + +public class Startup : StartupBase +{ + public override void ConfigureServices(IServiceCollection services) + { + services.AddScoped, ImpersonationDisplayDriver>(); + } +} diff --git a/Lombiq.LoginAsAnybody/Views/ImpersonationButton.cshtml b/Lombiq.LoginAsAnybody/Views/ImpersonationButton.cshtml new file mode 100644 index 0000000..aec58f7 --- /dev/null +++ b/Lombiq.LoginAsAnybody/Views/ImpersonationButton.cshtml @@ -0,0 +1,11 @@ +@using OrchardCore.Modules +@using OrchardCore.Users.Models +@using OrchardCore.Users.ViewModels + +@model SummaryAdminUserViewModel + +@{ + var user = Model.User as User; +} + +@T["Log in as user"] diff --git a/Lombiq.LoginAsAnybody/Views/_ViewImports.cshtml b/Lombiq.LoginAsAnybody/Views/_ViewImports.cshtml new file mode 100644 index 0000000..6d1d688 --- /dev/null +++ b/Lombiq.LoginAsAnybody/Views/_ViewImports.cshtml @@ -0,0 +1,6 @@ +@inherits OrchardCore.DisplayManagement.Razor.RazorPage + +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@addTagHelper *, OrchardCore.Contents.TagHelpers +@addTagHelper *, OrchardCore.DisplayManagement +@addTagHelper *, OrchardCore.ResourceManagement From 45e0781805009631ec0e99ebcb46250c57d71ef6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20M=C3=A1t=C3=A9?= Date: Fri, 8 Dec 2023 19:36:38 +0100 Subject: [PATCH 04/16] Button styling --- Lombiq.LoginAsAnybody/Views/ImpersonationButton.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lombiq.LoginAsAnybody/Views/ImpersonationButton.cshtml b/Lombiq.LoginAsAnybody/Views/ImpersonationButton.cshtml index aec58f7..f40d9b9 100644 --- a/Lombiq.LoginAsAnybody/Views/ImpersonationButton.cshtml +++ b/Lombiq.LoginAsAnybody/Views/ImpersonationButton.cshtml @@ -8,4 +8,4 @@ var user = Model.User as User; } -@T["Log in as user"] +@T["Log in as user"] From 29586b32151ce21aaca192c0fd0b9f96c79e3da8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20M=C3=A1t=C3=A9?= Date: Fri, 8 Dec 2023 19:41:28 +0100 Subject: [PATCH 05/16] Code styling --- Lombiq.LoginAsAnybody/Startup.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Lombiq.LoginAsAnybody/Startup.cs b/Lombiq.LoginAsAnybody/Startup.cs index 036d8f3..0ef9f52 100644 --- a/Lombiq.LoginAsAnybody/Startup.cs +++ b/Lombiq.LoginAsAnybody/Startup.cs @@ -8,8 +8,6 @@ namespace Lombiq.LoginAsAnybody; public class Startup : StartupBase { - public override void ConfigureServices(IServiceCollection services) - { + public override void ConfigureServices(IServiceCollection services) => services.AddScoped, ImpersonationDisplayDriver>(); - } } From 7b1ebd49980296a761256dab88953c0a56ad64d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20M=C3=A1t=C3=A9?= Date: Fri, 8 Dec 2023 19:44:05 +0100 Subject: [PATCH 06/16] Editing DefaultItemExcludes in csproj --- Lombiq.LoginAsAnybody/Lombiq.LoginAsAnybody.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lombiq.LoginAsAnybody/Lombiq.LoginAsAnybody.csproj b/Lombiq.LoginAsAnybody/Lombiq.LoginAsAnybody.csproj index 5077bf1..17b1019 100644 --- a/Lombiq.LoginAsAnybody/Lombiq.LoginAsAnybody.csproj +++ b/Lombiq.LoginAsAnybody/Lombiq.LoginAsAnybody.csproj @@ -3,7 +3,7 @@ net6.0 true - $(DefaultItemExcludes);.git*;node_modules\**;Tests\** + $(DefaultItemExcludes);.git*;node_modules\** From 738b37a5647e972a4f0cd2ad2c51aa09af461b4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20M=C3=A1t=C3=A9?= Date: Fri, 8 Dec 2023 20:33:20 +0100 Subject: [PATCH 07/16] Implementing controller, changing file names --- .../Controllers/UserSwitcherController.cs | 55 +++++++++++++++++++ ...Driver.cs => UserSwitcherDisplayDriver.cs} | 4 +- Lombiq.LoginAsAnybody/Startup.cs | 2 +- .../Views/ImpersonationButton.cshtml | 11 ---- .../Views/UserSwitcherButton.cshtml | 13 +++++ 5 files changed, 71 insertions(+), 14 deletions(-) create mode 100644 Lombiq.LoginAsAnybody/Controllers/UserSwitcherController.cs rename Lombiq.LoginAsAnybody/Drivers/{ImpersonationDisplayDriver.cs => UserSwitcherDisplayDriver.cs} (63%) delete mode 100644 Lombiq.LoginAsAnybody/Views/ImpersonationButton.cshtml create mode 100644 Lombiq.LoginAsAnybody/Views/UserSwitcherButton.cshtml diff --git a/Lombiq.LoginAsAnybody/Controllers/UserSwitcherController.cs b/Lombiq.LoginAsAnybody/Controllers/UserSwitcherController.cs new file mode 100644 index 0000000..2dab010 --- /dev/null +++ b/Lombiq.LoginAsAnybody/Controllers/UserSwitcherController.cs @@ -0,0 +1,55 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Localization; +using OrchardCore.Admin; +using OrchardCore.DisplayManagement.Notify; +using OrchardCore.Security; +using OrchardCore.Users; +using System.Threading.Tasks; + +namespace Lombiq.LoginAsAnybody.Controllers; + +[Admin] +public class UserSwitcherController : Controller +{ + private readonly IAuthorizationService _authorizationService; + private readonly SignInManager _signInManager; + private readonly UserManager _userManager; + private readonly INotifier _notifier; + private readonly IHtmlLocalizer H; + + public UserSwitcherController( + IAuthorizationService authorizationService, + SignInManager signInManager, + UserManager userManager, + INotifier notifier, + IHtmlLocalizer htmlLocalizer) + { + _authorizationService = authorizationService; + _signInManager = signInManager; + _userManager = userManager; + _notifier = notifier; + H = htmlLocalizer; + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task SwitchUser(string userId, string returnUrl = null) + { + if (!await _authorizationService.AuthorizeAsync(User, StandardPermissions.SiteOwner)) return Unauthorized(); + + var selectedUser = await _userManager.FindByIdAsync(userId); + + if (selectedUser == null) return NotFound(); + + await _signInManager.SignOutAsync(); + await _signInManager.SignInAsync(selectedUser, isPersistent: false); + + if (string.IsNullOrEmpty(returnUrl)) returnUrl = "~/"; + + await _notifier.InformationAsync(H["Successfully logged in as {0}.", selectedUser.UserName]); + + return Redirect(returnUrl); + } +} diff --git a/Lombiq.LoginAsAnybody/Drivers/ImpersonationDisplayDriver.cs b/Lombiq.LoginAsAnybody/Drivers/UserSwitcherDisplayDriver.cs similarity index 63% rename from Lombiq.LoginAsAnybody/Drivers/ImpersonationDisplayDriver.cs rename to Lombiq.LoginAsAnybody/Drivers/UserSwitcherDisplayDriver.cs index 24f1d82..d834912 100644 --- a/Lombiq.LoginAsAnybody/Drivers/ImpersonationDisplayDriver.cs +++ b/Lombiq.LoginAsAnybody/Drivers/UserSwitcherDisplayDriver.cs @@ -5,9 +5,9 @@ namespace Lombiq.LoginAsAnybody.Drivers; -public class ImpersonationDisplayDriver : DisplayDriver +public class UserSwitcherDisplayDriver : DisplayDriver { public override IDisplayResult Display(User model) - => Initialize("ImpersonationButton", summaryModel => summaryModel.User = model) + => Initialize("UserSwitcherButton", summaryModel => summaryModel.User = model) .Location("SummaryAdmin", "Actions:2"); } diff --git a/Lombiq.LoginAsAnybody/Startup.cs b/Lombiq.LoginAsAnybody/Startup.cs index 0ef9f52..86ef106 100644 --- a/Lombiq.LoginAsAnybody/Startup.cs +++ b/Lombiq.LoginAsAnybody/Startup.cs @@ -9,5 +9,5 @@ namespace Lombiq.LoginAsAnybody; public class Startup : StartupBase { public override void ConfigureServices(IServiceCollection services) => - services.AddScoped, ImpersonationDisplayDriver>(); + services.AddScoped, UserSwitcherDisplayDriver>(); } diff --git a/Lombiq.LoginAsAnybody/Views/ImpersonationButton.cshtml b/Lombiq.LoginAsAnybody/Views/ImpersonationButton.cshtml deleted file mode 100644 index f40d9b9..0000000 --- a/Lombiq.LoginAsAnybody/Views/ImpersonationButton.cshtml +++ /dev/null @@ -1,11 +0,0 @@ -@using OrchardCore.Modules -@using OrchardCore.Users.Models -@using OrchardCore.Users.ViewModels - -@model SummaryAdminUserViewModel - -@{ - var user = Model.User as User; -} - -@T["Log in as user"] diff --git a/Lombiq.LoginAsAnybody/Views/UserSwitcherButton.cshtml b/Lombiq.LoginAsAnybody/Views/UserSwitcherButton.cshtml new file mode 100644 index 0000000..ea69684 --- /dev/null +++ b/Lombiq.LoginAsAnybody/Views/UserSwitcherButton.cshtml @@ -0,0 +1,13 @@ +@using OrchardCore.Modules +@using OrchardCore.Users.Models +@using OrchardCore.Users.ViewModels +@using static Lombiq.LoginAsAnybody.Constants.FeatureIds + +@model SummaryAdminUserViewModel + +@{ + var user = Model.User as User; +} + +@T["Log in as user"] From b8b69b0209d6114892ce594a756853693ad4d27f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20M=C3=A1t=C3=A9?= Date: Fri, 8 Dec 2023 23:36:33 +0100 Subject: [PATCH 08/16] Editing controller, mapping controller route --- .../Controllers/UserSwitcherController.cs | 8 ++----- Lombiq.LoginAsAnybody/Startup.cs | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/Lombiq.LoginAsAnybody/Controllers/UserSwitcherController.cs b/Lombiq.LoginAsAnybody/Controllers/UserSwitcherController.cs index 2dab010..1ec0b02 100644 --- a/Lombiq.LoginAsAnybody/Controllers/UserSwitcherController.cs +++ b/Lombiq.LoginAsAnybody/Controllers/UserSwitcherController.cs @@ -33,9 +33,7 @@ public UserSwitcherController( H = htmlLocalizer; } - [HttpPost] - [ValidateAntiForgeryToken] - public async Task SwitchUser(string userId, string returnUrl = null) + public async Task SwitchUser(string userId) { if (!await _authorizationService.AuthorizeAsync(User, StandardPermissions.SiteOwner)) return Unauthorized(); @@ -46,10 +44,8 @@ public async Task SwitchUser(string userId, string returnUrl = nu await _signInManager.SignOutAsync(); await _signInManager.SignInAsync(selectedUser, isPersistent: false); - if (string.IsNullOrEmpty(returnUrl)) returnUrl = "~/"; - await _notifier.InformationAsync(H["Successfully logged in as {0}.", selectedUser.UserName]); - return Redirect(returnUrl); + return Redirect("~/"); } } diff --git a/Lombiq.LoginAsAnybody/Startup.cs b/Lombiq.LoginAsAnybody/Startup.cs index 86ef106..648df82 100644 --- a/Lombiq.LoginAsAnybody/Startup.cs +++ b/Lombiq.LoginAsAnybody/Startup.cs @@ -1,8 +1,14 @@ +using Lombiq.LoginAsAnybody.Constants; +using Lombiq.LoginAsAnybody.Controllers; using Lombiq.LoginAsAnybody.Drivers; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; using OrchardCore.DisplayManagement.Handlers; using OrchardCore.Modules; +using OrchardCore.Mvc.Core.Utilities; using OrchardCore.Users.Models; +using System; namespace Lombiq.LoginAsAnybody; @@ -10,4 +16,19 @@ public class Startup : StartupBase { public override void ConfigureServices(IServiceCollection services) => services.AddScoped, UserSwitcherDisplayDriver>(); + + public override void Configure( + IApplicationBuilder app, + IEndpointRouteBuilder routes, + IServiceProvider serviceProvider) => + routes.MapAreaControllerRoute( + name: "UserSwitcher", + areaName: FeatureIds.LoginAsAnybody, + pattern: "UserSwitcher/SwitchUser", + defaults: new + { + controller = typeof(UserSwitcherController).ControllerName(), + action = nameof(UserSwitcherController.SwitchUser), + } + ); } From 6156a280ac026bcb129e9d0315fc59463ca5bae5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20M=C3=A1t=C3=A9?= Date: Mon, 11 Dec 2023 18:17:42 +0100 Subject: [PATCH 09/16] Refactoring, matching built in method routes --- .../Controllers/UserSwitcherController.cs | 4 ++-- Lombiq.LoginAsAnybody/Startup.cs | 8 +++++++- Lombiq.LoginAsAnybody/Views/UserSwitcherButton.cshtml | 8 ++++++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Lombiq.LoginAsAnybody/Controllers/UserSwitcherController.cs b/Lombiq.LoginAsAnybody/Controllers/UserSwitcherController.cs index 1ec0b02..014abdd 100644 --- a/Lombiq.LoginAsAnybody/Controllers/UserSwitcherController.cs +++ b/Lombiq.LoginAsAnybody/Controllers/UserSwitcherController.cs @@ -33,11 +33,11 @@ public UserSwitcherController( H = htmlLocalizer; } - public async Task SwitchUser(string userId) + public async Task SwitchUser(string id) { if (!await _authorizationService.AuthorizeAsync(User, StandardPermissions.SiteOwner)) return Unauthorized(); - var selectedUser = await _userManager.FindByIdAsync(userId); + var selectedUser = await _userManager.FindByIdAsync(id); if (selectedUser == null) return NotFound(); diff --git a/Lombiq.LoginAsAnybody/Startup.cs b/Lombiq.LoginAsAnybody/Startup.cs index 648df82..4e3f457 100644 --- a/Lombiq.LoginAsAnybody/Startup.cs +++ b/Lombiq.LoginAsAnybody/Startup.cs @@ -4,6 +4,8 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using OrchardCore.Admin; using OrchardCore.DisplayManagement.Handlers; using OrchardCore.Modules; using OrchardCore.Mvc.Core.Utilities; @@ -14,6 +16,10 @@ namespace Lombiq.LoginAsAnybody; public class Startup : StartupBase { + private readonly AdminOptions _adminOptions; + + public Startup(IOptions adminOptions) => _adminOptions = adminOptions.Value; + public override void ConfigureServices(IServiceCollection services) => services.AddScoped, UserSwitcherDisplayDriver>(); @@ -24,7 +30,7 @@ public override void Configure( routes.MapAreaControllerRoute( name: "UserSwitcher", areaName: FeatureIds.LoginAsAnybody, - pattern: "UserSwitcher/SwitchUser", + pattern: _adminOptions.AdminUrlPrefix + "/Users/SwitchUser/{id}", defaults: new { controller = typeof(UserSwitcherController).ControllerName(), diff --git a/Lombiq.LoginAsAnybody/Views/UserSwitcherButton.cshtml b/Lombiq.LoginAsAnybody/Views/UserSwitcherButton.cshtml index ea69684..d98a73b 100644 --- a/Lombiq.LoginAsAnybody/Views/UserSwitcherButton.cshtml +++ b/Lombiq.LoginAsAnybody/Views/UserSwitcherButton.cshtml @@ -9,5 +9,9 @@ var user = Model.User as User; } -@T["Log in as user"] +@if (user.UserName != User.Identity.Name) +{ + @T["Log in as user"] +} + From 5b192522174cc8a0bc276ea476103513a5f37753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20M=C3=A1t=C3=A9?= Date: Mon, 11 Dec 2023 18:37:25 +0100 Subject: [PATCH 10/16] Editing Readme --- .../Controllers/UserSwitcherController.cs | 2 +- Readme.md | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Lombiq.LoginAsAnybody/Controllers/UserSwitcherController.cs b/Lombiq.LoginAsAnybody/Controllers/UserSwitcherController.cs index 014abdd..dc73b13 100644 --- a/Lombiq.LoginAsAnybody/Controllers/UserSwitcherController.cs +++ b/Lombiq.LoginAsAnybody/Controllers/UserSwitcherController.cs @@ -44,7 +44,7 @@ public async Task SwitchUser(string id) await _signInManager.SignOutAsync(); await _signInManager.SignInAsync(selectedUser, isPersistent: false); - await _notifier.InformationAsync(H["Successfully logged in as {0}.", selectedUser.UserName]); + await _notifier.InformationAsync(H["Successfully logged in as {0}.", selectedUser.UserName]); return Redirect("~/"); } diff --git a/Readme.md b/Readme.md index c0bd942..c5de3be 100644 --- a/Readme.md +++ b/Readme.md @@ -1,20 +1,20 @@ -# Login as Anybody +# Lombiq Login as Anybody for Orchard Core ## About -Orchard Core module for administrators to be able to log in as any user. +Orchard Core module for administrators to be able to log in as any user. The Orchard 1 version of the module is available on the branch `dev-orchard-1`. ## Documentation -After enabling the module you'll see a new tab under Users. You can log in as any registered user there. This is useful if you want to see how your Orchard app behaves for certain users. +After enabling the module you'll see a new button on the Security → Users page. You can log in as any registered user there. This is useful if you want to see how your Orchard Core app behaves for certain users. This feature is only available to site owners, thus it's not way to get around security. ## Contributing and support -Bug reports, feature requests, comments, questions, code contributions, and love letters are warmly welcome, please do so via GitHub issues and pull requests. Please adhere to our [open-source guidelines](https://lombiq.com/open-source-guidelines) while doing so. +Bug reports, feature requests, comments, questions, code contributions and love letters are warmly welcome. You can send them to us via GitHub issues and pull requests. Please adhere to our [open-source guidelines](https://lombiq.com/open-source-guidelines) while doing so. -This project is developed by [Lombiq Technologies](https://lombiq.com/). Commercial-grade support is available through Lombiq. \ No newline at end of file +This project is developed by [Lombiq Technologies](https://lombiq.com/). Commercial-grade support is available through Lombiq. From d7c498b8cd28ecac093d37874c281d5250545dd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20M=C3=A1t=C3=A9?= Date: Mon, 11 Dec 2023 22:48:12 +0100 Subject: [PATCH 11/16] Adding UI test project --- .../TestCaseUITestContextExtensions.cs | 24 +++++++++++++ Lombiq.LoginAsAnybody.Tests.UI/License.md | 13 +++++++ .../Lombiq.LoginAsAnybody.Tests.UI.csproj | 33 ++++++++++++++++++ Lombiq.LoginAsAnybody.Tests.UI/NuGetIcon.png | Bin 0 -> 4657 bytes Lombiq.LoginAsAnybody.Tests.UI/Readme.md | 7 ++++ Lombiq.LoginAsAnybody.sln | 6 ++++ 6 files changed, 83 insertions(+) create mode 100644 Lombiq.LoginAsAnybody.Tests.UI/Extensions/TestCaseUITestContextExtensions.cs create mode 100644 Lombiq.LoginAsAnybody.Tests.UI/License.md create mode 100644 Lombiq.LoginAsAnybody.Tests.UI/Lombiq.LoginAsAnybody.Tests.UI.csproj create mode 100644 Lombiq.LoginAsAnybody.Tests.UI/NuGetIcon.png create mode 100644 Lombiq.LoginAsAnybody.Tests.UI/Readme.md diff --git a/Lombiq.LoginAsAnybody.Tests.UI/Extensions/TestCaseUITestContextExtensions.cs b/Lombiq.LoginAsAnybody.Tests.UI/Extensions/TestCaseUITestContextExtensions.cs new file mode 100644 index 0000000..82b3488 --- /dev/null +++ b/Lombiq.LoginAsAnybody.Tests.UI/Extensions/TestCaseUITestContextExtensions.cs @@ -0,0 +1,24 @@ +using Lombiq.Tests.UI.Extensions; +using Lombiq.Tests.UI.Models; +using Lombiq.Tests.UI.Services; +using OpenQA.Selenium; +using Shouldly; +using System.Threading.Tasks; + +namespace Lombiq.LoginAsAnybody.Tests.UI.Extensions; + +public static class TestCaseUITestContextExtensions +{ + public static async Task TestLoginAsAnybodyAsync(this UITestContext context, bool checkBuildLink = false) + { + await context.SignInDirectlyAndGoToDashboardAsync(); + + var userParameters = UserRegistrationParameters.CreateDefault(); + await context.CreateUserAsync(userParameters.UserName, userParameters.Password, userParameters.Email); + + await context.GoToUsersAsync(); + await context.ClickReliablyOnAsync(By.XPath("//a[contains(.,'Log in as user')]")); + + (await context.GetCurrentUserNameAsync()).ShouldBe(userParameters.UserName); + } +} diff --git a/Lombiq.LoginAsAnybody.Tests.UI/License.md b/Lombiq.LoginAsAnybody.Tests.UI/License.md new file mode 100644 index 0000000..afc7cc7 --- /dev/null +++ b/Lombiq.LoginAsAnybody.Tests.UI/License.md @@ -0,0 +1,13 @@ +Copyright © 2023, [Lombiq Technologies Ltd.](https://lombiq.com) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +- Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/Lombiq.LoginAsAnybody.Tests.UI/Lombiq.LoginAsAnybody.Tests.UI.csproj b/Lombiq.LoginAsAnybody.Tests.UI/Lombiq.LoginAsAnybody.Tests.UI.csproj new file mode 100644 index 0000000..d732d1a --- /dev/null +++ b/Lombiq.LoginAsAnybody.Tests.UI/Lombiq.LoginAsAnybody.Tests.UI.csproj @@ -0,0 +1,33 @@ + + + + net6.0 + + + + Lombiq Login as Anybody for Orchard Core - UI Test Extensions + Lombiq Technologies + Copyright © 2023, Lombiq Technologies Ltd. + Lombiq Login as Anybody for Orchard Core - UI Test Extensions: Extensions to aid in UI testing Lombiq Login as Anybody for Orchard Core. + NuGetIcon.png + OrchardCore;Lombiq;AspNetCore + https://github.com/Lombiq/Orchard-Login-as-Anybody + https://github.com/Lombiq/Orchard-Login-as-Anybody/tree/dev/Lombiq.LoginAsAnybody.Tests.UI + License.md + + + + + + + + + + + + + + + + + diff --git a/Lombiq.LoginAsAnybody.Tests.UI/NuGetIcon.png b/Lombiq.LoginAsAnybody.Tests.UI/NuGetIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..162a00508d8041833604d427216238c1b23b2d47 GIT binary patch literal 4657 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 literal 0 HcmV?d00001 diff --git a/Lombiq.LoginAsAnybody.Tests.UI/Readme.md b/Lombiq.LoginAsAnybody.Tests.UI/Readme.md new file mode 100644 index 0000000..8a723fc --- /dev/null +++ b/Lombiq.LoginAsAnybody.Tests.UI/Readme.md @@ -0,0 +1,7 @@ +# Lombiq Login as Anybody for Orchard Core - UI Test Extensions + +## About + +Extension methods that test various features in Lombiq Login as Anybody for Orchard Core, with the help of [Lombiq UI Testing Toolbox for Orchard Core](https://github.com/Lombiq/UI-Testing-Toolbox). + +Call these from a UI test project to verify the module's basic features; as seen in [Open-Source Orchard Core Extensions](https://github.com/Lombiq/Open-Source-Orchard-Core-Extensions). diff --git a/Lombiq.LoginAsAnybody.sln b/Lombiq.LoginAsAnybody.sln index 0cbb0cc..5f9f7bd 100644 --- a/Lombiq.LoginAsAnybody.sln +++ b/Lombiq.LoginAsAnybody.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 17.8.34322.80 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lombiq.LoginAsAnybody", "Lombiq.LoginAsAnybody\Lombiq.LoginAsAnybody.csproj", "{44C41A2B-9D65-4448-87E1-00256C60899C}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lombiq.LoginAsAnybody.Tests.UI", "Lombiq.LoginAsAnybody.Tests.UI\Lombiq.LoginAsAnybody.Tests.UI.csproj", "{80B8DAC4-0D37-4CCD-AAA7-CFA7422399A9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +17,10 @@ Global {44C41A2B-9D65-4448-87E1-00256C60899C}.Debug|Any CPU.Build.0 = Debug|Any CPU {44C41A2B-9D65-4448-87E1-00256C60899C}.Release|Any CPU.ActiveCfg = Release|Any CPU {44C41A2B-9D65-4448-87E1-00256C60899C}.Release|Any CPU.Build.0 = Release|Any CPU + {80B8DAC4-0D37-4CCD-AAA7-CFA7422399A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {80B8DAC4-0D37-4CCD-AAA7-CFA7422399A9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {80B8DAC4-0D37-4CCD-AAA7-CFA7422399A9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {80B8DAC4-0D37-4CCD-AAA7-CFA7422399A9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 5f801855f7a1a15bf691dd112923be9206b7ec08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20M=C3=A1t=C3=A9?= Date: Tue, 12 Dec 2023 14:42:12 +0100 Subject: [PATCH 12/16] Readme and License formatting --- License.md | 2 +- Lombiq.LoginAsAnybody/License.md | 4 ++-- Readme.md | 3 --- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/License.md b/License.md index 53b7c51..4add106 100644 --- a/License.md +++ b/License.md @@ -10,4 +10,4 @@ Redistribution and use in source and binary forms, with or without modification, - Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Lombiq.LoginAsAnybody/License.md b/Lombiq.LoginAsAnybody/License.md index afc7cc7..4add106 100644 --- a/Lombiq.LoginAsAnybody/License.md +++ b/Lombiq.LoginAsAnybody/License.md @@ -1,4 +1,4 @@ -Copyright © 2023, [Lombiq Technologies Ltd.](https://lombiq.com) +Copyright © 2023, [Lombiq Technologies Ltd.](https://lombiq.com) All rights reserved. @@ -10,4 +10,4 @@ Redistribution and use in source and binary forms, with or without modification, - Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Readme.md b/Readme.md index c5de3be..2962e93 100644 --- a/Readme.md +++ b/Readme.md @@ -1,18 +1,15 @@ # Lombiq Login as Anybody for Orchard Core - ## About Orchard Core module for administrators to be able to log in as any user. The Orchard 1 version of the module is available on the branch `dev-orchard-1`. - ## Documentation After enabling the module you'll see a new button on the Security → Users page. You can log in as any registered user there. This is useful if you want to see how your Orchard Core app behaves for certain users. This feature is only available to site owners, thus it's not way to get around security. - ## Contributing and support Bug reports, feature requests, comments, questions, code contributions and love letters are warmly welcome. You can send them to us via GitHub issues and pull requests. Please adhere to our [open-source guidelines](https://lombiq.com/open-source-guidelines) while doing so. From 2339aecec0a050917ffa3beed4a4dad79a4fd593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20M=C3=A1t=C3=A9?= Date: Tue, 12 Dec 2023 14:54:27 +0100 Subject: [PATCH 13/16] Newline at end of file --- Lombiq.LoginAsAnybody.Tests.UI/License.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lombiq.LoginAsAnybody.Tests.UI/License.md b/Lombiq.LoginAsAnybody.Tests.UI/License.md index afc7cc7..4add106 100644 --- a/Lombiq.LoginAsAnybody.Tests.UI/License.md +++ b/Lombiq.LoginAsAnybody.Tests.UI/License.md @@ -1,4 +1,4 @@ -Copyright © 2023, [Lombiq Technologies Ltd.](https://lombiq.com) +Copyright © 2023, [Lombiq Technologies Ltd.](https://lombiq.com) All rights reserved. @@ -10,4 +10,4 @@ Redistribution and use in source and binary forms, with or without modification, - Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From fc9d3a579c9614cbe14b4b6e68c4bbaeb8ddc9e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20M=C3=A1t=C3=A9?= Date: Tue, 19 Dec 2023 16:53:10 +0100 Subject: [PATCH 14/16] Addressing feedback --- .gitattributes | 2 +- ...e-jira-issues-for-community-activities.yml | 2 +- .github/workflows/publish-nuget.yml | 2 +- .github/workflows/validate-pull-request.yml | 2 +- .gitignore | 2 +- License.md | 2 +- .../TestCaseUITestContextExtensions.cs | 2 +- .../Drivers/UserSwitcherDisplayDriver.cs | 23 ++++++++++++++++--- Lombiq.LoginAsAnybody/License.md | 2 +- .../Lombiq.LoginAsAnybody.csproj | 2 +- Lombiq.LoginAsAnybody/Manifest.cs | 4 ++-- .../Views/UserSwitcherButton.cshtml | 8 ++----- 12 files changed, 33 insertions(+), 20 deletions(-) diff --git a/.gitattributes b/.gitattributes index 9aa44dd..6d4c140 100644 --- a/.gitattributes +++ b/.gitattributes @@ -5,4 +5,4 @@ *.cs text eol=crlf # Keep LF line endings in pnpm-lock.yaml files to prevent Git from reporting this file as changed after pnpm touches it. -pnpm-lock.yaml text eol=lf \ No newline at end of file +pnpm-lock.yaml text eol=lf diff --git a/.github/workflows/create-jira-issues-for-community-activities.yml b/.github/workflows/create-jira-issues-for-community-activities.yml index a844b05..dee1d90 100644 --- a/.github/workflows/create-jira-issues-for-community-activities.yml +++ b/.github/workflows/create-jira-issues-for-community-activities.yml @@ -21,4 +21,4 @@ jobs: ISSUE_JIRA_ISSUE_DESCRIPTION: ${{ secrets.DEFAULT_ISSUE_JIRA_ISSUE_DESCRIPTION }} PULL_REQUEST_JIRA_ISSUE_DESCRIPTION: ${{ secrets.DEFAULT_PULL_REQUEST_JIRA_ISSUE_DESCRIPTION }} with: - issue-component: Lombiq.LoginAsAnybody \ No newline at end of file + issue-component: Lombiq.LoginAsAnybody diff --git a/.github/workflows/publish-nuget.yml b/.github/workflows/publish-nuget.yml index 6d69e55..fac826d 100644 --- a/.github/workflows/publish-nuget.yml +++ b/.github/workflows/publish-nuget.yml @@ -10,4 +10,4 @@ jobs: name: Publish to NuGet uses: Lombiq/GitHub-Actions/.github/workflows/publish-nuget.yml@dev secrets: - API_KEY: ${{ secrets.DEFAULT_NUGET_PUBLISH_API_KEY }} \ No newline at end of file + API_KEY: ${{ secrets.DEFAULT_NUGET_PUBLISH_API_KEY }} diff --git a/.github/workflows/validate-pull-request.yml b/.github/workflows/validate-pull-request.yml index 9e05214..3ca9813 100644 --- a/.github/workflows/validate-pull-request.yml +++ b/.github/workflows/validate-pull-request.yml @@ -6,4 +6,4 @@ on: jobs: validate-pull-request: name: Validate Pull Request - uses: Lombiq/GitHub-Actions/.github/workflows/validate-submodule-pull-request.yml@dev \ No newline at end of file + uses: Lombiq/GitHub-Actions/.github/workflows/validate-submodule-pull-request.yml@dev diff --git a/.gitignore b/.gitignore index d091319..dee8bf8 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,4 @@ node_modules/ .pnpm-debug.log # Mac -.DS_Store \ No newline at end of file +.DS_Store diff --git a/License.md b/License.md index 4add106..cc97fca 100644 --- a/License.md +++ b/License.md @@ -1,4 +1,4 @@ -Copyright © 2023, [Lombiq Technologies Ltd.](https://lombiq.com) +Copyright © 2015, [Lombiq Technologies Ltd.](https://lombiq.com) All rights reserved. diff --git a/Lombiq.LoginAsAnybody.Tests.UI/Extensions/TestCaseUITestContextExtensions.cs b/Lombiq.LoginAsAnybody.Tests.UI/Extensions/TestCaseUITestContextExtensions.cs index 82b3488..d635073 100644 --- a/Lombiq.LoginAsAnybody.Tests.UI/Extensions/TestCaseUITestContextExtensions.cs +++ b/Lombiq.LoginAsAnybody.Tests.UI/Extensions/TestCaseUITestContextExtensions.cs @@ -9,7 +9,7 @@ namespace Lombiq.LoginAsAnybody.Tests.UI.Extensions; public static class TestCaseUITestContextExtensions { - public static async Task TestLoginAsAnybodyAsync(this UITestContext context, bool checkBuildLink = false) + public static async Task TestLoginAsAnybodyAsync(this UITestContext context) { await context.SignInDirectlyAndGoToDashboardAsync(); diff --git a/Lombiq.LoginAsAnybody/Drivers/UserSwitcherDisplayDriver.cs b/Lombiq.LoginAsAnybody/Drivers/UserSwitcherDisplayDriver.cs index d834912..e7e4fb9 100644 --- a/Lombiq.LoginAsAnybody/Drivers/UserSwitcherDisplayDriver.cs +++ b/Lombiq.LoginAsAnybody/Drivers/UserSwitcherDisplayDriver.cs @@ -1,13 +1,30 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using OrchardCore.DisplayManagement.Handlers; +using OrchardCore.DisplayManagement.ModelBinding; using OrchardCore.DisplayManagement.Views; +using OrchardCore.Security; using OrchardCore.Users.Models; using OrchardCore.Users.ViewModels; +using System.Threading.Tasks; namespace Lombiq.LoginAsAnybody.Drivers; public class UserSwitcherDisplayDriver : DisplayDriver { - public override IDisplayResult Display(User model) - => Initialize("UserSwitcherButton", summaryModel => summaryModel.User = model) - .Location("SummaryAdmin", "Actions:2"); + private readonly IHttpContextAccessor _hca; + private readonly IAuthorizationService _authorizationService; + + public UserSwitcherDisplayDriver(IHttpContextAccessor hca, IAuthorizationService authorizationService) + { + _hca = hca; + _authorizationService = authorizationService; + } + + public override async Task DisplayAsync(User model, IUpdateModel updater) => + await _authorizationService.AuthorizeAsync(_hca.HttpContext.User, StandardPermissions.SiteOwner) && + _hca.HttpContext.User.Identity.Name != model.UserName + ? Initialize("UserSwitcherButton", summaryModel => summaryModel.User = model) + .Location("SummaryAdmin", "Actions:2") + : null; } diff --git a/Lombiq.LoginAsAnybody/License.md b/Lombiq.LoginAsAnybody/License.md index 4add106..cc97fca 100644 --- a/Lombiq.LoginAsAnybody/License.md +++ b/Lombiq.LoginAsAnybody/License.md @@ -1,4 +1,4 @@ -Copyright © 2023, [Lombiq Technologies Ltd.](https://lombiq.com) +Copyright © 2015, [Lombiq Technologies Ltd.](https://lombiq.com) All rights reserved. diff --git a/Lombiq.LoginAsAnybody/Lombiq.LoginAsAnybody.csproj b/Lombiq.LoginAsAnybody/Lombiq.LoginAsAnybody.csproj index 17b1019..d0bb9f4 100644 --- a/Lombiq.LoginAsAnybody/Lombiq.LoginAsAnybody.csproj +++ b/Lombiq.LoginAsAnybody/Lombiq.LoginAsAnybody.csproj @@ -10,7 +10,7 @@ Lombiq Login as Anybody for Orchard Core Lombiq Technologies Copyright © 2023, Lombiq Technologies Ltd. - Lombiq Login as Anybody for Orchard Core: An Orchard Core module that allows administrators to log in as any user. + Lombiq Login as Anybody for Orchard Core: An Orchard Core module that allows users with site owner permission to log in as any user. NuGetIcon.png OrchardCore;Lombiq;AspNetCore https://github.com/Lombiq/Orchard-Login-as-Anybody diff --git a/Lombiq.LoginAsAnybody/Manifest.cs b/Lombiq.LoginAsAnybody/Manifest.cs index 4d76b82..ca900c4 100644 --- a/Lombiq.LoginAsAnybody/Manifest.cs +++ b/Lombiq.LoginAsAnybody/Manifest.cs @@ -5,7 +5,7 @@ Name = "Lombiq Login as Anybody", Author = "Lombiq Technologies", Version = "0.0.1", - Description = "Module that allows administrators to log in as any user.", + Description = "Module that allows users with site owner permission to log in as any user.", Website = "https://github.com/Lombiq/Orchard-Login-as-Anybody" )] @@ -13,7 +13,7 @@ Id = LoginAsAnybody, Name = "Lombiq Login as Anybody", Category = "Security", - Description = "Module that allows administrators to log in as any user.", + Description = "Module that allows users with site owner permission to log in as any user.", Dependencies = new[] { "OrchardCore.Users", diff --git a/Lombiq.LoginAsAnybody/Views/UserSwitcherButton.cshtml b/Lombiq.LoginAsAnybody/Views/UserSwitcherButton.cshtml index d98a73b..c926746 100644 --- a/Lombiq.LoginAsAnybody/Views/UserSwitcherButton.cshtml +++ b/Lombiq.LoginAsAnybody/Views/UserSwitcherButton.cshtml @@ -9,9 +9,5 @@ var user = Model.User as User; } -@if (user.UserName != User.Identity.Name) -{ - @T["Log in as user"] -} - +@T["Log in as user"] From 0615662232ee30d6ac8afad54245ee19aa17fb45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20M=C3=A1t=C3=A9?= Date: Tue, 19 Dec 2023 21:15:10 +0100 Subject: [PATCH 15/16] Adding test and configuration for authorization --- .../Extensions/Configurations.cs | 17 +++++++++++++++++ .../TestCaseUITestContextExtensions.cs | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 Lombiq.LoginAsAnybody.Tests.UI/Extensions/Configurations.cs diff --git a/Lombiq.LoginAsAnybody.Tests.UI/Extensions/Configurations.cs b/Lombiq.LoginAsAnybody.Tests.UI/Extensions/Configurations.cs new file mode 100644 index 0000000..5e8673f --- /dev/null +++ b/Lombiq.LoginAsAnybody.Tests.UI/Extensions/Configurations.cs @@ -0,0 +1,17 @@ +using Lombiq.Tests.UI.Services; +using System; +using System.Linq; + +namespace Lombiq.LoginAsAnybody.Tests.UI.Extensions; + +public static class Configurations +{ + // We are checking a page with Unauthorized status code, so we need to make an exception here. + public static readonly Action IgnoreUnauthorizedBrowserLogEntries = + configuration => + configuration.AssertBrowserLog = + logEntries => + OrchardCoreUITestExecutorConfiguration.AssertBrowserLogIsEmpty( + logEntries.Where(logEntry => + !logEntry.Message.ContainsOrdinalIgnoreCase("the server responded with a status of 401"))); +} diff --git a/Lombiq.LoginAsAnybody.Tests.UI/Extensions/TestCaseUITestContextExtensions.cs b/Lombiq.LoginAsAnybody.Tests.UI/Extensions/TestCaseUITestContextExtensions.cs index d635073..6b95205 100644 --- a/Lombiq.LoginAsAnybody.Tests.UI/Extensions/TestCaseUITestContextExtensions.cs +++ b/Lombiq.LoginAsAnybody.Tests.UI/Extensions/TestCaseUITestContextExtensions.cs @@ -21,4 +21,21 @@ public static async Task TestLoginAsAnybodyAsync(this UITestContext context) (await context.GetCurrentUserNameAsync()).ShouldBe(userParameters.UserName); } + + public static async Task TestLoginAsAnybodyAuthorizationAsync(this UITestContext context) + { + var userParameters = UserRegistrationParameters.CreateDefault(); + await context.CreateUserAsync(userParameters.UserName, userParameters.Password, userParameters.Email); + + // The role needs this permission to visit the users page. + await context.AddPermissionToRoleAsync("ManageUsers", "Moderator"); + await context.AddUserToRoleAsync(userParameters.UserName, "Moderator"); + + await context.SignInDirectlyAndGoToDashboardAsync(userParameters.UserName); + await context.GoToUsersAsync(); + + context.Missing(By.XPath("//a[contains(.,'Log in as user')]")); + await context.GoToAdminRelativeUrlAsync("/Users/SwitchUser/userId"); + context.Exists(By.XPath("//h1[contains(text(),'You are not authorized to view this content.')]")); + } } From 8d324c383ebc32753ca1e43aefb40e3e2667a920 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20M=C3=A1t=C3=A9?= Date: Wed, 20 Dec 2023 20:35:27 +0100 Subject: [PATCH 16/16] Adding NuGet version shield to Readme --- Lombiq.LoginAsAnybody/Lombiq.LoginAsAnybody.csproj | 3 ++- Readme.md | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Lombiq.LoginAsAnybody/Lombiq.LoginAsAnybody.csproj b/Lombiq.LoginAsAnybody/Lombiq.LoginAsAnybody.csproj index d0bb9f4..65f59f9 100644 --- a/Lombiq.LoginAsAnybody/Lombiq.LoginAsAnybody.csproj +++ b/Lombiq.LoginAsAnybody/Lombiq.LoginAsAnybody.csproj @@ -9,7 +9,7 @@ Lombiq Login as Anybody for Orchard Core Lombiq Technologies - Copyright © 2023, Lombiq Technologies Ltd. + Copyright © 2015, Lombiq Technologies Ltd. Lombiq Login as Anybody for Orchard Core: An Orchard Core module that allows users with site owner permission to log in as any user. NuGetIcon.png OrchardCore;Lombiq;AspNetCore @@ -20,6 +20,7 @@ + diff --git a/Readme.md b/Readme.md index 2962e93..681b0d3 100644 --- a/Readme.md +++ b/Readme.md @@ -1,5 +1,7 @@ # Lombiq Login as Anybody for Orchard Core +[![Lombiq.LoginAsAnybody NuGet](https://img.shields.io/nuget/v/Lombiq.LoginAsAnybody?label=Lombiq.LoginAsAnybody)](https://www.nuget.org/packages/Lombiq.LoginAsAnybody/) [![Lombiq.LoginAsAnybody.Tests.UI NuGet](https://img.shields.io/nuget/v/Lombiq.LoginAsAnybody.Tests.UI?label=Lombiq.LoginAsAnybody.Tests.UI)](https://www.nuget.org/packages/Lombiq.LoginAsAnybody.Tests.UI/) + ## About Orchard Core module for administrators to be able to log in as any user. The Orchard 1 version of the module is available on the branch `dev-orchard-1`.