/
githubmirror
/
aspnetcore
Обзор
Документация
Войти
/
githubmirror
/
aspnetcore
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Identity/test/Identity.Test/IdentityUIScriptsTest.cs
187 строк
6 KB
Youssef Fahmy
Update AngleSharp to latest (#67898)
20 июл 2026, 15:48
Не верифицирован
20 июл 2026, 15:48
fc4e6e0
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Net.Http; using System.Reflection; using System.Security.Cryptography; using AngleSharp.Html.Dom; using AngleSharp.Html.Parser; using Microsoft.AspNetCore.InternalTesting; using Xunit.Abstractions; namespace Microsoft.AspNetCore.Identity.Test; [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/38542", Queues = "OSX.1015.Amd64.Open;OSX.1015.Amd64")] //slow public class IdentityUIScriptsTest : IDisposable { private readonly ITestOutputHelper _output; private readonly HttpClient _httpClient; public IdentityUIScriptsTest(ITestOutputHelper output) { _output = output; _httpClient = new HttpClient(new RetryHandler(new HttpClientHandler() { }, output, TimeSpan.FromSeconds(1), 5)); } public static IEnumerable<object[]> ScriptWithIntegrityData { get { return GetScriptTags() .Where(st => st.Integrity != null) .Select(st => new object[] { st }); } } [Theory] [MemberData(nameof(ScriptWithIntegrityData))] public async Task IdentityUI_ScriptTags_SubresourceIntegrityCheck(ScriptTag scriptTag) { var integrity = await GetShaIntegrity(scriptTag); Assert.Equal(scriptTag.Integrity, integrity); } private async Task<string> GetShaIntegrity(ScriptTag scriptTag) { var isSha256 = scriptTag.Integrity.StartsWith("sha256", StringComparison.Ordinal); var isSha384 = scriptTag.Integrity.StartsWith("sha384", StringComparison.Ordinal); var prefix = isSha256 ? "sha256" : (isSha384 ? "sha384" : "sha512"); using (var respStream = await _httpClient.GetStreamAsync(scriptTag.Src)) using (var alg256 = SHA256.Create()) using (var alg384 = SHA384.Create()) using (var alg512 = SHA512.Create()) { byte[] hash; if (isSha256) { hash = alg256.ComputeHash(respStream); }else if(isSha384) { hash = alg384.ComputeHash(respStream); } else { hash = alg512.ComputeHash(respStream); } return $"{prefix}-" + Convert.ToBase64String(hash); } } public static IEnumerable<object[]> ScriptWithFallbackSrcData { get { return GetScriptTags() .Where(st => st.FallbackSrc != null) .Select(st => new object[] { st }); } } [Theory] [MemberData(nameof(ScriptWithFallbackSrcData))] public async Task IdentityUI_ScriptTags_FallbackSourceContent_Matches_CDNContent(ScriptTag scriptTag) { var wwwrootDir = Path.Combine(GetProjectBasePath(), "assets", scriptTag.Version); var cdnContent = await _httpClient.GetStringAsync(scriptTag.Src); var fallbackSrcContent = File.ReadAllText( Path.Combine(wwwrootDir, scriptTag.FallbackSrc.Replace("Identity", "").TrimStart('~').TrimStart('/'))); Assert.Equal(RemoveLineEndings(cdnContent), RemoveLineEndings(fallbackSrcContent)); } public struct ScriptTag { public string Version; public string Src; public string Integrity; public string FallbackSrc; public string File; public override string ToString() { return Src; } } private static List<ScriptTag> GetScriptTags() { var scriptTags = new List<ScriptTag>(); var uiDirV4 = Path.Combine(GetProjectBasePath(), "Areas", "Identity", "Pages", "V4"); var uiDirV5 = Path.Combine(GetProjectBasePath(), "Areas", "Identity", "Pages", "V5"); var cshtmlFiles = GetRazorFiles(uiDirV4).Concat(GetRazorFiles(uiDirV5)); foreach (var cshtmlFile in cshtmlFiles) { var tags = GetScriptTags(cshtmlFile); scriptTags.AddRange(tags); } Assert.NotEmpty(scriptTags); return scriptTags; IEnumerable<string> GetRazorFiles(string dir) => Directory.GetFiles(dir, "*.cshtml", SearchOption.AllDirectories); } private static List<ScriptTag> GetScriptTags(string cshtmlFile) { IHtmlDocument htmlDocument; var htmlParser = new HtmlParser(); using (var stream = File.OpenRead(cshtmlFile)) { htmlDocument = htmlParser.ParseDocument(stream); } var scriptTags = new List<ScriptTag>(); foreach (var scriptElement in htmlDocument.Scripts) { var fallbackSrcAttribute = scriptElement.Attributes .FirstOrDefault(attr => string.Equals("asp-fallback-src", attr.Name, StringComparison.OrdinalIgnoreCase)); scriptTags.Add(new ScriptTag { Version = cshtmlFile.Contains("V4") ? "V4" : "V5", Src = scriptElement.Source, Integrity = scriptElement.Integrity, FallbackSrc = fallbackSrcAttribute?.Value, File = cshtmlFile }); } return scriptTags; } private static string RemoveLineEndings(string originalString) { return originalString.Replace("\r\n", "").Replace("\n", ""); } public void Dispose() { _httpClient.Dispose(); } private static string GetProjectBasePath() { var projectPath = typeof(IdentityUIScriptsTest).Assembly.GetCustomAttributes<AssemblyMetadataAttribute>() .Single(a => a.Key == "Microsoft.AspNetCore.InternalTesting.DefaultUIProjectPath").Value; return Directory.Exists(projectPath) ? projectPath : Path.Combine(FindHelixSlnFileDirectory(), "UI"); } private static string FindHelixSlnFileDirectory() { var applicationPath = Path.GetDirectoryName(typeof(IdentityUIScriptsTest).Assembly.Location); var directoryInfo = new DirectoryInfo(applicationPath); do { var solutionPath = Directory.EnumerateFiles(directoryInfo.FullName, "*.sln").FirstOrDefault(); if (solutionPath != null) { return directoryInfo.FullName; } directoryInfo = directoryInfo.Parent; } while (directoryInfo.Parent != null); throw new InvalidOperationException($"Solution root could not be located using application root {applicationPath}."); } }