feat(client)!: рабочая авторизация в IXrplClient — Basic на ws-хендшейке и admin-креды по WS (10.10.0.0) - #67
Merged
Conversation
…ке и admin-креды по WS ConnectionOptions.authorization была публичной опцией с момента порта с xrpl.js, но Connection.CreateWebSocket представлял собой блок закомментированного JS-псевдокода, заканчивающийся `WebSocketClient.Create(url); // todo add options`, а сам WebSocketClient не имел параметра, чтобы их принять. Ничто из authorization/headers/proxy/сертификатов до сокета не доходило. - authorization -> `Authorization: Basic base64(user:pass)` на WebSocket-апгрейде, как в xrpl.js createWebSocket - headers прокидываются как есть; тип сменён с Dictionary<string, object> на Dictionary<string, string> (source-breaking, но поле было инертным) - оба игнорируются под WebAssembly: браузерный WebSocket API не умеет ставить заголовки запроса, поэтому SetRequestHeader под guard'ом OperatingSystem.IsBrowser() - proxy, proxyAuthorization, trustedCertificates, key, passphrase, certificate помечены [Obsolete]: актуальный xrpl.js их тоже выбросил Отдельно добавлены AdminUser/AdminPassword — механизм, который rippled реально принимает для ws/wss: admin_user/admin_password передаются полями внутри JSON запроса. Basic-заголовок на ws-хендшейке нода не проверяет (authorized() вызывается только из HTTP-пути onRequest(), onHandoff() апгрейдит WebSocket без него), поэтому authorization осмысленна лишь для reverse-proxy перед нодой. Креды подмешиваются в сериализованный JSON, а не в объект запроса, чтобы пароль не попадал в текст TimeoutException. Тесты: TestUAuthorization ассертит по сырому тексту HTTP-апгрейда, пойманному локальным сокет-сервером. TestIAdminCredentials работает против новой станзы [port_ws_admin_auth] (порт 6007) на standalone-стенде и проверяет обе стороны — ledger_accept с noPermission без кредов и успешный с ними; порт отделён от port_ws_admin, чтобы не задеть остальную интеграционную сюиту.
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Comment |
…не noPermission Прогон на standalone-стенде показал, что порт с заданными admin_user/admin_password отвергает запрос без кредов с `forbidden` / `Bad credentials.`: requestRole возвращает Role::FORBID и до гостевой роли клиент не понижается, поэтому noPermission не приходит. Ассерт стал точнее — он теперь доказывает, что нода отвергла именно креды, а не просто отказала в недоступной команде. Позитивный сценарий (ledger_accept с кредами) прошёл сразу — механизм передачи admin-кредов в теле JSON работает end-to-end. Формулировки в CHANGES.md и комментарий к [port_ws_admin_auth] приведены в соответствие.
…Options proxy, proxyAuthorization, trustedCertificates, key, passphrase, certificate и неиспользуемая пара trace/Trace удалены вместо пометки [Obsolete]. Ни одно из этих полей никогда не читалось: CreateWebSocket их игнорировал, WebSocketClient не имел параметра, чтобы их принять. Актуальный xrpl.js эти опции тоже выбросил, а единообразно поддержать их на всех таргетах ClientWebSocket нельзя. BREAKING CHANGE: свойства удалены без grace-периода [Obsolete] — как и при удалении hex-хелперов в 10.9.0.0. Работающий код на них опираться не мог: любое присвоение молча ничего не делало. authorization и headers сохранены — они реализованы в этом же релизе.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Проблема
ConnectionOptions.authorizationбыла публичной опцией наXrplClient.ClientOptionsс момента порта с xrpl.js, но никуда не подключена.Connection.CreateWebSocket— блок закомментированного JS-псевдокода, заканчивающийся одной живой строкой:WebSocketClient.Create(string uri)параметрconfigвообще не принимал. Ниauthorization, ниheaders, ниproxy, ни сертификаты до сокета не доходили — опция выглядела рабочей и молча игнорировалась.Что важно знать про rippled
В rippled две несвязанные схемы аутентификации на port-станзе, и для WebSocket работает только вторая:
user/passwordadmin_user/admin_passwordauthorized()вServerHandler.cppвызывается ровно из одного места —onRequest(). ПутьonHandoff()приwebsocket::is_upgrade(request)уходит в апгрейд без этой проверки. То есть Basic-заголовок на ws/wss-рукопожатии сама нода не смотрит: опцияauthorizationосмысленна для reverse-proxy или провайдера перед нодой, а для админ-команд по WS нужен второй механизм. Поэтому в PR реализованы оба.Изменения
1.
authorizationиheadersдоходят до сокетаauthorization→Authorization: Basic base64(value)на WebSocket-апгрейде, как в xrpl.jscreateWebSocket; значение — сырая параuser:password, base64 делает SDKheadersпрокидываются как есть; тип сменёнDictionary<string, object>→Dictionary<string, string>(как в xrpl.js). Формально source-breaking, фактически нет: поле было инертнымClientWebSocket.Options.SetRequestHeaderпод тем же guard'омOperatingSystem.IsBrowser(), что уже стоял наKeepAliveIntervalproxy,proxyAuthorization,trustedCertificates,key,passphrase,certificateи неиспользуемая параtrace/Traceудалены, а не реализованы (breaking, без grace-периода[Obsolete]— как при удалении hex-хелперов в 10.9.0.0): актуальный xrpl.js их тоже выбросил, единообразно поддержать их на всех таргетахClientWebSocketнельзя, и ни одно из них никогда не читалось. Свойство, которое молча ничего не делает, хуже того, которое не компилируется2.
AdminUser/AdminPasswordadmin-сетями и корректные креды)TimeoutException, который потребители логируютRequestManager.CreateRequest/CreateGRequestстоит последним, поэтому существующие позиционные вызовы не сломаныТесты
TestUAuthorization(7 юнит-тестов) ассертит по сырому тексту HTTP-апгрейда, пойманному локальным сокет-сервером: Basic-заголовок присутствует и корректно закодирован, кастомные заголовки на месте,Authorizationотсутствует когда опция не задана, admin-креды попадают в оба вида запросов и не попадают в текст таймаут-исключения.TestIAdminCredentialsработает против новой станзы[port_ws_admin_auth](порт 6007, сadmin_user/admin_password) и проверяет обе стороны. Порт отделён отport_ws_admin, поэтому остальная интеграционная сюита не затронута; станза и проброс порта добавлены в оба стенда.Прогон на стенде уточнил одно ожидание: порт с заданными кредами отвергает запрос без них не с
noPermission, а сforbidden/Bad credentials.—requestRoleвозвращаетRole::FORBIDи до гостевой роли клиента не понижает. Ассерт исправлен на фактическое поведение, и он получился строже: доказывает, что нода отвергла именно креды, а не просто отказала в недоступной команде.Проверено
dotnet test --filter "TestU"— 865/865 зелёныеdotnet test --filter "TestI&TestCategory!=Live"на standalone-стенде — 219 прошли, 40 пропущены (amendment-gated на CI-стенде, штатно), 0 падений. Новый порт 6007 поднимается штатно:Opened 'port_ws_admin_auth' (ip=0.0.0.0:6007, admin nets:0.0.0.0/0, ::/0, ws)dotnet build XrplCSharp.sln— 0 ошибок (единственное использование удалённогоproxyбыло вTestConnection.csи заменено на проверку новых дефолтов; больше в решении эти свойства нигде не читались)Summary by CodeRabbit
New Features
Documentation
Tests