]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
ID Console can no longer grant access the privileged ID doesn't have. (read: AA nerf...
authorMoony <moony@hellomouse.net>
Fri, 5 May 2023 13:56:54 +0000 (08:56 -0500)
committerGitHub <noreply@github.com>
Fri, 5 May 2023 13:56:54 +0000 (23:56 +1000)
Co-authored-by: moonheart08 <moonheart08@users.noreply.github.com>
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
Content.Client/Access/UI/IdCardConsoleWindow.xaml.cs
Content.Server/Access/Systems/IdCardConsoleSystem.cs
Content.Shared/Access/Components/IdCardConsoleComponent.cs
Content.Shared/Access/Systems/SharedIdCardConsoleSystem.cs
Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml
Resources/Prototypes/Roles/Jobs/Command/head_of_personnel.yml

index 9bc410db0fef60c9a165ffa32c6af4ac788598f4..ffd949a643880a03a79ef6b796ee35992711b6c0 100644 (file)
@@ -116,7 +116,7 @@ namespace Content.Client.Access.UI
             // this is a sussy way to do this
             foreach (var access in job.Access)
             {
-                if (_accessButtons.TryGetValue(access, out var button))
+                if (_accessButtons.TryGetValue(access, out var button) && !button.Disabled)
                 {
                     button.Pressed = true;
                 }
@@ -131,7 +131,7 @@ namespace Content.Client.Access.UI
 
                 foreach (var access in groupPrototype.Tags)
                 {
-                    if (_accessButtons.TryGetValue(access, out var button))
+                    if (_accessButtons.TryGetValue(access, out var button) && !button.Disabled)
                     {
                         button.Pressed = true;
                     }
@@ -187,6 +187,7 @@ namespace Content.Client.Access.UI
                 if (interfaceEnabled)
                 {
                     button.Pressed = state.TargetIdAccessList?.Contains(accessName) ?? false;
+                    button.Disabled = (!state.AllowedModifyAccessList?.Contains(accessName)) ?? true;
                 }
             }
 
index 4318987233ebe27f6969d063bf8045ab8ef89a5f..e33bb946bf5651c70a0e6b9d2389e25a7f671a0c 100644 (file)
@@ -54,16 +54,18 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem
         if (!component.Initialized)
             return;
 
+        var privilegedIdName = string.Empty;
+        string[]? possibleAccess = null;
+        if (component.PrivilegedIdSlot.Item is { Valid: true } item)
+        {
+            privilegedIdName = EntityManager.GetComponent<MetaDataComponent>(item).EntityName;
+            possibleAccess = _accessReader.FindAccessTags(item).ToArray();
+        }
+
         IdCardConsoleBoundUserInterfaceState newState;
         // this could be prettier
         if (component.TargetIdSlot.Item is not { Valid: true } targetId)
         {
-            var privilegedIdName = string.Empty;
-            if (component.PrivilegedIdSlot.Item is { Valid: true } item)
-            {
-                privilegedIdName = EntityManager.GetComponent<MetaDataComponent>(item).EntityName;
-            }
-
             newState = new IdCardConsoleBoundUserInterfaceState(
                 component.PrivilegedIdSlot.HasItem,
                 PrivilegedIdIsAuthorized(uid, component),
@@ -71,6 +73,7 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem
                 null,
                 null,
                 null,
+                possibleAccess,
                 string.Empty,
                 privilegedIdName,
                 string.Empty);
@@ -79,9 +82,6 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem
         {
             var targetIdComponent = EntityManager.GetComponent<IdCardComponent>(targetId);
             var targetAccessComponent = EntityManager.GetComponent<AccessComponent>(targetId);
-            var name = string.Empty;
-            if (component.PrivilegedIdSlot.Item is { Valid: true } item)
-                name = EntityManager.GetComponent<MetaDataComponent>(item).EntityName;
 
             var jobProto = string.Empty;
             if (_station.GetOwningStation(uid) is { } station
@@ -99,8 +99,9 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem
                 targetIdComponent.FullName,
                 targetIdComponent.JobTitle,
                 targetAccessComponent.Tags.ToArray(),
+                possibleAccess,
                 jobProto,
-                name,
+                privilegedIdName,
                 EntityManager.GetComponent<MetaDataComponent>(targetId).EntityName);
         }
 
@@ -130,16 +131,29 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem
 
         if (!newAccessList.TrueForAll(x => component.AccessLevels.Contains(x)))
         {
-            Logger.Warning("Tried to write unknown access tag.");
+            _sawmill.Warning($"User {ToPrettyString(uid)} tried to write unknown access tag.");
             return;
         }
 
         var oldTags = _access.TryGetTags(targetId) ?? new List<string>();
         oldTags = oldTags.ToList();
 
+        var privilegedId = component.PrivilegedIdSlot.Item;
+
         if (oldTags.SequenceEqual(newAccessList))
             return;
 
+        // I hate that C# doesn't have an option for this and don't desire to write this out the hard way.
+        // var difference = newAccessList.Difference(oldTags);
+        var difference = (newAccessList.Union(oldTags)).Except(newAccessList.Intersect(oldTags)).ToHashSet();
+        // NULL SAFETY: PrivilegedIdIsAuthorized checked this earlier.
+        var privilegedPerms = _accessReader.FindAccessTags(privilegedId!.Value).ToHashSet();
+        if (!difference.IsSubsetOf(privilegedPerms))
+        {
+            _sawmill.Warning($"User {ToPrettyString(uid)} tried to modify permissions they could not give/take!");
+            return;
+        }
+
         var addedTags = newAccessList.Except(oldTags).Select(tag => "+" + tag).ToList();
         var removedTags = oldTags.Except(newAccessList).Select(tag => "-" + tag).ToList();
         _access.TrySetTags(targetId, newAccessList);
@@ -155,6 +169,9 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem
     /// <summary>
     /// Returns true if there is an ID in <see cref="IdCardConsoleComponent.PrivilegedIdSlot"/> and said ID satisfies the requirements of <see cref="AccessReaderComponent"/>.
     /// </summary>
+    /// <remarks>
+    /// Other code relies on the fact this returns false if privileged Id is null. Don't break that invariant.
+    /// </remarks>
     private bool PrivilegedIdIsAuthorized(EntityUid uid, IdCardConsoleComponent? component = null)
     {
         if (!Resolve(uid, ref component))
index 87c5f48bf963cd35c3ff9945cc9f1146c832c0eb..53001867c540e730f5e9b91c23a8a5a61bfdf622 100644 (file)
@@ -85,6 +85,7 @@ public sealed class IdCardConsoleComponent : Component
         public readonly string? TargetIdFullName;
         public readonly string? TargetIdJobTitle;
         public readonly string[]? TargetIdAccessList;
+        public readonly string[]? AllowedModifyAccessList;
         public readonly string TargetIdJobPrototype;
 
         public IdCardConsoleBoundUserInterfaceState(bool isPrivilegedIdPresent,
@@ -93,6 +94,7 @@ public sealed class IdCardConsoleComponent : Component
             string? targetIdFullName,
             string? targetIdJobTitle,
             string[]? targetIdAccessList,
+            string[]? allowedModifyAccessList,
             string targetIdJobPrototype,
             string privilegedIdName,
             string targetIdName)
@@ -103,6 +105,7 @@ public sealed class IdCardConsoleComponent : Component
             TargetIdFullName = targetIdFullName;
             TargetIdJobTitle = targetIdJobTitle;
             TargetIdAccessList = targetIdAccessList;
+            AllowedModifyAccessList = allowedModifyAccessList;
             TargetIdJobPrototype = targetIdJobPrototype;
             PrivilegedIdName = privilegedIdName;
             TargetIdName = targetIdName;
index 8661b47ccfee83b8893734ea730b4d4f17b3c722..9abb91de473929ae5348046b2ecacd30c94a21cb 100644 (file)
@@ -10,12 +10,15 @@ namespace Content.Shared.Access.Systems
     public abstract class SharedIdCardConsoleSystem : EntitySystem
     {
         [Dependency] private readonly ItemSlotsSystem _itemSlotsSystem = default!;
+        [Dependency] private readonly ILogManager _log = default!;
 
         public const string Sawmill = "idconsole";
+        protected ISawmill _sawmill = default!;
 
         public override void Initialize()
         {
             base.Initialize();
+            _sawmill = _log.GetSawmill(Sawmill);
 
             SubscribeLocalEvent<IdCardConsoleComponent, ComponentInit>(OnComponentInit);
             SubscribeLocalEvent<IdCardConsoleComponent, ComponentRemove>(OnComponentRemove);
index 0fd8d2c8118c0c0fb38fe854cdcd457a5356a81e..33eced8fca7b0aa1b649a2840f95d32740b4a0a2 100644 (file)
   name: ID card computer
   description: Terminal for programming Nanotrasen employee ID cards to access parts of the station.
   components:
-  - type: AccessReader
-    access: [["HeadOfPersonnel"]]
   - type: IdCardConsole
     privilegedIdSlot:
       name: id-card-console-privileged-id
index a8ba12057014c7db52ca76dad0437b11a9e0d0f4..b05f20c4638d65f246bc6c1b06b065a6d4a79a47 100644 (file)
   - Hydroponics
   - External
   # I mean they'll give themselves the rest of the access levels *anyways*.
+  # As of 15/03/23 they can't do that so here's MOST of the rest of the access levels.
+  # Head level access that isn't their own was deliberately left out, get AA from the captain instead.
+  - Chemistry
+  - Engineering
+  - Quartermaster
+  - Research
+  - Salvage
+  - Security
+  - Brig
+  - Cargo
+  - Atmospherics
+  - Cargo
+  - Medical
 
 - type: startingGear
   id: HoPGear