source: binary-improvements2/WebServer/src/UrlHandlers/SessionHandler.cs@ 402

Last change on this file since 402 was 402, checked in by alloc, 22 months ago
  • Major refactoring
  • Using Utf8Json for (de)serialization
  • Moving APIs to REST
  • Removing dependencies from WebServer and MapRenderer to ServerFixes
File size: 5.5 KB
RevLine 
[391]1using System;
[402]2using System.Collections.Generic;
3using System.IO;
[391]4using System.Net;
[402]5using Platform.Steam;
6using Utf8Json;
[391]7
8namespace Webserver.UrlHandlers {
9 public class SessionHandler : AbsHandler {
[394]10 private const string pageBasePath = "/app";
11 private const string pageErrorPath = "/app/error/";
[402]12
[391]13 private const string steamOpenIdVerifyUrl = "verifysteamopenid";
14 private const string steamLoginUrl = "loginsteam";
[402]15 private const string userPassLoginUrl = "login";
[391]16
17 private readonly ConnectionHandler connectionHandler;
18
[394]19 public SessionHandler (ConnectionHandler _connectionHandler) : base (null) {
[391]20 connectionHandler = _connectionHandler;
21 }
22
23 public override void HandleRequest (RequestContext _context) {
[394]24 if (_context.Request.RemoteEndPoint == null) {
25 _context.Response.Redirect (pageErrorPath + "NoRemoteEndpoint");
[391]26 return;
27 }
28
29 string subpath = _context.RequestPath.Remove (0, urlBasePath.Length);
30
31 if (subpath.StartsWith (steamOpenIdVerifyUrl)) {
[394]32 HandleSteamVerification (_context);
33 return;
34 }
[391]35
[394]36 if (subpath.StartsWith ("logout")) {
37 HandleLogout (_context);
38 return;
39 }
[391]40
[394]41 if (subpath.StartsWith (steamLoginUrl)) {
42 HandleSteamLogin (_context);
43 return;
44 }
[402]45
46 if (subpath.StartsWith (userPassLoginUrl)) {
47 HandleUserPassLogin (_context);
48 return;
49 }
[391]50
[394]51 _context.Response.Redirect (pageErrorPath + "InvalidSessionsCommand");
52 }
53
[402]54 private void HandleUserPassLogin (RequestContext _context) {
55 if (!_context.Request.HasEntityBody) {
56 _context.Response.Redirect (pageErrorPath + "NoLoginData");
57 return;
58 }
59
60 Stream requestInputStream = _context.Request.InputStream;
61
62 byte[] jsonInputData = new byte[_context.Request.ContentLength64];
63 requestInputStream.Read (jsonInputData, 0, (int)_context.Request.ContentLength64);
64
65 IDictionary<string, object> inputJson;
66 try {
67 inputJson = JsonSerializer.Deserialize<IDictionary<string, object>> (jsonInputData);
68 } catch (Exception e) {
69 Log.Error ("Error deserializing JSON from user/password login:");
70 Log.Exception (e);
71 _context.Response.Redirect (pageErrorPath + "InvalidLoginJson");
72 return;
73 }
74
75 if (!inputJson.TryGetValue ("username", out object fieldNode) || fieldNode is not string username) {
76 _context.Response.Redirect (pageErrorPath + "InvalidLoginJson");
77 return;
78 }
79
80 if (!inputJson.TryGetValue ("password", out fieldNode) || fieldNode is not string password) {
81 _context.Response.Redirect (pageErrorPath + "InvalidLoginJson");
82 return;
83 }
84
85 // TODO: Apply login
86
87 string remoteEndpointString = _context.Request.RemoteEndPoint!.ToString ();
88
89 if (username != "test" || password != "123") {
90 // TODO: failed login
91 Log.Out ($"[Web] User/pass login failed from {remoteEndpointString}");
92 _context.Response.Redirect (pageErrorPath + "UserPassInvalid");
93 return;
94 }
95
96 try {
97 // TODO: Match username/password to UserIdentifierAbs / serveradmins.xml
98
99 WebConnection con = connectionHandler.LogIn (new UserIdentifierSteam (76561198066968172ul), _context.Request.RemoteEndPoint.Address);
100 int level = GameManager.Instance.adminTools.GetUserPermissionLevel (con.UserId);
101 Log.Out ($"[Web] User/pass login from {remoteEndpointString} with ID {con.UserId}, permission level {level}");
102
103 Cookie cookie = new Cookie ("sid", con.SessionID, "/") {
104 Expired = false,
105 Expires = DateTime.MinValue,
106 HttpOnly = true,
107 Secure = false
108 };
109 _context.Response.AppendCookie (cookie);
110 _context.Response.Redirect (pageBasePath);
111
112 return;
113 } catch (Exception e) {
114 Log.Error ("[Web] Error during user/pass login:");
115 Log.Exception (e);
116 }
117
118 _context.Response.Redirect (pageErrorPath + "UserPassLoginFailed");
119 }
120
[394]121 private void HandleSteamLogin (RequestContext _context) {
[402]122 string host = $"{(WebUtils.IsSslRedirected (_context.Request) ? "https://" : "http://")}{_context.Request.UserHostName}";
123 string url = OpenID.GetOpenIdLoginUrl (host, $"{host}{urlBasePath}{steamOpenIdVerifyUrl}");
[394]124 _context.Response.Redirect (url);
125 }
126
127 private void HandleLogout (RequestContext _context) {
128 Cookie cookie = new Cookie ("sid", "", "/") {
129 Expired = true
130 };
131 _context.Response.AppendCookie (cookie);
132
133 if (_context.Connection == null) {
134 _context.Response.Redirect (pageErrorPath + "NotLoggedIn");
135 return;
136 }
137
138 connectionHandler.LogOut (_context.Connection.SessionID);
139 _context.Response.Redirect (pageBasePath);
140 }
141
142 private void HandleSteamVerification (RequestContext _context) {
143 string remoteEndpointString = _context.Request.RemoteEndPoint!.ToString ();
144
145 try {
146 ulong id = OpenID.Validate (_context.Request);
147 if (id > 0) {
[402]148 WebConnection con = connectionHandler.LogIn (new UserIdentifierSteam (id), _context.Request.RemoteEndPoint.Address);
[394]149 int level = GameManager.Instance.adminTools.GetUserPermissionLevel (con.UserId);
[402]150 Log.Out ($"[Web] Steam OpenID login from {remoteEndpointString} with ID {con.UserId}, permission level {level}");
[394]151
152 Cookie cookie = new Cookie ("sid", con.SessionID, "/") {
153 Expired = false,
154 Expires = DateTime.MinValue,
155 HttpOnly = true,
156 Secure = false
[391]157 };
158 _context.Response.AppendCookie (cookie);
159 _context.Response.Redirect (pageBasePath);
[394]160
[391]161 return;
162 }
[394]163 } catch (Exception e) {
[399]164 Log.Error ("[Web] Error validating Steam login:");
[394]165 Log.Exception (e);
[391]166 }
167
[399]168 Log.Out ($"[Web] Steam OpenID login failed from {remoteEndpointString}");
[394]169 _context.Response.Redirect (pageErrorPath + "SteamLoginFailed");
170 }
[391]171
172 }
173}
Note: See TracBrowser for help on using the repository browser.