Browse Source

Optimized and added test

BaronGreenback 4 years ago
parent
commit
414e918c01

+ 15 - 24
Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs

@@ -263,26 +263,9 @@ namespace Emby.Server.Implementations.HttpServer.Security
                 return null;
             }
 
-            // Remove uptil the first space
+            // Remove up until the first space
             authorizationHeader = parts[1];
-            parts = GetParts(authorizationHeader);
-
-            var result = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
-
-            foreach (var item in parts)
-            {
-                var param = item.Trim().Split('=', 2);
-
-                var value = param[1].Trim('"');
-                result[param[0]] = NormalizeValue(value);
-            }
-
-            return result;
-        }
-
-        private static string NormalizeValue(string value)
-        {
-            return string.IsNullOrEmpty(value) ? value : WebUtility.UrlDecode(value);
+            return GetParts(authorizationHeader);
         }
 
         /// <summary>
@@ -290,13 +273,15 @@ namespace Emby.Server.Implementations.HttpServer.Security
         /// </summary>
         /// <param name="authtorizationHeader">The authorization header.</param>
         /// <returns>string</returns>
-        public static string[] GetParts(string authtorizationHeader)
+        public static Dictionary<string, string> GetParts(string authtorizationHeader)
         {
-            var result = new List<string>();
+            var result = new Dictionary<string, string>();
             var escapeChars = new[] { '"', ',' };
             var escaped = false;
             int start = 0;
             int i = 0;
+            string key = string.Empty;
+
             while (i < authtorizationHeader.Length)
             {
                 var token = authtorizationHeader[i];
@@ -309,12 +294,18 @@ namespace Emby.Server.Implementations.HttpServer.Security
                         // Meeting a comma after a closing escape char means the value is complete
                         if (start < i)
                         {
-                            result.Add(WebUtility.UrlDecode(authtorizationHeader[start..(i)]));
+                            result[key] = WebUtility.UrlDecode(authtorizationHeader[start..i].Trim('"'));
+                            key = string.Empty;
                         }
 
                         start = i + 1;
                     }
                 }
+                else if (!escaped && token == '=')
+                {
+                    key = authtorizationHeader[start.. i];
+                    start = i + 1;
+                }
 
                 i++;
             }
@@ -322,10 +313,10 @@ namespace Emby.Server.Implementations.HttpServer.Security
             // Add last value
             if (start < i)
             {
-                result.Add(WebUtility.UrlDecode(authtorizationHeader[start..(i)]));
+                result[key] = WebUtility.UrlDecode(authtorizationHeader[start..i].Trim('"'));
             }
 
-            return result.ToArray();
+            return result;
         }
     }
 }

+ 13 - 1
tests/Jellyfin.Api.Tests/Auth/DefaultAuthorizationPolicy/DefaultAuthorizationHandlerTests.cs

@@ -1,7 +1,8 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
 using System.Threading.Tasks;
 using AutoFixture;
 using AutoFixture.AutoMoq;
+using Emby.Server.Implementations.HttpServer.Security;
 using Jellyfin.Api.Auth.DefaultAuthorizationPolicy;
 using Jellyfin.Api.Constants;
 using MediaBrowser.Common.Configuration;
@@ -49,5 +50,16 @@ namespace Jellyfin.Api.Tests.Auth.DefaultAuthorizationPolicy
             await _sut.HandleAsync(context);
             Assert.True(context.HasSucceeded);
         }
+
+        [Theory]
+        [InlineData("x=\"123,123\",y=\"123\"", "x", "123,123")]
+        [InlineData("x=\"ab\"", "x", "ab")]
+        [InlineData("param=Hörbücher", "param", "Hörbücher")]
+        [InlineData("param=%22%Hörbücher", "param", "\"%Hörbücher")]
+        public void TestAuthHeaders(string input, string key, string value)
+        {
+            var dict = AuthorizationContext.GetParts(input);
+            Assert.True(string.Equals(dict[key], value, System.StringComparison.Ordinal));
+        }
     }
 }