Skip to content

Commit

Permalink
Merge pull request #4 from Karzoug/incr10_mvp
Browse files Browse the repository at this point in the history
MVP: basic client and server functionality
1. file storage of large user files is not implemented
2. client recognizes but cannot resolve data version conflicts
  • Loading branch information
Karzoug authored Aug 17, 2023
2 parents 0e7e7e6 + 706dab2 commit 1ace687
Show file tree
Hide file tree
Showing 156 changed files with 10,180 additions and 6 deletions.
34 changes: 34 additions & 0 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: lint
on:
pull_request:
push:
branches:
- main

jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup go
uses: actions/setup-go@v4
with:
go-version: '1.21'
cache: false
- name: golangci-lint (server)
uses: golangci/golangci-lint-action@v3
with:
version: v1.54.1
working-directory: server
- name: golangci-lint (client)
uses: golangci/golangci-lint-action@v3
with:
version: v1.54.1
working-directory: client
- name: golangci-lint (pkg)
uses: golangci/golangci-lint-action@v3
with:
version: v1.54.1
working-directory: pkg
38 changes: 38 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: release

on:
release:
types: [created]

permissions:
contents: write
packages: write

jobs:
releases-matrix:
name: Release Go Binary
runs-on: ubuntu-latest
strategy:
matrix:
goos: [linux, windows, darwin]
goarch: ["386", amd64, arm64]
exclude:
- goarch: "386"
goos: darwin
- goarch: "386"
goos: windows
steps:
- uses: actions/checkout@v3
- name: Set APP_VERSION env
run: echo APP_VERSION=$(echo ${GITHUB_REF} | rev | cut -d'/' -f 1 | rev ) >> ${GITHUB_ENV}
- name: Set BUILD_TIME env
run: echo BUILD_TIME=$(date) >> ${GITHUB_ENV}
- uses: wangyoucao577/go-release-action@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
goarch: ${{ matrix.goarch }}
project_path: "./client/cmd/"
extra_files: ./client/config/config.yaml
binary_name: "client"
ldflags: -X "main.buildVersion=${{ env.APP_VERSION }}" -X "main.buildDate=${{ env.BUILD_TIME }}"
160 changes: 160 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
name: tests

on:
pull_request:
push:
branches:
- main

jobs:

tests:
runs-on: ubuntu-latest
container: golang:1.21

services:
postgres:
image: postgres
env:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: gophkeeper
options: >-
--health-cmd pg_isready
--health-interval 5s
--health-timeout 5s
--health-retries 5
redis:
image: redis
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
mailpit:
image: axllent/mailpit
ports:
- 1025:1025
- 8025:8025

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Generate TLS cert and key
run: |
cd ./test/
mkdir integration
cd integration/
go run /usr/local/go/src/crypto/tls/generate_cert.go -duration=168h -ca=true -host='localhost' $(date +"%b %d %H:%M:%S %Y")
- name: Build server binary
run: |
cd server/cmd
go build -buildvcs=false -cover -o server
cp server ../../test/integration/server
rm server
- name: Build integration tests
run: |
cd test/
go test -c -o test
cp test ./integration/test
rm test
- name: Apply migrations
run: |
go install -tags 'postgres,sqlite' github.com/golang-migrate/migrate/v4/cmd/migrate@latest
migrate -source file://server/migrations/postgres -database postgres://postgres:postgres@postgres:5432/gophkeeper?sslmode=disable up
migrate -source file://server/migrations/sqlite -database sqlite://vault.db up
cp vault.db ./test/integration/vault.db
rm vault.db
- name: "Run integration tests (postgres + sync map cache)"
run: |
cd ./test/integration/
mkdir cover
chmod +x server
chmod +x test
./test
env:
TEST_GRPC_HOST: localhost
TEST_GRPC_PORT: 8081
TEST_MAIL_HOST: mailpit
TEST_MAIL_PORT: 8025
TEST_REDIS_HOST: redis
TEST_REDIS_PORT: 6379
TEST_BINARY_PATH: ./server
GOCOVERDIR: cover
GOPHKEEPER_SERVICE_STORAGE_URI: postgres://postgres:postgres@postgres:5432/gophkeeper?sslmode=disable
GOPHKEEPER_GRPC_KEY_FILE_NAME: key.pem
GOPHKEEPER_GRPC_CERT_FILE_NAME: cert.pem
GOPHKEEPER_GRPC_HOST: localhost
GOPHKEEPER_GRPC_PORT: 8081
GOPHKEEPER_SMTP_HOST: mailpit
GOPHKEEPER_SMTP_PORT: 1025
GOPHKEEPER_RTASK_STORAGE_URI: redis://redis:6379/1

