source: TFP-WebServer/WebServer/src/Permissions/AdminApiTokens.cs@ 487

Last change on this file since 487 was 487, checked in by alloc, 5 months ago

1.1.0.1 Release for V 1.0

File size: 4.2 KB
Line 
1using System.Collections.Generic;
2using System.Xml;
3
4namespace Webserver.Permissions {
5 public class AdminApiTokens : AdminSectionAbs {
6 public static AdminApiTokens Instance { get; private set; }
7
8 public AdminApiTokens (AdminTools _parent) : base (_parent, "apitokens") {
9 Instance = this;
10 }
11
12 private readonly Dictionary<string, ApiToken> tokens = new CaseInsensitiveStringDictionary<ApiToken> ();
13
14
15#region IO
16
17 public override void Clear () {
18 tokens.Clear ();
19 }
20
21 public override void ParseElement (XmlElement _childElement) {
22 if (ApiToken.TryParse (_childElement, out ApiToken apiToken)) {
23 tokens [apiToken.Name] = apiToken;
24 }
25 }
26
27 public override void Save (XmlElement _root) {
28 XmlElement adminTokensElem = _root.AddXmlElement (SectionTypeName);
29 adminTokensElem.AddXmlComment (" <token name=\"adminuser1\" secret=\"supersecrettoken\" permission_level=\"0\" /> ");
30
31 foreach ((string _, ApiToken apiToken) in tokens) {
32 apiToken.ToXml (adminTokensElem);
33 }
34 }
35
36#endregion
37
38
39#region Runtime interaction
40
41 public void AddToken (string _name, string _secret, int _permissionLevel) {
42 lock (Parent) {
43 ApiToken apiToken = new ApiToken (_name, _secret, _permissionLevel);
44 tokens[_name] = apiToken;
45 Parent.Save ();
46 }
47 }
48
49 public bool RemoveToken (string _name) {
50 lock (Parent) {
51 bool removed = tokens.Remove (_name);
52 if (removed) {
53 Parent.Save ();
54 }
55
56 return removed;
57 }
58 }
59
60 public Dictionary<string, ApiToken> GetTokens () {
61 lock (Parent) {
62 return tokens;
63 }
64 }
65
66#endregion
67
68 public readonly struct ApiToken {
69 public readonly string Name;
70 public readonly string Secret;
71 public readonly int PermissionLevel;
72
73 public ApiToken (string _name, string _secret, int _permissionLevel) {
74 Name = _name;
75 Secret = _secret;
76 PermissionLevel = _permissionLevel;
77 }
78
79 public void ToXml (XmlElement _parent) {
80 _parent.AddXmlElement ("token")
81 .SetAttrib ("name", Name)
82 .SetAttrib ("secret", Secret)
83 .SetAttrib ("permission_level", PermissionLevel.ToString ());
84 }
85
86 public static bool TryParse (XmlElement _element, out ApiToken _result) {
87 _result = default;
88
89
90 if (!_element.TryGetAttribute ("name", out string name)) {
91 Log.Warning ($"[Web] [Perms] Ignoring apitoken-entry because of missing 'name' attribute: {_element.OuterXml}");
92 return false;
93 }
94
95 if (!_element.TryGetAttribute ("secret", out string secret)) {
96 Log.Warning ($"[Web] [Perms] Ignoring apitoken-entry because of missing 'secret' attribute: {_element.OuterXml}");
97 return false;
98 }
99
100 if (!_element.TryGetAttribute ("permission_level", out string permissionLevelString)) {
101 Log.Warning ($"[Web] [Perms] Ignoring apitoken-entry because of missing 'permission_level' attribute: {_element.OuterXml}");
102 return false;
103 }
104
105 if (!int.TryParse (permissionLevelString, out int permissionLevel)) {
106 Log.Warning (
107 $"[Web] [Perms] Ignoring apitoken-entry because of invalid (non-numeric) value for 'permission_level' attribute: {_element.OuterXml}");
108 return false;
109 }
110
111
112 _result = new ApiToken (name, secret, permissionLevel);
113 return true;
114 }
115 }
116
117
118#region Specials
119
120 public int GetPermissionLevel (string _name, string _secret) {
121 lock (Parent) {
122 if (tokens.TryGetValue (_name, out ApiToken apiToken) && apiToken.Secret == _secret) {
123 return apiToken.PermissionLevel;
124 }
125
126 if (IsCommandlineToken (_name, _secret)) {
127 return 0;
128 }
129
130 return int.MaxValue;
131 }
132 }
133
134 private bool commandlineChecked;
135 private string commandlineTokenName;
136 private string commandlineTokenSecret;
137
138 private bool IsCommandlineToken (string _name, string _secret) {
139 if (!commandlineChecked) {
140 commandlineTokenName = GameUtils.GetLaunchArgument ("webapitokenname");
141 commandlineTokenSecret = GameUtils.GetLaunchArgument ("webapitokensecret");
142
143 commandlineChecked = true;
144 }
145
146 if (string.IsNullOrEmpty (commandlineTokenName) || string.IsNullOrEmpty (commandlineTokenSecret)) {
147 return false;
148 }
149
150 return _name == commandlineTokenName && _secret == commandlineTokenSecret;
151 }
152
153#endregion
154 }
155}
Note: See TracBrowser for help on using the repository browser.