Changeset 404


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
Files:
6 added
2 deleted
18 edited

Legend:

Unmodified
Added
Removed
  • binary-improvements2/CommandExtensions/src/Commands/ListKnownPlayers.cs

    r391 r404  
    6161                                        if (
    6262                                                (!onlineOnly || player.IsOnline)
    63                                                 && (!notBannedOnly || !admTools.IsBanned (userId, out _, out _))
     63                                                && (!notBannedOnly || !admTools.Blacklist.IsBanned (userId, out _, out _))
    6464                                                && (nameFilter.Length == 0 || player.Name.ContainsCaseInsensitive (nameFilter))
    6565                                        ) {
  • binary-improvements2/WebServer/WebServer.csproj

    r402 r404  
    4343  </PropertyGroup>
    4444  <ItemGroup>
     45    <Reference Include="0Harmony, Version=2.10.0.0, Culture=neutral, PublicKeyToken=null">
     46      <HintPath>..\7dtd-binaries\0Harmony.dll</HintPath>
     47      <Private>False</Private>
     48    </Reference>
    4549    <Reference Include="Assembly-CSharp-firstpass, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
    4650      <HintPath>..\7dtd-binaries\Assembly-CSharp-firstpass.dll</HintPath>
     
    6569    <Reference Include="System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    6670      <HintPath>..\7dtd-binaries\System.Xml.dll</HintPath>
     71      <Private>False</Private>
     72    </Reference>
     73    <Reference Include="System.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     74      <HintPath>..\7dtd-binaries\System.Xml.Linq.dll</HintPath>
    6775      <Private>False</Private>
    6876    </Reference>
     
    93101  </ItemGroup>
    94102  <ItemGroup>
     103    <Compile Include="src\Commands\CreateWebUser.cs" />
    95104    <Compile Include="src\FileCache\AbstractCache.cs" />
    96105    <Compile Include="src\FileCache\DirectAccess.cs" />
     
    101110    <Compile Include="src\LiveData\Hostiles.cs" />
    102111    <Compile Include="src\ModApi.cs" />
     112    <Compile Include="src\Permissions\AdminWebModules.cs" />
     113    <Compile Include="src\Permissions\AdminApiTokens.cs" />
     114    <Compile Include="src\Permissions\AdminWebUsers.cs" />
     115    <Compile Include="src\Permissions\RegisterModules.cs" />
    103116    <Compile Include="src\UrlHandlers\ApiHandler.cs" />
    104117    <Compile Include="src\UrlHandlers\SseHandler.cs" />
     
    123136    <Compile Include="src\AssemblyInfo.cs" />
    124137    <Compile Include="src\Commands\EnableOpenIDDebug.cs" />
    125     <Compile Include="src\Commands\ReloadWebPermissions.cs" />
    126138    <Compile Include="src\Commands\WebPermissionsCmd.cs" />
    127139    <Compile Include="src\Commands\WebTokens.cs" />
     
    144156    <Compile Include="src\WebConnection.cs" />
    145157    <Compile Include="src\WebMod.cs" />
    146     <Compile Include="src\WebPermissions.cs" />
    147158    <Compile Include="src\WebUtils.cs" />
    148159  </ItemGroup>
  • binary-improvements2/WebServer/src/Commands/WebPermissionsCmd.cs

    r391 r404  
    11using System.Collections.Generic;
    22using JetBrains.Annotations;
     3using Webserver.Permissions;
    34
    45namespace Webserver.Commands {
     
    4445                        }
    4546
    46                         if (!WebPermissions.Instance.IsKnownModule (_params [1])) {
     47                        if (!AdminWebModules.Instance.IsKnownModule (_params [1])) {
    4748                                SdtdConsole.Instance.Output ($"\"{_params [1]}\" is not a valid web function.");
    4849                                return;
     
    5455                        }
    5556
    56                         WebPermissions.Instance.AddModulePermission (_params [1], level);
     57                        AdminWebModules.Instance.AddModule (_params [1], level);
    5758                        SdtdConsole.Instance.Output ($"{_params [1]} added with permission level of {level}.");
    5859                }
     
    6465                        }
    6566
    66                         if (!WebPermissions.Instance.IsKnownModule (_params [1])) {
     67                        if (!AdminWebModules.Instance.IsKnownModule (_params [1])) {
    6768                                SdtdConsole.Instance.Output ($"\"{_params [1]}\" is not a valid web function.");
    6869                                return;
    6970                        }
    7071
    71                         WebPermissions.Instance.RemoveModulePermission (_params [1]);
     72                        AdminWebModules.Instance.RemoveModule (_params [1]);
    7273                        SdtdConsole.Instance.Output ($"{_params [1]} removed from permissions list.");
    7374                }
     
    7677                        SdtdConsole.Instance.Output ("Defined web function permissions:");
    7778                        SdtdConsole.Instance.Output ("  Level: Web function");
    78                         foreach (WebPermissions.WebModulePermission wmp in WebPermissions.Instance.GetModules ()) {
    79                                 SdtdConsole.Instance.Output ($"  {wmp.permissionLevel,5}: {wmp.module}");
     79                       
     80                        List<AdminWebModules.WebModule> wmps = AdminWebModules.Instance.GetModules ();
     81                        for (int i = 0; i < wmps.Count; i++) {
     82                                AdminWebModules.WebModule wmp = wmps [i];
     83                               
     84                                SdtdConsole.Instance.Output ($"  {wmp.PermissionLevel,5}: {wmp.Name}");
    8085                        }
    8186                }
  • binary-improvements2/WebServer/src/Commands/WebTokens.cs

    r402 r404  
    22using System.Text.RegularExpressions;
    33using JetBrains.Annotations;
     4using Webserver.Permissions;
    45
    56namespace Webserver.Commands {
     
    1920                        return "Set/get webtoken permission levels. A level of 0 is maximum permission.\n" +
    2021                               "Usage:\n" +
    21                                "   webtokens add <username> <usertoken> <level>\n" +
    22                                "   webtokens remove <username>\n" +
     22                               "   webtokens add <tokenname> <tokensecret> <level>\n" +
     23                               "   webtokens remove <tokenname>\n" +
    2324                               "   webtokens list";
    2425                }
     
    4748
    4849                        if (string.IsNullOrEmpty (_params [1])) {
    49                                 SdtdConsole.Instance.Output ("Argument 'username' is empty.");
     50                                SdtdConsole.Instance.Output ("Argument 'tokenname' is empty.");
    5051                                return;
    5152                        }
     
    5354                        if (!validNameTokenMatcher.IsMatch (_params [1])) {
    5455                                SdtdConsole.Instance.Output (
    55                                         "Argument 'username' may only contain characters (A-Z, a-z), digits (0-9) and underscores (_).");
     56                                        "Argument 'tokenname' may only contain characters (A-Z, a-z), digits (0-9) and underscores (_).");
    5657                                return;
    5758                        }
    5859
    5960                        if (string.IsNullOrEmpty (_params [2])) {
    60                                 SdtdConsole.Instance.Output ("Argument 'usertoken' is empty.");
     61                                SdtdConsole.Instance.Output ("Argument 'tokensecret' is empty.");
    6162                                return;
    6263                        }
     
    6465                        if (!validNameTokenMatcher.IsMatch (_params [2])) {
    6566                                SdtdConsole.Instance.Output (
    66                                         "Argument 'usertoken' may only contain characters (A-Z, a-z), digits (0-9) and underscores (_).");
     67                                        "Argument 'tokensecret' may only contain characters (A-Z, a-z), digits (0-9) and underscores (_).");
    6768                                return;
    6869                        }
     
    7374                        }
    7475
    75                         WebPermissions.Instance.AddAdmin (_params [1], _params [2], level);
    76                         SdtdConsole.Instance.Output ($"Web user with name={_params [1]} and password={_params [2]} added with permission level of {level}.");
     76                        AdminApiTokens.Instance.AddToken (_params [1], _params [2], level);
     77                        SdtdConsole.Instance.Output ($"Web API token with name={_params [1]} and secret={_params [2]} added with permission level of {level}.");
    7778                }
    7879
     
    8485
    8586                        if (string.IsNullOrEmpty (_params [1])) {
    86                                 SdtdConsole.Instance.Output ("Argument 'username' is empty.");
     87                                SdtdConsole.Instance.Output ("Argument 'tokenname' is empty.");
    8788                                return;
    8889                        }
     
    9091                        if (!validNameTokenMatcher.IsMatch (_params [1])) {
    9192                                SdtdConsole.Instance.Output (
    92                                         "Argument 'username' may only contain characters (A-Z, a-z), digits (0-9) and underscores (_).");
     93                                        "Argument 'tokenname' may only contain characters (A-Z, a-z), digits (0-9) and underscores (_).");
    9394                                return;
    9495                        }
    9596
    96                         WebPermissions.Instance.RemoveAdmin (_params [1]);
    97                         SdtdConsole.Instance.Output ($"{_params [1]} removed from web user permissions list.");
     97                        AdminApiTokens.Instance.RemoveToken (_params [1]);
     98                        SdtdConsole.Instance.Output ($"{_params [1]} removed from web API token permissions list.");
    9899                }
    99100
    100101                private void ExecuteList () {
    101                         SdtdConsole.Instance.Output ("Defined webuser permissions:");
    102                         SdtdConsole.Instance.Output ("  Level: Name / Token");
    103                         foreach (WebPermissions.AdminToken at in WebPermissions.Instance.GetAdmins ()) {
    104                                 SdtdConsole.Instance.Output ($"  {at.permissionLevel,5}: {at.name} / {at.token}");
     102                        SdtdConsole.Instance.Output ("Defined web API token permissions:");
     103                        SdtdConsole.Instance.Output ("  Level: Name / Secret");
     104                        foreach ((string _, AdminApiTokens.ApiToken apiToken) in AdminApiTokens.Instance.GetTokens ()) {
     105                                SdtdConsole.Instance.Output ($"  {apiToken.PermissionLevel,5}: {apiToken.Name} / {apiToken.Secret}");
    105106                        }
    106107                }
  • binary-improvements2/WebServer/src/ConnectionHandler.cs

    r402 r404  
    3131                }
    3232
    33                 public WebConnection LogIn (PlatformUserIdentifierAbs _userId, IPAddress _ip) {
     33                public WebConnection LogIn (IPAddress _ip, string _username, PlatformUserIdentifierAbs _userId, PlatformUserIdentifierAbs _crossUserId = null) {
    3434                        string sessionId = Guid.NewGuid ().ToString ();
    35                         WebConnection con = new WebConnection (sessionId, _ip, _userId);
     35                        WebConnection con = new WebConnection (sessionId, _ip, _username, _userId, _crossUserId);
    3636                        connections.Add (sessionId, con);
    3737                        return con;
  • binary-improvements2/WebServer/src/ModApi.cs

    r391 r404  
     1using System.Reflection;
     2using HarmonyLib;
    13using JetBrains.Annotations;
    24using Webserver.UrlHandlers;
     
    1214                        ModEvents.GameShutdown.RegisterHandler (GameShutdown);
    1315                        modInstance = _modInstance;
     16
     17                        Harmony.CreateAndPatchAll (Assembly.GetExecutingAssembly ());
    1418                }
    1519
  • 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                        }
  • binary-improvements2/WebServer/src/Web.cs

    r402 r404  
    66using UnityEngine;
    77using Webserver.FileCache;
     8using Webserver.Permissions;
    89using Webserver.UrlHandlers;
    910using Cookie = System.Net.Cookie;
     
    2526                private readonly Version httpProtocolVersion = new Version(1, 1);
    2627
     28                private readonly AsyncCallback handleRequestDelegate;
     29
    2730                public Web (string _modInstancePath) {
    2831                        try {
     
    8184                                // listener.Prefixes.Add ($"http://[::1]:{webPort}/");
    8285                                listener.Start ();
    83                                 listener.BeginGetContext (HandleRequest, listener);
     86                                handleRequestDelegate = HandleRequest;
     87                                listener.BeginGetContext (handleRequestDelegate, listener);
    8488
    8589                                SdtdConsole.Instance.RegisterServer (this);
     
    250254#if ENABLE_PROFILER
    251255                        } finally {
    252                                 listenerInstance.BeginGetContext (HandleRequest, listenerInstance);
     256                                listenerInstance.BeginGetContext (handleRequestDelegate, listenerInstance);
    253257                                UnityEngine.Profiling.Profiler.EndThreadProfiling ();
    254258                        }
     
    297301                                _con = connectionHandler.IsLoggedIn (sessionId, reqRemoteEndPoint.Address);
    298302                                if (_con != null) {
    299                                         return GameManager.Instance.adminTools.GetUserPermissionLevel (_con.UserId);
    300                                 }
    301                         }
    302 
    303                         if (_req.QueryString ["adminuser"] == null || _req.QueryString ["admintoken"] == null) {
     303                                        int level1 = GameManager.Instance.adminTools.Users.GetUserPermissionLevel (_con.UserId);
     304                                        int level2 = int.MaxValue;
     305                                        if (_con.CrossplatformUserId != null) {
     306                                                level2 = GameManager.Instance.adminTools.Users.GetUserPermissionLevel (_con.CrossplatformUserId);
     307                                        }
     308
     309                                        return Math.Min (level1, level2);
     310                                }
     311                        }
     312
     313                        if (!_req.Headers.TryGetValue ("X-SDTD-API-TOKENNAME", out string apiTokenName) ||
     314                            !_req.Headers.TryGetValue ("X-SDTD-API-SECRET", out string apiTokenSecret)) {
    304315                                return guestPermissionLevel;
    305316                        }
    306317
    307                         WebPermissions.AdminToken admin = WebPermissions.Instance.GetWebAdmin (_req.QueryString ["adminuser"],
    308                                 _req.QueryString ["admintoken"]);
    309                         if (admin != null) {
    310                                 return admin.permissionLevel;
     318                        int adminLevel = AdminApiTokens.Instance.GetPermissionLevel (apiTokenName, apiTokenSecret);
     319                        if (adminLevel < int.MaxValue) {
     320                                return adminLevel;
    311321                        }
    312322
  • binary-improvements2/WebServer/src/WebAPI/APIs/Command.cs

    r402 r404  
    2525
    2626                        if (string.IsNullOrEmpty (id)) {
    27                                 bool first = true;
    28                                 foreach (IConsoleCommand cc in SdtdConsole.Instance.GetCommands ()) {
    29                                         if (!first) {
     27                                IList<IConsoleCommand> ccs = SdtdConsole.Instance.GetCommands ();
     28                                for (int i = 0; i < ccs.Count; i++) {
     29                                        IConsoleCommand cc = ccs [i];
     30                                       
     31                                        if (i > 0) {
    3032                                                writer.WriteValueSeparator ();
    3133                                        }
    32 
    33                                         first = false;
    3434
    3535                                        writeCommandJson (ref writer, cc, permissionLevel);
     
    8181                        _writer.WriteString (_command.GetHelp ());
    8282                               
    83                         int commandPermissionLevel = GameManager.Instance.adminTools.GetCommandPermissionLevel (_command.GetCommands ());
     83                        int commandPermissionLevel = GameManager.Instance.adminTools.Commands.GetCommandPermissionLevel (_command.GetCommands ());
    8484                        _writer.WriteRaw (jsonAllowedKey);
    8585                        _writer.WriteBoolean (_userPermissionLevel <= commandPermissionLevel);
     
    117117                        }
    118118
    119                         int commandPermissionLevel = GameManager.Instance.adminTools.GetCommandPermissionLevel (command.GetCommands ());
     119                        int commandPermissionLevel = GameManager.Instance.adminTools.Commands.GetCommandPermissionLevel (command.GetCommands ());
    120120
    121121                        if (_context.PermissionLevel > commandPermissionLevel) {
  • binary-improvements2/WebServer/src/WebAPI/APIs/ServerInfo.cs

    r402 r404  
     1using System.Collections.Generic;
    12using JetBrains.Annotations;
    23using Utf8Json;
     
    2223                        GameServerInfo gsi = ConnectionManager.Instance.LocalServerInfo;
    2324
    24                         bool first = true;
    25                        
    26                        
     25                        IList<GameInfoString> list = EnumUtils.Values<GameInfoString> ();
     26                        for (int i = 0; i < list.Count; i++) {
     27                                GameInfoString stringGamePref = list [i];
    2728
    28                         foreach (GameInfoString stringGamePref in EnumUtils.Values<GameInfoString> ()) {
    29                                 string value = gsi.GetValue (stringGamePref);
    30 
    31                                 if (!first) {
     29                                if (i > 0) {
    3230                                        writer.WriteValueSeparator ();
    3331                                }
    3432
    35                                 first = false;
    36                                
    3733                                writer.WriteString (stringGamePref.ToStringCached ());
    3834                                writer.WriteNameSeparator ();
    39                                
     35
    4036                                writer.WriteRaw (keyType);
    4137                                writer.WriteString ("string");
    42                                
     38
    4339                                writer.WriteRaw (keyValue);
    44                                 writer.WriteString (value);
    45                                
     40                                writer.WriteString (gsi.GetValue (stringGamePref));
     41
    4642                                writer.WriteEndObject ();
    4743                        }
    4844
    49                         foreach (GameInfoInt intGamePref in EnumUtils.Values<GameInfoInt> ()) {
    50                                 int value = gsi.GetValue (intGamePref);
     45                        IList<GameInfoInt> ints = EnumUtils.Values<GameInfoInt> ();
     46                        for (int i = 0; i < ints.Count; i++) {
     47                                GameInfoInt intGamePref = ints [i];
    5148
    52                                 if (!first) {
     49                                if (i > 0) {
    5350                                        writer.WriteValueSeparator ();
    5451                                }
    5552
    56                                 first = false;
    57                                
    5853                                writer.WriteString (intGamePref.ToStringCached ());
    5954                                writer.WriteNameSeparator ();
    60                                
     55
    6156                                writer.WriteRaw (keyType);
    6257                                writer.WriteString ("int");
    63                                
     58
    6459                                writer.WriteRaw (keyValue);
    65                                 writer.WriteInt32 (value);
    66                                
     60                                writer.WriteInt32 (gsi.GetValue (intGamePref));
     61
    6762                                writer.WriteEndObject ();
    6863                        }
    6964
    70                         foreach (GameInfoBool boolGamePref in EnumUtils.Values<GameInfoBool> ()) {
    71                                 bool value = gsi.GetValue (boolGamePref);
     65                        IList<GameInfoBool> prefs = EnumUtils.Values<GameInfoBool> ();
     66                        for (int i = 0; i < prefs.Count; i++) {
     67                                GameInfoBool boolGamePref = prefs [i];
    7268
    73                                 if (!first) {
     69                                if (i > 0) {
    7470                                        writer.WriteValueSeparator ();
    7571                                }
    7672
    77                                 first = false;
    78                                
    7973                                writer.WriteString (boolGamePref.ToStringCached ());
    8074                                writer.WriteNameSeparator ();
    81                                
     75
    8276                                writer.WriteRaw (keyType);
    8377                                writer.WriteString ("bool");
    84                                
     78
    8579                                writer.WriteRaw (keyValue);
    86                                 writer.WriteBoolean (value);
    87                                
     80                                writer.WriteBoolean (gsi.GetValue (boolGamePref));
     81
    8882                                writer.WriteEndObject ();
    8983                        }
    90                        
     84
    9185                        writer.WriteEndObject ();
    9286                       
  • binary-improvements2/WebServer/src/WebAPI/AbsRestApi.cs

    r402 r404  
    9595                }
    9696
    97                 protected void SendErrorResult (RequestContext _context, HttpStatusCode _statusCode, byte[] _jsonInputData = null, string _errorCode = null, Exception _exception = null) {
    98                         PrepareEnvelopedResult (out JsonWriter writer);
    99                         writer.WriteRaw (JsonEmptyData);
    100                         SendEnvelopedResult (_context, ref writer, _statusCode, _jsonInputData, _errorCode, _exception);
    101                 }
    102 
    10397                static AbsRestApi () {
    10498                        JsonWriter writer = new JsonWriter ();
     
    108102                }
    109103
     104                protected virtual void HandleRestGet (RequestContext _context) {
     105                        SendErrorResult (_context, HttpStatusCode.MethodNotAllowed, null, "Unsupported");
     106                }
     107
     108                protected virtual void HandleRestPost (RequestContext _context, IDictionary<string, object> _jsonInput, byte[] _jsonInputData) {
     109                        SendErrorResult (_context, HttpStatusCode.MethodNotAllowed, _jsonInputData, "Unsupported");
     110                }
     111
     112                protected virtual void HandleRestPut (RequestContext _context, IDictionary<string, object> _jsonInput, byte[] _jsonInputData) {
     113                        SendErrorResult (_context, HttpStatusCode.MethodNotAllowed, _jsonInputData, "Unsupported");
     114                }
     115
     116                protected virtual void HandleRestDelete (RequestContext _context) {
     117                        SendErrorResult (_context, HttpStatusCode.MethodNotAllowed, null, "Unsupported");
     118                }
     119
     120
     121#region Helpers
     122
    110123                protected static readonly byte[] JsonEmptyData;
    111124               
    112                 protected void PrepareEnvelopedResult (out JsonWriter _writer) {
     125                protected static void PrepareEnvelopedResult (out JsonWriter _writer) {
    113126                        WebUtils.PrepareEnvelopedResult (out _writer);
    114127                }
    115128
    116                 protected void SendEnvelopedResult (RequestContext _context, ref JsonWriter _writer, HttpStatusCode _statusCode = HttpStatusCode.OK,
     129                protected static void SendEnvelopedResult (RequestContext _context, ref JsonWriter _writer, HttpStatusCode _statusCode = HttpStatusCode.OK,
    117130                        byte[] _jsonInputData = null, string _errorCode = null, Exception _exception = null) {
    118131                       
     
    120133                }
    121134
    122                 protected bool TryGetJsonField (IDictionary<string, object> _jsonObject, string _fieldName, out int _value) {
     135                protected static void SendErrorResult (RequestContext _context, HttpStatusCode _statusCode, byte[] _jsonInputData = null, string _errorCode = null, Exception _exception = null) {
     136                        PrepareEnvelopedResult (out JsonWriter writer);
     137                        writer.WriteRaw (JsonEmptyData);
     138                        SendEnvelopedResult (_context, ref writer, _statusCode, _jsonInputData, _errorCode, _exception);
     139                }
     140
     141                protected static bool TryGetJsonField (IDictionary<string, object> _jsonObject, string _fieldName, out int _value) {
    123142                        _value = default;
    124143                       
     
    139158                }
    140159
    141                 protected bool TryGetJsonField (IDictionary<string, object> _jsonObject, string _fieldName, out double _value) {
     160                protected static bool TryGetJsonField (IDictionary<string, object> _jsonObject, string _fieldName, out double _value) {
    142161                        _value = default;
    143162                       
     
    158177                }
    159178
    160                 protected bool TryGetJsonField (IDictionary<string, object> _jsonObject, string _fieldName, out string _value) {
     179                protected static bool TryGetJsonField (IDictionary<string, object> _jsonObject, string _fieldName, out string _value) {
    161180                        _value = default;
    162181                       
     
    176195                        }
    177196                }
    178 
    179                 protected virtual void HandleRestGet (RequestContext _context) {
    180                         SendErrorResult (_context, HttpStatusCode.MethodNotAllowed, null, "Unsupported");
    181                 }
    182 
    183                 protected virtual void HandleRestPost (RequestContext _context, IDictionary<string, object> _jsonInput, byte[] _jsonInputData) {
    184                         SendErrorResult (_context, HttpStatusCode.MethodNotAllowed, _jsonInputData, "Unsupported");
    185                 }
    186 
    187                 protected virtual void HandleRestPut (RequestContext _context, IDictionary<string, object> _jsonInput, byte[] _jsonInputData) {
    188                         SendErrorResult (_context, HttpStatusCode.MethodNotAllowed, _jsonInputData, "Unsupported");
    189                 }
    190 
    191                 protected virtual void HandleRestDelete (RequestContext _context) {
    192                         SendErrorResult (_context, HttpStatusCode.MethodNotAllowed, null, "Unsupported");
    193                 }
     197               
     198
     199#endregion
    194200        }
    195201}
  • binary-improvements2/WebServer/src/WebAPI/Null.cs

    r391 r404  
    1 using System.Text;
     1using System;
     2using System.Text;
    23
    34namespace Webserver.WebAPI {
     
    1011                        _context.Response.ContentType = "text/plain";
    1112                        _context.Response.ContentEncoding = Encoding.ASCII;
    12                         _context.Response.OutputStream.Write (new byte[] { }, 0, 0);
     13                        _context.Response.OutputStream.Write (Array.Empty<byte> (), 0, 0);
    1314                }
    1415        }
  • binary-improvements2/WebServer/src/WebConnection.cs

    r402 r404  
    33using System.Net;
    44using UnityEngine;
     5using Webserver.Permissions;
    56
    67namespace Webserver {
     
    1516                public IPAddress Endpoint { get; }
    1617
     18                public string Username { get; }
    1719                public PlatformUserIdentifierAbs UserId { get; }
     20                public PlatformUserIdentifierAbs CrossplatformUserId { get; }
    1821
    1922                public TimeSpan Age => DateTime.Now - lastAction;
    2023
    21                 public WebConnection (string _sessionId, IPAddress _endpoint, PlatformUserIdentifierAbs _userId) {
     24                public WebConnection (string _sessionId, IPAddress _endpoint, string _username, PlatformUserIdentifierAbs _userId, PlatformUserIdentifierAbs _crossUserId = null) {
    2225                        SessionID = _sessionId;
    2326                        Endpoint = _endpoint;
     27                        Username = _username;
    2428                        UserId = _userId;
     29                        CrossplatformUserId = _crossUserId;
    2530                        login = DateTime.Now;
    2631                        lastAction = login;
     
    2934
    3035                public static bool CanViewAllPlayers (int _permissionLevel) {
    31                         return WebPermissions.Instance.ModuleAllowedWithLevel ("webapi.viewallplayers", _permissionLevel);
     36                        return AdminWebModules.Instance.ModuleAllowedWithLevel ("webapi.viewallplayers", _permissionLevel);
    3237                }
    3338
    3439                public static bool CanViewAllClaims (int _permissionLevel) {
    35                         return WebPermissions.Instance.ModuleAllowedWithLevel ("webapi.viewallclaims", _permissionLevel);
     40                        return AdminWebModules.Instance.ModuleAllowedWithLevel ("webapi.viewallclaims", _permissionLevel);
    3641                }
    3742
  • binary-improvements2/WebServer/src/WebUtils.cs

    r402 r404  
    11using System;
     2using System.Collections.Specialized;
    23using System.Diagnostics.CodeAnalysis;
    34using System.Net;
     
    110111                        WriteJsonData (_context.Response, ref _writer, _statusCode);
    111112                }
     113
     114                public static bool TryGetValue (this NameValueCollection _nameValueCollection, string _name, out string _result) {
     115                        _result = _nameValueCollection [_name];
     116                        return _result != null;
     117                }
    112118        }
    113119}
Note: See TracChangeset for help on using the changeset viewer.