-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Expand file tree
/
Copy pathGitHubAuthChallenge.cs
More file actions
121 lines (97 loc) · 3.71 KB
/
GitHubAuthChallenge.cs
File metadata and controls
121 lines (97 loc) · 3.71 KB
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
113
114
115
116
117
118
119
120
121
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace GitHub;
public class GitHubAuthChallenge : IEquatable<GitHubAuthChallenge>
{
private static readonly Regex BasicRegex = new(@"Basic\s+(?'props1'.*)realm=""GitHub""(?'props2'.*)",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static IList<GitHubAuthChallenge> FromHeaders(IEnumerable<string> headers)
{
var challenges = new List<GitHubAuthChallenge>();
foreach (string header in headers)
{
var match = BasicRegex.Match(header);
if (match.Success)
{
IDictionary<string, string> props = ParseProperties(match.Groups["props1"].Value + match.Groups["props2"]);
// The enterprise shortcode is provided in the `domain_hint` property, whereas the
// enterprise name/slug is provided in the `enterprise_hint` property.
props.TryGetValue("domain_hint", out string domain);
props.TryGetValue("enterprise_hint", out string enterprise);
var challenge = new GitHubAuthChallenge(domain, enterprise);
challenges.Add(challenge);
}
}
return challenges;
}
private static IDictionary<string, string> ParseProperties(string str)
{
var props = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
foreach (string prop in str.Split(' '))
{
int delim = prop.IndexOf('=');
if (delim < 0)
{
continue;
}
string key = prop.Substring(0, delim).Trim();
string value = prop.Substring(delim + 1).Trim('"');
props[key] = value;
}
return props;
}
public GitHubAuthChallenge() { }
public GitHubAuthChallenge(string domain, string enterprise)
{
Domain = domain;
Enterprise = enterprise;
}
public string Domain { get; }
public string Enterprise { get; }
public bool IsDomainMember(string userName)
{
if (string.IsNullOrWhiteSpace(userName))
{
return false;
}
int delim = userName.LastIndexOf('_');
if (delim < 0)
{
return string.IsNullOrWhiteSpace(Domain);
}
// Check for users that contain underscores but are not EMU logins
if (GitHubConstants.InvalidUnderscoreLogins.Contains(userName, StringComparer.OrdinalIgnoreCase))
{
return string.IsNullOrWhiteSpace(Domain);
}
string shortCode = userName.Substring(delim + 1);
return StringComparer.OrdinalIgnoreCase.Equals(Domain, shortCode);
}
public bool Equals(GitHubAuthChallenge other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return string.Equals(Domain, other.Domain, StringComparison.OrdinalIgnoreCase) &&
string.Equals(Enterprise, other.Enterprise, StringComparison.OrdinalIgnoreCase);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals((GitHubAuthChallenge)obj);
}
public override int GetHashCode()
{
int domainHash = Domain is null
? 0
: StringComparer.OrdinalIgnoreCase.GetHashCode(Domain);
int enterpriseHash = Enterprise is null
? 0
: StringComparer.OrdinalIgnoreCase.GetHashCode(Enterprise);
return (domainHash * 1019) ^
(enterpriseHash * 337);
}
}