Skip to content

Commit

Permalink
Add Linux compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
diev committed Jul 26, 2024
1 parent cf8b28e commit f80e410
Show file tree
Hide file tree
Showing 11 changed files with 132 additions and 47 deletions.
35 changes: 35 additions & 0 deletions .github/workflows/dotnet8-desktop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# This workflow will build a .NET8 Desktop project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net

name: .NET8 Desktop

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
build:

runs-on: windows-latest

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x

- name: Restore dependencies
run: dotnet restore

- name: Build
run: dotnet build --no-restore

- name: Test
run: dotnet test --no-build --verbosity normal
5 changes: 4 additions & 1 deletion FeedsAPI/ConfigManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ public static Config Read()
{
try
{
string appsettings = Path.ChangeExtension(Environment.ProcessPath!, ".config.json");
// Works in Windows, fails in Linux (/usr/lib/dotnet...)
// string appsettings = Path.ChangeExtension(Environment.ProcessPath!, ".config.json");

string appsettings = Path.Combine(AppContext.BaseDirectory, "FeedsAPI.config.json"); //TODO what?

if (File.Exists(appsettings))
{
Expand Down
2 changes: 1 addition & 1 deletion FeedsAPI/FeedsAPI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<RootNamespace>FeedsApi</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Version>8.2024.712</Version>
<Version>8.2024.726</Version>
<Company>diev</Company>
<Copyright>2022-2024 Dmitrii Evdokimov</Copyright>
<Description>Получение фидов из FinCERT (АСОИ ФинЦЕРТ) Банка России. Обновление референсного проекта до TLS с сертификатами.</Description>
Expand Down
6 changes: 3 additions & 3 deletions FeedsAPI/FincertAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public async Task<bool> LogoutFromASOIAsync()
{
try
{
var response = await _tlsClient.PostAsJsonAsync(_api + "account/logout", string.Empty);
using var response = await _tlsClient.PostAsJsonAsync(_api + "account/logout", string.Empty);
response.EnsureSuccessStatusCode();

if (response.StatusCode == HttpStatusCode.OK)
Expand Down Expand Up @@ -204,7 +204,7 @@ public async Task<bool> LogoutFromASOIAsync()

for (int i = 0; i < 3; i++) // Сколько делаем попыток получить данные
{
var response = await _tlsClient.GetAsync(_api + $"antifraud/feeds/{feed}");
using var response = await _tlsClient.GetAsync(_api + $"antifraud/feeds/{feed}");
response.EnsureSuccessStatusCode();

if (response.StatusCode == HttpStatusCode.OK) // Ответ получен
Expand Down Expand Up @@ -260,7 +260,7 @@ public async Task<bool> LogoutFromASOIAsync()

for (int i = 0; i < 3; i++) // Сколько делаем попыток получить данные
{
var response = await _tlsClient.GetAsync(_api + $"antifraud/feeds/{feed}/download");
using var response = await _tlsClient.GetAsync(_api + $"antifraud/feeds/{feed}/download");
response.EnsureSuccessStatusCode();

if (response.StatusCode == HttpStatusCode.OK) // Ответ получен
Expand Down
27 changes: 21 additions & 6 deletions FeedsAPI/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# FeedsAPI

[![Build status](https://ci.appveyor.com/api/projects/status/hpsbfj3qds34i4yb?svg=true)](https://ci.appveyor.com/project/diev/fincert-client)
[![.NET8 Desktop](https://github.com/diev/FinCERT-Client/actions/workflows/dotnet8-desktop.yml/badge.svg)](https://github.com/diev/FinCERT-Client/actions/workflows/dotnet8-desktop.yml)
[![GitHub Release](https://img.shields.io/github/release/diev/FinCERT-Client.svg)](https://github.com/diev/FinCERT-Client/releases/latest)

Получение по API фидов из FinCERT (АСОИ ФинЦЕРТ) Банка России.
Expand All @@ -21,8 +22,8 @@ read-only.

## Config / Конфигурация

При первом запуске и отсутствии файла конфигурации `.config.json`, он
создается рядом с программой с параметрами по умолчанию.
При первом запуске и отсутствии файла конфигурации `FeedsAPI.config.json`,
он создается рядом с программой с параметрами по умолчанию.
Никакие другие конфиги, переменные среды окружения и т.п. не используются.

Важно заполнить вашими данными значения параметров:
Expand All @@ -35,6 +36,9 @@ read-only.
Если указываете файловые пути, то по правилам JSON надо удваивать `\\`
в Windows и использовать `/` в Linux.

По окончании корректировки надо переключить параметр NewConfig = `true`
в `false` или удалить эту строчку полностью.

## Exit codes / Коды возврата

* 0 - успешно;
Expand All @@ -44,21 +48,30 @@ read-only.
## Requirements / Требования

* .NET 6-7-8 (Windows или Linux)
* КриптоПро для подключения с сертификатом TLS
* КриптоПро CSP для установки соединения TLS
* Сертификат TLS клиента и цепочка доверия
* Логин и пароль

Вариант Linux пока не тестировался, Stunnel программе не требуется.
## Linux

Вариант Linux протестирован в WSL без установки КриптоПро.

Пример сборки проекта под Linux (укажите нужную версию .NET) из папки
с файлом FeedsAPI.csproj:

dotnet publish -r linux-x64 -f net6.0 --self-contained

Запуск:
Запуск из папки с файлами программы:

dotnet FeedsAPI.dll

## Breaking Changes / Важные изменения

Выяснилось, что механизм получения файла настроек, работавший в Windows
(одноименный и рядом с exe), в Linux дает неправильное размещение файла.
Пока пришлось жестко прописать имя файла в коде. Далее придется менять
эту схему именования, крайне удобную ранее.

## Versioning / Порядок версий

Номер версии программы указывается по нарастающему принципу и строится
Expand All @@ -80,5 +93,7 @@ read-only.

## License / Лицензия

Licensed under the [Apache License, Version 2.0](LICENSE).
Licensed under the [Apache License, Version 2.0](LICENSE).
Вы можете использовать эти материалы под свою ответственность.

[![Telegram](https://img.shields.io/badge/t.me-dievdo-blue?logo=telegram)](https://t.me/dievdo)
21 changes: 14 additions & 7 deletions FinCERT-Client/API/Bulletins.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ internal static class Bulletins
public static async Task<BulletinIds> GetBulletinIdsAsync(int limit = 100, long offset = 0)
{
string url = $"bulletins?limit={limit}&offset={offset}";
var response = await TlsClient.GetAsync(url);
using var response = await TlsClient.GetAsync(url);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<BulletinIds>()
?? throw new BulletinsException(
"Список бюллетеней не получен.");
Expand All @@ -95,7 +96,8 @@ public static async Task<BulletinIds> GetBulletinIdsAsync(int limit = 100, long
public static async Task GetBulletinIdsAsync(string path, int limit = 100, long offset = 0)
{
string url = $"bulletins?limit={limit}&offset={offset}";
var response = await TlsClient.GetAsync(url);
using var response = await TlsClient.GetAsync(url);
response.EnsureSuccessStatusCode();
using var output = File.Create(path);
await response.Content.CopyToAsync(output);
}
Expand All @@ -109,7 +111,8 @@ public static async Task<BulletinInfos> GetBulletinInfosAsync(string[] ids)
{
string url = "bulletins/list";
var content = new BulletinList(ids);
var response = await TlsClient.PostAsJsonAsync(url, content);
using var response = await TlsClient.PostAsJsonAsync(url, content);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<BulletinInfos>()
?? throw new BulletinsException(
"Информация по бюллетеням не получена.");
Expand All @@ -124,7 +127,8 @@ public static async Task GetBulletinInfosAsync(string[] ids, string path)
{
string url = "bulletins/list";
var content = new BulletinList(ids);
var response = await TlsClient.PostAsJsonAsync(url, content);
using var response = await TlsClient.PostAsJsonAsync(url, content);
response.EnsureSuccessStatusCode();
using var output = File.Create(path);
await response.Content.CopyToAsync(output);
}
Expand All @@ -137,7 +141,8 @@ public static async Task GetBulletinInfosAsync(string[] ids, string path)
public static async Task<BulletinAttachInfo> GetBulletinAttachInfoAsync(string id)
{
string url = $"bulletins/{id}";
var response = await TlsClient.GetAsync(url);
using var response = await TlsClient.GetAsync(url);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<BulletinAttachInfo>()
?? throw new BulletinsException(
$"Информация по бюллетеню '{id}' не получена.");
Expand All @@ -151,7 +156,8 @@ public static async Task<BulletinAttachInfo> GetBulletinAttachInfoAsync(string i
public static async Task GetBulletinAttachInfoAsync(string id, string path)
{
string url = $"bulletins/{id}";
var response = await TlsClient.GetAsync(url);
using var response = await TlsClient.GetAsync(url);
response.EnsureSuccessStatusCode();
using var output = File.Create(path);
await response.Content.CopyToAsync(output);
}
Expand All @@ -164,7 +170,8 @@ public static async Task GetBulletinAttachInfoAsync(string id, string path)
public static async Task DownloadAttachmentAsync(string id, string path)
{
string url = $"attachments/{id}/download";
var response = await TlsClient.GetAsync(url);
using var response = await TlsClient.GetAsync(url);
response.EnsureSuccessStatusCode();
using var output = File.Create(path);
await response.Content.CopyToAsync(output);
}
Expand Down
6 changes: 4 additions & 2 deletions FinCERT-Client/API/Feeds.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ internal static class Feeds
public static async Task<FeedsStatus> GetFeedsStatusAsync(FeedType feed)
{
string url = $"antifraud/feeds/{feed}";
var response = await TlsClient.GetAsync(url);
using var response = await TlsClient.GetAsync(url);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<FeedsStatus>()
?? throw new FeedsException("Статус фидов не получен.");
}
Expand All @@ -54,7 +55,8 @@ public static async Task DownloadFeedsAsync(FeedType feed, string path)
Directory.CreateDirectory(path);

string url = $"antifraud/feeds/{feed}/download";
var response = await TlsClient.GetAsync(url);
using var response = await TlsClient.GetAsync(url);
response.EnsureSuccessStatusCode();

string name = feed switch
{
Expand Down
2 changes: 1 addition & 1 deletion FinCERT-Client/FinCERT-Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<RootNamespace>FincertClient</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Version>8.2024.712</Version>
<Version>8.2024.726</Version>
<Company>diev</Company>
<Copyright>2022-2024 Dmitrii Evdokimov</Copyright>
<Description>Получение фидов и бюллетеней из FinCERT (АСОИ ФинЦЕРТ) Банка России.</Description>
Expand Down
25 changes: 15 additions & 10 deletions FinCERT-Client/Managers/ConfigManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,23 @@ private static JsonSerializerOptions GetJsonOptions()

public static Config Read()
{
string appsettings = Path.ChangeExtension(Environment.ProcessPath!, ".config.json");
// Works in Windows, fails in Linux (/usr/lib/dotnet...)
// string appsettings = Path.ChangeExtension(Environment.ProcessPath!, ".config.json");

string appsettings = Path.Combine(AppContext.BaseDirectory, "FinCERT-Client.config.json"); //TODO what?

if (File.Exists(appsettings))
{
using var read = File.OpenRead(appsettings);
var config = JsonSerializer.Deserialize<Config>(read);

if (config is null || config.NewConfig)
if (config is null)
throw new NewConfigException(
@$"Файл настроек ""{appsettings}"" испорчен - удалите его.");

if (config.NewConfig)
throw new NewConfigException(
);
@$"Откорректируйте файл настроек ""{appsettings}"" и отключите NewConfig.");

return config;
}
Expand All @@ -52,22 +59,20 @@ public static Config Read()
JsonSerializer.Serialize(write, newConfig, GetJsonOptions());

throw new NewConfigException(
@$"Создан новый файл настроек ""{appsettings}"".");
@$"Создан новый файл настроек ""{appsettings}"" - откорректируйте его.");
}
}

internal class NewConfigException : Exception
{
const string message = @"Необходимо откорректировать новый конфиг ""{0}"".";

public NewConfigException()
: base() { }

public NewConfigException(string config)
: base(string.Format(message, config)) { }
public NewConfigException(string message)
: base(message) { }

public NewConfigException(string config, Exception inner)
: base(string.Format(message, config), inner) { }
public NewConfigException(string message, Exception inner)
: base(message, inner) { }
}

public class ConfigException : Exception
Expand Down
35 changes: 24 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# FinCERT-Client

[![Build status](https://ci.appveyor.com/api/projects/status/hpsbfj3qds34i4yb?svg=true)](https://ci.appveyor.com/project/diev/fincert-client)
[![.NET8 Desktop](https://github.com/diev/FinCERT-Client/actions/workflows/dotnet8-desktop.yml/badge.svg)](https://github.com/diev/FinCERT-Client/actions/workflows/dotnet8-desktop.yml)
[![GitHub Release](https://img.shields.io/github/release/diev/FinCERT-Client.svg)](https://github.com/diev/FinCERT-Client/releases/latest)

Получение по API фидов и бюллетеней из FinCERT (АСОИ ФинЦЕРТ) Банка России.
Expand Down Expand Up @@ -49,14 +50,10 @@ feeds_20240703-03.zip), то его содержимое будет распак

## Config / Конфигурация

При первом запуске и отсутствии файла конфигурации `.config.json`, он
создается рядом с программой с параметрами по умолчанию.
При первом запуске и отсутствии файла конфигурации `FinCERT-Client.config.json`,
он создается рядом с программой с параметрами по умолчанию.
Никакие другие конфиги, переменные среды окружения и т.п. не используются.

В этом файле есть параметр `NewConfig` (true) - программа будет ждать
корректировки созданного нового файла конфигурации при каждом запуске,
пока этот параметр не будет удален или переключен в false.

Важно заполнить вашими данными значения параметров:

* `MyThumbprint` - отпечаток сертификата клиента, зарегистрированного на
Expand All @@ -72,6 +69,9 @@ feeds_20240703-03.zip), то его содержимое будет распак
Если указываете файловые пути, то по правилам JSON надо удваивать `\\`
в Windows и использовать `/` в Linux.

По окончании корректировки надо переключить параметр NewConfig = `true`
в `false` или удалить эту строчку полностью.

## Parameters / Опциональные параметры командной строки

* `-checklist` - сформировать в папке `BulletinsDownloads\CheckList`
Expand Down Expand Up @@ -117,21 +117,32 @@ feeds_20240703-03.zip), то его содержимое будет распак
## Requirements / Требования

* .NET 6-7-8 (Windows или Linux)
* КриптоПро для подключения с сертификатом TLS
* КриптоПро CSP для установки соединения TLS
* Сертификат TLS клиента и цепочка доверия
* Логин и пароль

Вариант Linux пока не тестировался, Stunnel программе не требуется.
*Stunnel* программе не требуется - она сама поднимает соединение TLS.

## Linux

Вариант Linux протестирован в WSL без установки КриптоПро.

Пример сборки проекта под Linux (укажите нужную версию .NET) из папки
с файлом FinCERT-Client.csproj:

dotnet publish -r linux-x64 -f net6.0 --self-contained
dotnet publish -r linux-x64 -f net8.0 --self-contained

Запуск:
Запуск из папки с файлами программы:

dotnet FinCERT-Client.dll

## Breaking Changes / Важные изменения

Выяснилось, что механизм получения файла настроек, работавший в Windows
(одноименный и рядом с exe), в Linux дает неправильное размещение файла.
Пока пришлось жестко прописать имя файла в коде. Далее придется менять
эту схему именования, крайне удобную ранее.

## Versioning / Порядок версий

Номер версии программы указывается по нарастающему принципу и строится
Expand All @@ -153,5 +164,7 @@ feeds_20240703-03.zip), то его содержимое будет распак

## License / Лицензия

Licensed under the [Apache License, Version 2.0](LICENSE).
Licensed under the [Apache License, Version 2.0](LICENSE).
Вы можете использовать эти материалы под свою ответственность.

[![Telegram](https://img.shields.io/badge/t.me-dievdo-blue?logo=telegram)](https://t.me/dievdo)
Loading

0 comments on commit f80e410

Please sign in to comment.