-
-
Notifications
You must be signed in to change notification settings - Fork 69
/
SessionElevationManager.cs
112 lines (99 loc) · 4.49 KB
/
SessionElevationManager.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
using System;
using System.Collections.Generic;
using System.Web;
using System.Xml;
using Sitecore.Configuration;
using Spe.Core.Diagnostics;
namespace Spe.Core.Settings.Authorization
{
public static class SessionElevationManager
{
private const string SessionCacheToken = "SPE_Session_Elevation_{0}";
private static readonly Dictionary<string, TokenDefinition> Tokens;
public const string SaveAction = "Save";
public const string ExecuteAction = "Execute";
static SessionElevationManager()
{
var tokenDefinitions = new Dictionary<string, TokenDefinition>();
var xmlDefinitions = Factory.GetConfigNodes("powershell/userAccountControl/tokens/token");
foreach (XmlElement xmlDefinition in xmlDefinitions)
{
var token = new TokenDefinition()
{
Name = xmlDefinition.Attributes["name"].Value
};
if (tokenDefinitions.ContainsKey(token.Name))
{
throw new ArgumentException($"A duplicate token was detected in the configuration. The token '{token.Name}' already exists.");
}
if (TimeSpan.TryParse(xmlDefinition.Attributes["expiration"].Value, out var expiration))
{
token.Expiration = expiration;
}
token.Action = Enum.TryParse(xmlDefinition.Attributes["elevationAction"].Value, out TokenDefinition.ElevationAction action)
? action
: TokenDefinition.ElevationAction.Block;
tokenDefinitions.Add(token.Name, token);
}
Tokens = new Dictionary<string, TokenDefinition>();
var xmlApps = Factory.GetConfigNodes("powershell/userAccountControl/gates/gate");
foreach (XmlElement xmlApp in xmlApps)
{
var name = xmlApp.Attributes["name"].Value;
if (Tokens.ContainsKey(name))
{
throw new ArgumentException($"A duplicate gate was detected in the configuration. The gate '{name}' already exists.");
}
Tokens.Add(name, tokenDefinitions[xmlApp.Attributes["token"].Value]);
}
}
internal static TokenDefinition GetToken(string appName)
{
if (Tokens.TryGetValue(appName, out var token)) return token;
return Tokens["Default"];
}
public static bool IsSessionTokenElevated(string appName)
{
var token = GetToken(appName);
switch (token.Action)
{
case TokenDefinition.ElevationAction.Allow:
return true;
case TokenDefinition.ElevationAction.Password:
case TokenDefinition.ElevationAction.Confirm:
var cachedSession = HttpContext.Current?.Session[string.Format(SessionCacheToken, token.Name)];
if (cachedSession == null || ((DateTime) cachedSession >= DateTime.Now)) return cachedSession != null;
PowerShellLog.Warn($"Session state elevation expired for '{appName}' for user: {Sitecore.Context.User?.Name}");
HttpContext.Current.Session.Remove(string.Format(SessionCacheToken, token.Name));
return false;
default:
return false;
}
}
public static void ElevateSessionToken(string appName)
{
var token = GetToken(appName);
PowerShellLog.Warn($"Session state elevated for '{appName}' by user: {Sitecore.Context.User?.Name}");
HttpContext.Current.Session[string.Format(SessionCacheToken, token?.Name)] = DateTime.Now + token.Expiration;
}
public static void DropSessionTokenElevation(string appName)
{
var token = GetToken(appName);
HttpContext.Current.Session.Remove(string.Format(SessionCacheToken, token?.Name));
PowerShellLog.Warn($"Session state elevation dropped for '{appName}' by user: {Sitecore.Context.User?.Name}");
}
internal class TokenDefinition
{
public string Name { get; set; }
public TimeSpan Expiration { get; set; }
public ElevationAction Action { get; set; }
internal enum ElevationAction
{
Block,
Password,
Confirm,
Allow,
}
}
}
}