VEU.WathBody/1-docs/4-modules/m07-fit-fetch/api_specs/01-garmin-client.md

2.7 KiB
Raw Permalink Blame History

Спецификация 01: GarminClient — SSO и API Garmin Connect

Источники: tech-req разд. 5 (FitFetcher — «по контракту семьи библиотек garminconnect»), Ф-8.1, vision (SSO-последовательность). Прототип: против живого Garmin не автоматизируется; тесты — фейковый HttpMessageHandler с теми же маршрутами.

1. Сигнатуры

public class GarminClient
{
    public GarminClient(string login, string password,
        string baseUrl, HttpMessageHandler? handler = null);
    public void Login(CancellationToken ct = default);   // SSO → Bearer
    public List<GarminActivity> ListActivities(int limit, CancellationToken ct = default);
    public byte[] DownloadFit(long activityId, CancellationToken ct = default);
}

public sealed record GarminActivity(
    long ActivityId, DateTime StartTimeLocal, string ActivityType);

2. Маршруты (по контракту garminconnect; {base} = Garmin.BaseUrl)

Шаг Запрос Что берём
1 GET {base}/sso/embed cookies (SSO)
2 GET {base}/sso/signin csrf из html (name="_csrf")
3 POST {base}/sso/signin (form: username, password, embed, csrf) ticket из редиректа (?ticket=…); неуспех → GarminAuthException
4 GET {base}/modern/?ticket=… cookies современного домена
5 POST {base}/sso/api/2.0/oauth/exchange/service/user/2.0 (OAuth1-подпись тестовыми consumer key/secret) Bearer access_token
6 GET {base}/activitylist-service/activities/search/activities?limit=N&start=0 JSON список: activityId, startTimeLocal, activityType.typeKey
7 GET {base}/download-service/files/activity/{id} байты .fit

Все запросы после шага 5 — заголовок Authorization: Bearer …. Таймаут HttpClient — 30 с. 🛡 пароль и токены в логи не попадают (исключения — без credential-текста).

3. Тестовый handler

FakeGarminHandler : HttpMessageHandler — маршруты разд. 2 на {base}; список и байты .fit задаёт тест (FitParser.WriteTestFile); режим FailLogin — шаг 3 возвращает 401.

4. Ошибки

  • GarminAuthException — шаги 1–5 (логин/MFA/блокировка); текст содержит шаг и код ответа, не содержит пароль;
  • HttpRequestException/TaskCanceledException — сеть/таймаут (сеть сбоит в тестах подменой handler).