- name: "Converting coverage to legacy text format"
if: ${{ success() }}
run: |
cd ./test/integration/
go tool covdata textfmt -i=cover -o integration_coverage_postgres.out
rm -rf cover
cd ./../
cp ./integration/integration_coverage_postgres.out integration_coverage_postgres.out
env:
GOCOVERDIR: cover

- name: "Run integration tests (sqlite + redis cache)"
run: |
cd ./test/integration/
mkdir cover
chmod +x server
chmod +x test
./test
env:
TEST_GRPC_HOST: localhost
TEST_GRPC_PORT: 8081
TEST_MAIL_HOST: mailpit
TEST_MAIL_PORT: 8025
TEST_REDIS_HOST: redis
TEST_REDIS_PORT: 6379
TEST_BINARY_PATH: ./server
GOCOVERDIR: cover
GOPHKEEPER_SERVICE_STORAGE_URI: file:vault.db
GOPHKEEPER_GRPC_KEY_FILE_NAME: key.pem
GOPHKEEPER_GRPC_CERT_FILE_NAME: cert.pem
GOPHKEEPER_GRPC_HOST: localhost
GOPHKEEPER_GRPC_PORT: 8081
GOPHKEEPER_SMTP_HOST: mailpit
GOPHKEEPER_SMTP_PORT: 1025
GOPHKEEPER_SERVICE_AUTH_CACHE_URI: redis://redis:6379/2
GOPHKEEPER_SERVICE_MAIL_CACHE_URI: redis://redis:6379/3
GOPHKEEPER_RTASK_STORAGE_URI: redis://redis:6379/1

- name: "Converting coverage to legacy text format"
if: ${{ success() }}
run: |
cd ./test/integration/
go tool covdata textfmt -i=cover -o integration_coverage_sqlite.out
rm -rf cover
cd ./../
cp ./integration/integration_coverage_sqlite.out integration_coverage_sqlite.out
env:
GOCOVERDIR: cover

