- Протокол взаимодействия - REST (или что-то на него похожее)
- Хранение данных на стороне сервера: сейчас sqlite, в принципе, несложно перейти на другой вариант SQL БД.
- Аутентификация - basic + https
- сохраняемые данные - пароли (
Account
), текстовые записи (Note
), данные платёжных карт (Card
) и бинарные данные (Binary
). - Шифрование данных: на стороне клиента с помощью мастер-ключа
алгоритмом AES. Данные шифруются перед отправкой на сервер и кэшированием.
Шифруются поля
Opaque
иMeta
структурыRecord
. В полеOpaque
сохраняется содержимоеAccount
,Card
,Note
илиBinary
.
- Внутренние модули:
internal/store/
: код, работающий с БДinternal/server/
: код, работающий в http-сервереinternal/client/
: код, работающий в http-клиентеcmd/server/
: код для запуска сервераcmd/client/
: код для запуска клиентаcmd/server/internal/
, cmd/client/internal` - внутренние модули команд сервера и клиента.
- Сохранение и обновление: при успешной попытке сохранения или обновления на сервере, обновляется также запись в локальном кэше.
- Чтение: делается попытка чтения с сервера. Если не удаётся связаться с сервером -
делается попытка чтения из кэша. При удачной попытке чтения с сервера - кэш
обновляется. Операция
list
локального кэша не обновляет, но при недоступности сервера выводит содержимое локального кэша. - Удаление: при успешном удалении с сервера запись из локального кэша удаляется.
- Предусмотрены операции очистки кэша и единовременного кэширования всех данных.
Общая схема:
go run cmd/client/main.go MODE -a ACTION flags
гдеs
MODE
- один изuser
,cache
,acc
,note
,card
илиbin
ACTION
- для режима
user
один изregister
,verify
илиpassword
- для режима
cache
один изclean
илиsync
- для режимов
acc
,note
илиcard
- один изlist
,store
,get
,update
илиdelete
- для режима
flags
:-h
- получить справку по флагам- для режима
acc
:-i int record ID -n string account name -l string account URL -p string account password -u string account user name -m string account metainfo
- для режима
note
:-i int record ID -n string note name -t string note text -m string note metainfo
- для режима
card
:-i int record ID -n string card name -ch string card holder -num string card number -c string card CVC code -em int card expiry month -ey int card expiry year -m string card metainfo
- для режима
bin
:-i int binary record ID -n string binary record name -f string file name -m string bin record metainfo
- Сделать конфигурационный файл сервера
server.cfg
(имя можно задать в переменной окруженияSERVER_CFG
):{ "store_file": "server_storage.db", "listen_port": 8443, "server_key": "keys/server.key", "server_crt": "keys/server.crt" }
- Скопировать ключ и сертификат сервера в соответствующие файлы.
Можно изготовить самоподписанный сертификат через команду
make key
. - Записать секретную фразу в файл
secret_phrase.txt
или другой, назначить ему режим доступа0400
или0600
. - Сделать конфигурационный файл клиента
gosecret.cfg
(имя можно задать в переменной окруженияGOSECRET_CFG
). Если для сервера применяется самоподписанный сертификат, нужно выставитьhttps_insecure
вtrue
. Режим доступа конфигурационного файла клиента должен быть0400
или0600
.{ "user_name": "user1", "password": "pass", "full_name": "Full Name", "server_address": "https://localhost:8443" "cache_file": "cache_store.db", "https_insecure": true, "key_phrase_file": "secret_phrase.txt" }
- Запустить сервер
go run cmd/server/main.go
- Зарегистрироваться на сервере:
$ go run cmd/client/main.go user -a register 2022/04/30 09:17:26 user is registered with id 1
- Проверить регистрацию:
$ go run cmd/client/main.go user -a verify 2022/04/30 09:18:11 user is verified
Далее показаны действия по работе с аккаунтами (логин-пароль-url-мета). Для других типов данных (платёжные карты и текстовые записи) действия аналогичны. Для бинарных данных примеры приведены ниже - они отличаются заданием имени файла.
-
Сохранить данные аккаунтов:
$ go run cmd/client/main.go acc -a store \ -n "My account" \ -u user123 \ -p pass987 \ -l http://example.com \ -m "test account, some info" accout record stored with id 1 $ go run cmd/client/main.go acc -a store \ -n "Another account" \ -u user22 \ -p passW0RD \ -l http://example.org \ -m "second account, metainfo" accout record stored with id 2
-
Получить список сохранённых аккаунтов:
$ go run cmd/client/main.go acc -a list Id: 2 Type: account Name: Another account Id: 1 Type: account Name: My account
-
Обновить данные аккаунта по ID
$ go run cmd/client/main.go acc -a update \ -i 2 \ -u user22 \ -p passW0RD \ -l https://example.org:4433 \ record updated
-
Обновить метаданные по ID
$ go run cmd/client/main.go acc -a update \ -i 2 \ -m "second account, Meta Info: new info" record updated
-
Обновить имя записи по ID
$ go run cmd/client/main.go acc -a update \ -i 2 \ -n "Yet another account" \ record updated
-
Обновить аккаунт по имени
$ go run cmd/client/main.go acc -a update \ -n "Another account" \ -u user22 \ -p passW0RD \ -l https://example.org:4433 \ -m "second account, Meta Info" record updated
-
Получить запись аккаунта по ID:
$ go run cmd/client/main.go acc -a get -i 2 Type: account Name: Another account Meta info: second account, Meta Info Data: {"url":"https://example.org:4433","user_name":"user22","password":"passW0RD"}
-
Получить запись аккаунта по имени:
$ go run cmd/client/main.go acc -a get -n "Another account" Type: account Name: Another account Meta info: second account, Meta Info Data: {"url":"https://example.org:4433","user_name":"user22","password":"passW0RD"}
-
Удалить аккаунт по ID:
$ go run cmd/client/main.go acc -a delete -i 1 Record 1 deleted
-
Удалить аккаунт по имени:
$ go run cmd/client/main.go acc -a delete -n "Another account" Record 1 deleted
-
Для бинарных данных использование предполагает задание имени файла для исходных данных или для их сохранения на локальной машине.
- для сохранения содержимого файла
FILE_NAME
на сервере:go run cmd/client/main.go bin -a store -n REC_NAME -f FILE_NAME record stored with id 3
- для получения с сервера и сохранения в файле
FILE_NAME
:go run cmd/client/main.go bin -a get -i 3 -f FILE_NAME Type: binary Name: REC_NAME File FILE_NAME is written
- для сохранения содержимого файла
-
Очистка локального кэша
go run cmd/client/main.go cache -a clean 2022/05/15 17:39:59 cache is cleaned
-
Синхронизация кэша с данными сервера
go run cmd/client/main.go cache -a sync 2022/05/15 17:36:57 cache is synchronized
-
Работа от другого пользователя: создать другой файл конфигурации, именить его параметры, указать через переменную окружения:
GOSECRET_CFG=gosecret1.cfg go run cmd/client/main.go user -a register 2022/05/13 22:52:40 user is registered with id 2 GOSECRET_CFG=gosecret1.cfg go run cmd/client/main.go user -a verify 2022/05/13 22:58:04 user is verified
-
В случае утери секретной фразы, зная пароль учётной записи, можно получить список записей, но нельзя получить их секретную часть:
echo "wrongphrase" > keys/secret_key_phrase_2.txt GOSECRET_CFG=gosecret1.cfg go run cmd/client/main.go user -a verify 2022/05/13 23:01:04 user is verified GOSECRET_CFG=gosecret1.cfg go run cmd/client/main.go acc -a list Id: 4 Type: account Name: rec1 GOSECRET_CFG=gosecret1.cfg go run cmd/client/main.go acc -a get -i 4 2022/05/13 23:01:46 cipher: message authentication failed
-
Смена пароля учётной записи:
go run cmd/client/main.go user -a password -p NEW_PASSWORD 2022/05/15 20:26:23 password is changed
После чего необходимо сменить пароль в файле
gosecret.cfg
.
- Вынести настройку тайм-аута клиента http в конфигурационный файл
- Добавить ключ по принудительной работе с локальным кэшем, без обращения к серверу
- Сделать сообщения об ошибках более user friendly. Например, при попытке создания
записи с повторяющимся именем и типом, клиент сейчас пишет
А при попытке получить несуществующую запись
2022/05/13 22:48:15 storing account: http status 500: Cannot Store Record: UNIQUE constraint failed: records.user_id, records.name, records.type
2022/05/13 22:54:58 get account: http status 404