Skip to content

PaulYakow/gophkeeper

Repository files navigation

Менеджер паролей GophKeeper

License

Общая информация

Техническое задание

Клиент-серверная система хранения приватных данных «GophKeeper» (второй выпускной проект курса «Продвинутый Go-разработчик»). Обеспечивает безопасное хранение и передачу следующих данных пользователя:

  • пара логин/пароль
  • данные банковских карт
  • произвольные текстовые данные
  • произвольные бинарные данные (файлы до 1 МБ)

Также для всех типов данных есть возможность хранения произвольной текстовой метаинформации (принадлежность данных к веб-сайту, личности или банку, списки одноразовых кодов активации и прочее).

Клиент и сервер обмениваются данными с помощью gRPC.

Клиент представляет собой CLI-приложение (с терминальным интерфейсом) с возможностью запуска на платформах Windows, Linux и Mac OS. Реализует следующий функционал:

  • регистрация нового пользователя
  • аутентификация существующего пользователя
  • шифрование/расшифровка приватных данных пользователя
  • создание/удаление/обновление приватных данных пользователя

Сервер обслуживает запросы от клиентской программы и реализует следующую логику:

  • обслуживание запроса на регистрацию
  • аутентификация пользователя
  • обслуживание запросов на создание/обновление/удаление приватных данных пользователя
  • работа с базой данных

Пароли пользователей храняться в БД в зашифрованном виде (для шифрования используется bcrypt).

Для аутентификации запросов пользователя, используются токены PaseTo. Токен генерируется при регистрации/аутентификации пользователя и отправляется со всеми командами (кроме register/login).

Архитектура

Функциональная схема

Функциональная схема

Сущности приложения

Сущности приложения

Диаграмма последовательности

Представлена на примере маршрута первичной регистрации пользователя. Диаграмма последовательности

Схема базы данных

В качестве базы данных используется PostgreSQL.

Схема базы данных

Особенности реализации

Сборка

Для сборки клиента и сервера можно использовать следующие команды (прописаны в Makefile):

make client_build
make server_build

Либо аналоги (выполняются из корня проекта):

GOARCH=amd64 GOOS=linux go build -o ${CLIENT_BINARY_NAME}-linux ./cmd/client/main.go
GOARCH=amd64 GOOS=windows go build -o ${CLIENT_BINARY_NAME}-windows ./cmd/client/main.go
GOARCH=amd64 GOOS=darwin go build -o ${CLIENT_BINARY_NAME}-darwin ./cmd/client/main.go
GOARCH=amd64 GOOS=linux go build -o ${SERVER_BINARY_NAME}-linux ./cmd/server/main.go
GOARCH=amd64 GOOS=windows go build -o ${SERVER_BINARY_NAME}-windows ./cmd/server/main.go
GOARCH=amd64 GOOS=darwin go build -o ${SERVER_BINARY_NAME}-darwin ./cmd/server/main.go

Конфигурация

Клиентское и серверное приложения конфигурируются переменными окружения или данными из файла конфигурации (путь к которому задаётся флагом -c при запуске). Приоритет отдаётся переменным окружения.

Если параметр не задан ни в одном из вариантов, то при запуске будет выдана ошибка и приложение завершится с кодом 1.

Клиент

Переменная окружения Параметры из файла Описание
APP_NAME app.name название приложения
APP_VERSION app.version версия приложения
GRPC_ADDRESS grpc.address адрес gRPC-сервера
GRPC_PORT grpc.port порт gRPC-сервера для отправки команд

Сервер

Переменная окружения Параметры из файла Описание
APP_NAME app.name название приложения
APP_VERSION app.version версия приложения
PG_URL нет адрес подключения к базе данных
PG_POOL_MAX postgres.pool_max максимальное количество подключений к БД
PG_CONN_ATTEMPTS postgres.conn_attempts количество попыток подключения к БД
GRPC_PORT grpc.port порт приёма команд и отправки данных по gRPC
TOKEN_KEY нет ключ для подписи токена
TOKEN_ACCESS_DURATION token.access_duration длительность действия токена

Терминальный интерфейс клиента

После успешного запуска клиента в терминале появляется основное меню (main), из которого можно зарегистрировать нового пользователя либо зайти с имеющимся логином/паролем.