- name: Run unit tests
run: |
cd ./test/
mkdir unit
cd ./../server
go test -tags fast -coverprofile unit_coverage.out -covermode atomic ./...
cp unit_coverage.out ./../test/unit_coverage.out
rm unit_coverage.out
- name: Upload coverage report to Codecov
if: ${{ success() }}
uses: codecov/codecov-action@v3
with:
files: ./test/integration_coverage_postgres.out,./test/integration_coverage_sqlite.out,./test/unit_coverage.out
token: ${{ secrets.CODECOV_TOKEN }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ server/cmd/server

# Go workspace file
go.work*

# Certificates
*.pem
1 change: 0 additions & 1 deletion .golangci.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ disable-all = true
enable = [
"bodyclose",
"dogsled",
"dupl",
"errcheck",
"goimports",
"goprintffuncname",
Expand Down
49 changes: 49 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
.PHONY: build
build: clean build-client build-server

build-client:
cd client/cmd/ && go build -tags=debug -o client

build-server:
cd server/cmd/ && go build -o server

.PHONY: clean
clean:
rm -f client/cmd/client
rm -f server/cmd/server

up-server: gen-keys
echo -n "GOPHKEEPER_SERVICE_TOKEN_SECRET_KEY=" > server/build/dev_secret_key.env
openssl rand -hex 20 >> server/build/dev_secret_key.env
docker compose -f "server/build/docker-compose.yml" up -d --build

down-server:
docker compose -f "server/build/docker-compose.yml" down -v

start-server:
docker compose -f "server/build/docker-compose.yml" start

stop-server:
docker compose -f "server/build/docker-compose.yml" stop

run-client:
cd ./client/cmd/ && go build -tags=debug -o client
cp ./../config/dev.yaml ./config.yaml
./client

.PHONY: lint
lint:
golangci-lint run ./client/...
golangci-lint run ./server/...
golangci-lint run ./pkg/...
golangci-lint run ./common/...

gen-keys:
go run /usr/local/go/src/crypto/tls/generate_cert.go -duration=168h -ca=true -host='localhost' $(date +"%b %d %H:%M:%S %Y")
cp cert.pem server/build/cert.pem
cp key.pem server/build/key.pem
cp cert.pem client/cmd/cert.pem
rm cert.pem && rm key.pem

gen-grpc:
protoc --go_out=. --go_opt=paths=import --go-grpc_out=. --go-grpc_opt=paths=import common/api/keeper.proto
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
# Менеджер паролей GophKeeper

GophKeeper представляет собой клиент-серверную систему, позволяющую пользователю надёжно и безопасно хранить логины, пароли, бинарные данные и прочую приватную информацию.
[![logo](gophkeeper.png)](gophkeeper.png)

GophKeeper представляет собой клиент-серверную систему, позволяющую пользователю надёжно и безопасно хранить приватную информацию.

Типы хранимой информации:
- пары логин/пароль;
- произвольные текстовые данные;
- произвольные бинарные данные;
- данные банковских карт.

Подробное описание схемы работы приложения, в т.ч. обмена и защиты данных можно найти [здесь](docs/sheme.md).

[![asciicast](https://asciinema.org/a/602664.svg)](https://asciinema.org/a/602664?speed=2.5&t=0:01)

[![asciicast](https://asciinema.org/a/602668.svg)](https://asciinema.org/a/602668?speed=3&t=0:01)

# Запуск
Для локального запуска следует использовать Docker и предложенный Makefile:
- up-server:
- генерирует ключ и сертификат для TLS,
- генерирует случайный секретный ключ, используемый для подписи токенов,
- запускает redis, postgres, mailpit (для перехвата писем от сервера) и сервер GophKeeper;
- на порту 8025 размещает веб-интерфейс mailpit.
- run-client: создает и запускает клиент GophKeeper в папке client/cmd/.
3 changes: 3 additions & 0 deletions client/cmd/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.db
*.log
*.yaml
53 changes: 53 additions & 0 deletions client/cmd/builder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package main

import (
"log/slog"

"github.com/ilyakaznacheev/cleanenv"
"gopkg.in/natefinch/lumberjack.v2"

"github.com/Karzoug/goph_keeper/client/internal/config"
)

var (
logFilename = "log.log"
configFilename = "config.yaml"
)

func buildConfig() (*config.Config, error) {
cfg := new(config.Config)

err := cleanenv.ReadConfig(configFilename, cfg)
if err != nil {
return nil, err
}

cfg.Env = envMode
cfg.Version = buildVersion

return cfg, nil
}

func buildLogger(env config.EnvType) (*slog.Logger, error) {
var log *slog.Logger

w := &lumberjack.Logger{
Filename: logFilename,
MaxSize: 5, // megabytes
MaxBackups: 3,
MaxAge: 28, //days
}

switch env {
case config.EnvDevelopment:
log = slog.New(
slog.NewJSONHandler(w, &slog.HandlerOptions{Level: slog.LevelDebug}),
)
default:
log = slog.New(
slog.NewJSONHandler(w, &slog.HandlerOptions{Level: slog.LevelInfo}),
)
}

return log, nil
}
Loading

0 comments on commit 1ace687

Please sign in to comment.