Ignore:
Timestamp:
Feb 16, 2023, 3:50:53 PM (21 months ago)
Author:
alloc
Message:

Latest state including reworking to the permissions system

Location:
binary-improvements2/WebServer/src/UrlHandlers
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • binary-improvements2/WebServer/src/UrlHandlers/AbsHandler.cs

    r391 r404  
     1using Webserver.Permissions;
     2
    13namespace Webserver.UrlHandlers {
    24        public abstract class AbsHandler {
     
    1012                protected AbsHandler (string _moduleName, int _defaultPermissionLevel = 0) {
    1113                        moduleName = _moduleName;
    12                         WebPermissions.Instance.AddKnownModule (_moduleName, _defaultPermissionLevel);
     14                        AdminWebModules.Instance.AddKnownModule (_moduleName, _defaultPermissionLevel);
    1315                }
    1416
     
    1618
    1719                public virtual bool IsAuthorizedForHandler (WebConnection _user, int _permissionLevel) {
    18                         return moduleName == null || WebPermissions.Instance.ModuleAllowedWithLevel (moduleName, _permissionLevel);
     20                        return moduleName == null || AdminWebModules.Instance.ModuleAllowedWithLevel (moduleName, _permissionLevel);
    1921                }
    2022
  • binary-improvements2/WebServer/src/UrlHandlers/ApiHandler.cs

    r402 r404  
    33using System.Net;
    44using System.Reflection;
     5using Webserver.Permissions;
    56using Webserver.WebAPI;
    67
     
    1011
    1112                public ApiHandler () : base (null) {
    12 
    1313                }
     14               
     15                private static readonly Type[] apiWithParentCtorTypes = { typeof (Web) };
     16                private static readonly object[] apiWithParentCtorArgs = new object[1];
     17                private static readonly Type[] apiEmptyCtorTypes = { };
     18                private static readonly object[] apiEmptyCtorArgs = { };
    1419
    1520                public override void SetBasePathAndParent (Web _parent, string _relativePath) {
    1621                        base.SetBasePathAndParent (_parent, _relativePath);
    1722
    18                         Type[] apiWithParentCtorTypes = { typeof (Web) };
    19                         object[] apiWithParentCtorArgs = { _parent };
     23                        apiWithParentCtorArgs[0] = _parent;
    2024
    21                         Type[] apiEmptyCtorTypes = { };
    22                         object[] apiEmptyCtorArgs = { };
    23                        
    24                        
    25                         ReflectionHelpers.FindTypesImplementingBase (typeof (AbsWebAPI), _type => {
    26                                 ConstructorInfo ctor = _type.GetConstructor (apiWithParentCtorTypes);
    27                                 if (ctor != null) {
    28                                         AbsWebAPI apiInstance = (AbsWebAPI) ctor.Invoke (apiWithParentCtorArgs);
    29                                         addApi (apiInstance);
    30                                         return;
    31                                 }
    32                                        
    33                                 ctor = _type.GetConstructor (apiEmptyCtorTypes);
    34                                 if (ctor != null) {
    35                                         AbsWebAPI apiInstance = (AbsWebAPI) ctor.Invoke (apiEmptyCtorArgs);
    36                                         addApi (apiInstance);
    37                                 }
    38                         });
     25                        ReflectionHelpers.FindTypesImplementingBase (typeof (AbsWebAPI), apiFoundCallback);
    3926
    4027                        // Permissions that don't map to a real API
     
    4330                }
    4431
     32                private void apiFoundCallback (Type _type) {
     33                        ConstructorInfo ctor = _type.GetConstructor (apiWithParentCtorTypes);
     34                        if (ctor != null) {
     35                                AbsWebAPI apiInstance = (AbsWebAPI)ctor.Invoke (apiWithParentCtorArgs);
     36                                addApi (apiInstance);
     37                                return;
     38                        }
     39
     40                        ctor = _type.GetConstructor (apiEmptyCtorTypes);
     41                        if (ctor != null) {
     42                                AbsWebAPI apiInstance = (AbsWebAPI)ctor.Invoke (apiEmptyCtorArgs);
     43                                addApi (apiInstance);
     44                        }
     45                }
     46
    4547                private void addApi (AbsWebAPI _api) {
    4648                        apis.Add (_api.Name, _api);
    47                         WebPermissions.Instance.AddKnownModule ($"webapi.{_api.Name}", _api.DefaultPermissionLevel ());
     49                        AdminWebModules.Instance.AddKnownModule ($"webapi.{_api.Name}", _api.DefaultPermissionLevel ());
    4850                }
    4951
     
    9294
    9395                private bool IsAuthorizedForApi (string _apiName, int _permissionLevel) {
    94                         return WebPermissions.Instance.ModuleAllowedWithLevel ($"webapi.{_apiName}", _permissionLevel);
     96                        return AdminWebModules.Instance.ModuleAllowedWithLevel ($"webapi.{_apiName}", _permissionLevel);
    9597                }
    9698        }
  • binary-improvements2/WebServer/src/UrlHandlers/SessionHandler.cs

    r402 r404  
    55using Platform.Steam;
    66using Utf8Json;
     7using Webserver.Permissions;
    78
    89namespace Webserver.UrlHandlers {
     
    1011                private const string pageBasePath = "/app";
    1112                private const string pageErrorPath = "/app/error/";
    12                
     13
    1314                private const string steamOpenIdVerifyUrl = "verifysteamopenid";
    1415                private const string steamLoginUrl = "loginsteam";
     16                private const string steamLoginFailedPage = "SteamLoginFailed";
     17
    1518                private const string userPassLoginUrl = "login";
    1619
     
    2932                        string subpath = _context.RequestPath.Remove (0, urlBasePath.Length);
    3033
     34                        string remoteEndpointString = _context.Request.RemoteEndPoint!.ToString ();
     35
    3136                        if (subpath.StartsWith (steamOpenIdVerifyUrl)) {
    32                                 HandleSteamVerification (_context);
     37                                HandleSteamVerification (_context, remoteEndpointString);
    3338                                return;
    3439                        }
     
    4348                                return;
    4449                        }
    45                        
     50
    4651                        if (subpath.StartsWith (userPassLoginUrl)) {
    47                                 HandleUserPassLogin (_context);
     52                                HandleUserPassLogin (_context, remoteEndpointString);
    4853                                return;
    4954                        }
     
    5257                }
    5358
    54                 private void HandleUserPassLogin (RequestContext _context) {
     59                private void HandleUserPassLogin (RequestContext _context, string _remoteEndpointString) {
    5560                        if (!_context.Request.HasEntityBody) {
    5661                                _context.Response.Redirect (pageErrorPath + "NoLoginData");
     
    8388                        }
    8489
    85                         // TODO: Apply login
     90                        AdminWebUsers.WebUser? webUser = AdminWebUsers.Instance.GetUser (username, password);
    8691
    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                        if (!webUser.HasValue) {
     93                                Log.Out ($"[Web] User/pass login failed from {_remoteEndpointString}");
    9294                                _context.Response.Redirect (pageErrorPath + "UserPassInvalid");
    9395                                return;
    9496                        }
    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}");
    10297
    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");
     98                        HandleUserIdLogin (_context, _remoteEndpointString, "user/pass", "UserPassLoginFailed", webUser.Value.Name, webUser.Value.PlatformUser, webUser.Value.CrossPlatformUser);
    11999                }
    120100
     
    140120                }
    141121
    142                 private void HandleSteamVerification (RequestContext _context) {
    143                         string remoteEndpointString = _context.Request.RemoteEndPoint!.ToString ();
    144 
     122                private void HandleSteamVerification (RequestContext _context, string _remoteEndpointString) {
     123                        ulong id;
    145124                        try {
    146                                 ulong id = OpenID.Validate (_context.Request);
    147                                 if (id > 0) {
    148                                         WebConnection con = connectionHandler.LogIn (new UserIdentifierSteam (id), _context.Request.RemoteEndPoint.Address);
    149                                         int level = GameManager.Instance.adminTools.GetUserPermissionLevel (con.UserId);
    150                                         Log.Out ($"[Web] Steam OpenID login from {remoteEndpointString} with ID {con.UserId}, permission level {level}");
    151 
    152                                         Cookie cookie = new Cookie ("sid", con.SessionID, "/") {
    153                                                 Expired = false,
    154                                                 Expires = DateTime.MinValue,
    155                                                 HttpOnly = true,
    156                                                 Secure = false
    157                                         };
    158                                         _context.Response.AppendCookie (cookie);
    159                                         _context.Response.Redirect (pageBasePath);
    160 
    161                                         return;
    162                                 }
     125                                id = OpenID.Validate (_context.Request);
    163126                        } catch (Exception e) {
    164                                 Log.Error ("[Web] Error validating Steam login:");
     127                                Log.Error ($"[Web] Error validating Steam login from {_remoteEndpointString}:");
    165128                                Log.Exception (e);
     129                                _context.Response.Redirect (pageErrorPath + steamLoginFailedPage);
     130                                return;
    166131                        }
    167132
    168                         Log.Out ($"[Web] Steam OpenID login failed from {remoteEndpointString}");
    169                         _context.Response.Redirect (pageErrorPath + "SteamLoginFailed");
     133                        if (id <= 0) {
     134                                Log.Out ($"[Web] Steam OpenID login failed (invalid ID) from {_remoteEndpointString}");
     135                                _context.Response.Redirect (pageErrorPath + steamLoginFailedPage);
     136                                return;
     137                        }
     138
     139                        UserIdentifierSteam userId = new UserIdentifierSteam (id);
     140                        HandleUserIdLogin (_context, _remoteEndpointString, "Steam OpenID", steamLoginFailedPage, userId.ToString (), userId);
    170141                }
    171142
     143                private void HandleUserIdLogin (RequestContext _context, string _remoteEndpointString, string _loginName, string _errorPage, string _username,
     144                        PlatformUserIdentifierAbs _userId, PlatformUserIdentifierAbs _crossUserId = null) {
     145                        try {
     146                                WebConnection con = connectionHandler.LogIn (_context.Request.RemoteEndPoint!.Address, _username, _userId, _crossUserId);
     147
     148                                int level1 = GameManager.Instance.adminTools.Users.GetUserPermissionLevel (_userId);
     149                                int level2 = int.MaxValue;
     150                                if (_crossUserId != null) {
     151                                        level2 = GameManager.Instance.adminTools.Users.GetUserPermissionLevel (_crossUserId);
     152                                }
     153
     154                                int higherLevel = Math.Min (level1, level2);
     155
     156                                Log.Out ($"[Web] {_loginName} login from {_remoteEndpointString}, name {_username} with ID {_userId}, CID {(_crossUserId != null ? _crossUserId : "none")}, permission level {higherLevel}");
     157                                Cookie cookie = new Cookie ("sid", con.SessionID, "/") {
     158                                        Expired = false,
     159                                        Expires = DateTime.MinValue,
     160                                        HttpOnly = true,
     161                                        Secure = false
     162                                };
     163                                _context.Response.AppendCookie (cookie);
     164                                _context.Response.Redirect (pageBasePath);
     165                        } catch (Exception e) {
     166                                Log.Error ($"[Web] Error during {_loginName} login:");
     167                                Log.Exception (e);
     168                                _context.Response.Redirect (pageErrorPath + _errorPage);
     169                        }
     170                }
    172171        }
    173172}
  • binary-improvements2/WebServer/src/UrlHandlers/SseHandler.cs

    r402 r404  
    44using System.Reflection;
    55using System.Threading;
     6using Webserver.Permissions;
    67using Webserver.SSE;
    78
     
    1718                private bool shutdown;
    1819
     20                private static readonly Type[] ctorTypes = { typeof (SseHandler) };
     21                private static readonly object[] ctorParams = new object[1];
     22
    1923                public SseHandler (string _moduleName = null) : base (_moduleName) {
    20                         Type[] ctorTypes = { typeof (SseHandler) };
    21                         object[] ctorParams = { this };
     24                        ctorParams[0] = this;
    2225
    23                         foreach (Type t in Assembly.GetExecutingAssembly ().GetTypes ()) {
    24                                 if (t.IsAbstract || !t.IsSubclassOf (typeof (AbsEvent))) {
    25                                         continue;
    26                                 }
     26                        ReflectionHelpers.FindTypesImplementingBase (typeof (AbsEvent), apiFoundCallback);
     27                }
    2728
    28                                 ConstructorInfo ctor = t.GetConstructor (ctorTypes);
    29                                 if (ctor == null) {
    30                                         continue;
    31                                 }
     29                private void apiFoundCallback (Type _type) {
     30                        ConstructorInfo ctor = _type.GetConstructor (ctorTypes);
     31                        if (ctor == null) {
     32                                return;
     33                        }
    3234
    33                                 AbsEvent apiInstance = (AbsEvent)ctor.Invoke (ctorParams);
    34                                 AddEvent (apiInstance.Name, apiInstance);
    35                         }
     35                        AbsEvent apiInstance = (AbsEvent)ctor.Invoke (ctorParams);
     36                        AddEvent (apiInstance.Name, apiInstance);
    3637                }
    3738
     
    5253                public void AddEvent (string _eventName, AbsEvent _eventInstance) {
    5354                        events.Add (_eventName, _eventInstance);
    54                         WebPermissions.Instance.AddKnownModule ($"webevent.{_eventName}", _eventInstance.DefaultPermissionLevel ());
     55                        AdminWebModules.Instance.AddKnownModule ($"webevent.{_eventName}", _eventInstance.DefaultPermissionLevel ());
    5556                }
    5657
     
    8990
    9091                private bool IsAuthorizedForEvent (string _eventName, int _permissionLevel) {
    91                         return WebPermissions.Instance.ModuleAllowedWithLevel ($"webevent.{_eventName}", _permissionLevel);
     92                        return AdminWebModules.Instance.ModuleAllowedWithLevel ($"webevent.{_eventName}", _permissionLevel);
    9293                }
    9394
  • binary-improvements2/WebServer/src/UrlHandlers/UserStatusHandler.cs

    r402 r404  
     1using System.Collections.Generic;
    12using Utf8Json;
     3using Webserver.Permissions;
    24
    35namespace Webserver.UrlHandlers {
     
    810                private static readonly byte[] jsonLoggedInKey = JsonWriter.GetEncodedPropertyNameWithBeginObject ("loggedIn");
    911                private static readonly byte[] jsonUsernameKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("username");
     12                private static readonly byte[] jsonPermissionLevelKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("permissionLevel");
    1013                private static readonly byte[] jsonPermissionsKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("permissions");
    1114
     
    2023                       
    2124                        writer.WriteRaw (jsonUsernameKey);
    22                         writer.WriteString (_context.Connection != null ? _context.Connection.UserId.ToString () : string.Empty);
     25                        writer.WriteString (_context.Connection != null ? _context.Connection.Username : string.Empty);
     26                       
     27                        writer.WriteRaw (jsonPermissionLevelKey);
     28                        writer.WriteInt32 (_context.PermissionLevel);
    2329                       
    2430                        writer.WriteRaw (jsonPermissionsKey);
    2531                        writer.WriteBeginArray ();
    2632
    27                         bool first = true;
    28                         foreach (WebPermissions.WebModulePermission perm in WebPermissions.Instance.GetModules ()) {
    29                                 if (!first) {
     33                        List<AdminWebModules.WebModule> list = AdminWebModules.Instance.GetModules ();
     34                        for (int i = 0; i < list.Count; i++) {
     35                                AdminWebModules.WebModule perm = list [i];
     36                               
     37                                if (i > 0) {
    3038                                        writer.WriteValueSeparator ();
    3139                                }
    3240
    33                                 first = false;
    34                                
    3541                                writer.WriteRaw (jsonModuleKey);
    36                                 writer.WriteString (perm.module);
    37                                
     42                                writer.WriteString (perm.Name);
     43
    3844                                writer.WriteRaw (jsonAllowedKey);
    39                                 writer.WriteBoolean (perm.permissionLevel >= _context.PermissionLevel);
    40                                
     45                                writer.WriteBoolean (perm.PermissionLevel >= _context.PermissionLevel);
     46
    4147                                writer.WriteEndObject ();
    4248                        }
Note: See TracChangeset for help on using the changeset viewer.