После успешного входа (получение токена от сервера) отображается меню с типами данных (units на изображении ниже), хранящихся на сервере. Из него можно перейти к просмотру необходимых списков.

Также в нижней части слева отображается версия приложения клиента.

Навигация по меню осуществляется стрелками вверх/вниз, выбор пункта - клавиша Enter. Также слева от пунктов имеются указания клавиш быстрого доступа - нажатие соответствующей клавиши приведёт к немедленному переходу к соответствующему экрану/меню.

Терминальный интерфейс клиента

Использованные библиотеки

Итоги

Освоенные темы

Анализ ТЗ

Получил полезный опыт формулирования технических требований и построения структуры приложений на основе текстового описания пожеланий к системе (ТЗ).

Архитектура и организация приложения

Скомпоновал подходы, которые использовал для учебного проекта (DevOps трек) и первого выпускного (gophermart).

Понравилось применение подхода "Чистой архитектуры" - приложение получается достаточно гибким для внесения изменений в будущем.

Обмен по gRPC

Намеренно выбрал реализацию через gRPC, чтобы закрепить знания полученные в последнем спринте.

Тестирование

Для изучения подхода TDD применил его при выполнении данного проекта. Поначалу было очень трудозатратно по времени, т.к. непривычно. Потом втянулся и стало получаться быстрее. Подход понравился - написание теста перед кодом получается как некий этап проектирования (а в какой-то степени и документирования) и помогает понять что хочешь от будущего функционала. Намерен изучать и применять в дальнейшем.

Также лучше разобрался с mock-тестированием.

Code-style и выразительность

Старался использовать комментарии для функций, интерфейсов и структур всех импортируемых пакетов, а также, при необходимости, внутренних функций данных пакетов.

Для лучшего изучения и соблюдения code-style локально установил gofumpt и golangci (команда запуска прописана в Makefile).

Также настроил проверку посредством golangci в Github Actions при каждом git push.

Новые библиотеки

Для построения клиентского интерфейса использован пакет rivo/tview. Хорошо документирован (с отдельными примерами для каждого элемента), прост и понятен в применении.

Как возможный вариант рассматривал - charmbracelet/bubbletea.

Возможное развитие проекта

  • Шифрование пользовательских данных с помощью ключей (private-public key).

  • Подгрузка на клиентское приложение только изменившихся данных (например, путём проверки md5-хеша из базы)

  • Для хешей можно завести отдельные таблицы, в которые пересчитывать хеш при обновлении записи. И при чтении с клиента обращаться сначала по хешу (который на клиенте тоже хранится и считается по тем же правилам).

  • Хранение токена и вход без ввода пароля пока токен валиден

  • Больше информативности в TUI (ошибки от сервера и клиента)

  • Необходимость изменять пароль (например, через 1/3/6 месяцев). Неповторяемость паролей.

  • Разбить код отвечающий за TUI на логические части (для более удобного восприятия).

  • Отображение версии сервера в TUI при подключении

Предполагаемая реализация оставшегося по ТЗ функционала

Хранение произвольных бинарных данных (файлы до 1 МБ)

Аналогично остальным типам данных - таблица resources.binary_data в БД:

id user_id data filename metadata
serial int text varchar(255) text

При отображении данного типа на клиенте показывается только имя файла и дополнительная метаинформация.

Также есть возможность отдельным запросом загрузить файл в указанную в конфигурации папку - запрос к БД на чтение колонки data и сохранение данных (возможно чанками в отдельной горутине) в файл с именем filename.

Шифрование/расшифровка приватных данных пользователя

Рассматриваемые варианты:

  • Использование TLS соединения при передаче данных
  • Использование private-public key - сервер при регистрации нового пользователя формирует пару ключей и отправляет публичный ответным сообщением на клиент, где он сохраняется и используется в дальнейшем для шифрования/расшифровки запросов/ответов.

Создание/удаление/обновление приватных данных пользователя

В интерфейсе клиента (TUI) добавится возможность для каждого типа данных (дополнительные кнопки в соответствующем списке) добавить новую запись, изменить или удалить существующую.

В proto-описаниях, соответственно, добавятся процедуры Create, Update, Delete.

В слое repo соответствующие запросы к таблицам.

И далее по слоям ответственности - логика (usecase), обмен данными (controller).

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published