Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
ce97830
Linter, makefile
Feb 18, 2025
daf2d64
DB and migrator
Feb 18, 2025
18806d7
Migrator config
Feb 19, 2025
db82854
Logger
Feb 20, 2025
e8f3a78
auth: proto
Feb 20, 2025
3093b2e
auth: grpc server
Feb 20, 2025
f339b43
auth: server config
Feb 22, 2025
56ff8dd
auth: register
Feb 22, 2025
1e9567a
auth: login
Feb 22, 2025
2491be9
auth: refresh tokens
Feb 23, 2025
5776437
client: move sever app
Feb 24, 2025
47e7e59
client: login ui
Feb 24, 2025
c1b0eb5
client: refactoring
Feb 27, 2025
236cc3f
client: registration form
Feb 27, 2025
fbba804
client: refactoring RPC server
Feb 27, 2025
d61aa4e
client: rpc client
Feb 27, 2025
472dd14
client: login
Feb 28, 2025
2acd9a9
client: registration
Feb 28, 2025
5caee4f
client: rpc refresh tokens
Feb 28, 2025
4c95a9a
client: list of pass categories
Feb 28, 2025
013cac9
client: ui passwords
Mar 1, 2025
3f0dcc3
server: create `data` table
Mar 1, 2025
be9e106
server: rpc `get_all_data`
Mar 2, 2025
9be66cd
server: auth
Mar 2, 2025
f16b11f
server: auth
Mar 2, 2025
ebd3f66
client: add to get all data
Mar 3, 2025
9eb1606
migrator: support sqlite
Mar 3, 2025
53611d1
client: add `data` table
Mar 3, 2025
d1b4b53
client: tokens store
Mar 3, 2025
b7b0f55
client: auth
Mar 3, 2025
02d70e1
client: refactoring
Mar 4, 2025
dc6eb3a
client: sqlite db
Mar 4, 2025
a3ae876
server: refactoring rpc method
Mar 4, 2025
6cd058e
client: get/save items
Mar 4, 2025
20be89a
client: save item values
Mar 5, 2025
d3980a6
client: list items
Mar 5, 2025
9a4f225
client: view password item
Mar 5, 2025
3f297ae
client: view text item
Mar 6, 2025
818bc6a
client: save items
Mar 6, 2025
4fcbb3a
client: refactoring
Mar 7, 2025
df4b96e
client: save item usecase
Mar 7, 2025
c0bd12c
server: without response in server logs
Mar 7, 2025
b56c07b
client: limit
Mar 7, 2025
093c7f9
client: save text item
Mar 7, 2025
e3f7c2e
server: rpc update item
Mar 7, 2025
5446f3a
server: rpc delete item
Mar 7, 2025
e1a5a8e
server: rpc create item
Mar 7, 2025
9c32b83
server: refactoring
Mar 7, 2025
75384d8
client: delete usecase
Mar 7, 2025
dd36831
client: create usecase
Mar 7, 2025
05273f6
client: delete ui
Mar 7, 2025
3e69605
client: ui main page
Mar 7, 2025
6fc5f75
client: create item ui
Mar 7, 2025
5bbe6e1
client: create items on server
Mar 9, 2025
eb8112a
client: delete items on server
Mar 9, 2025
8e523ff
client: encryption
Mar 10, 2025
01eddd7
client: refactoring
Mar 11, 2025
9b4e948
client: ui bank card
Mar 11, 2025
8696cb9
client: ui file
Mar 11, 2025
76a82ee
client: refactoring proto file
Mar 12, 2025
4a65f52
client: sync password
Mar 12, 2025
1fcd2cf
client: sync text
Mar 14, 2025
544a9b4
client: sync file
Mar 14, 2025
d964b2f
client: sync bank card
Mar 14, 2025
0cc902e
client: refactoring
Mar 14, 2025
42c7541
doc
Mar 14, 2025
5def57e
client: view build version and data
Mar 16, 2025
593ddde
client: building
Mar 16, 2025
bffce1c
client: refactoring
Mar 16, 2025
5e8e103
client: tests
Mar 16, 2025
f67f2df
migrator: refactoring
Mar 17, 2025
16d676b
tests: init db
Mar 17, 2025
2caee6c
tests: fixtures
Mar 17, 2025
6d6bcc0
tests: init
Mar 17, 2025
1b5b374
tests: pg container refactoring
Mar 17, 2025
58eda0a
tests: fixture refactoring
Mar 17, 2025
32b22ed
tests: config
Mar 17, 2025
c286826
tests: test suite
Mar 17, 2025
e795951
tests: test rpc server
Mar 17, 2025
581f5b9
tests: nop logger
Mar 17, 2025
fd0640e
server: test login
Mar 17, 2025
cbaf52b
server: test register
Mar 17, 2025
96871ba
server: test get all items
Mar 18, 2025
661ef5f
server: test get by guid
Mar 18, 2025
cfc4411
server: test get all items limit offset
Mar 18, 2025
04c71ee
server: test refactoring
Mar 18, 2025
5cbf092
server: test refresh tokens
Mar 18, 2025
2729d14
server: test create item
Mar 18, 2025
659577d
server: test delete item
Mar 18, 2025
0cef600
server: test update item
Mar 18, 2025
b263531
client: own db for each user
Mar 18, 2025
6d653e3
client: encrypt/decrypt local data while logout/login
Mar 19, 2025
274f9c1
client: refactoring
Mar 19, 2025
4f25aa9
readme
Mar 19, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@

# Binaries
cmd/client/main
cmd/client/agent
cmd/client/client_darwin_amd64
cmd/client/client_linux_amd64
cmd/client/client_windows_amd64
cmd/server/main
cmd/server/server
cmd/migrator/main
cmd/migrator/migrator

# Dependency directories (remove the comment below to include it)
vendor/
Expand All @@ -25,5 +29,16 @@ vendor/
.idea
.vscode

# Data
data/
# Configs
config/migrator_client.yaml
config/migrator_server.yaml
config/server.yaml
config/server_test.yaml
config/client.yaml
config/client_test.yaml

# log
*.log

# client
__debug_bin*
56 changes: 56 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
linters:
enable-all: true
disable:
- nlreturn
- varnamelen
- wsl
- perfsprint
- depguard
- forbidigo
- exhaustruct
- tenv
- tagalign
- nosprintfhostport
- lll
- loggercheck
- paralleltest
- tagliatelle
- gochecknoglobals
- nonamedreturns
- wrapcheck
- gocognit
- cyclop
- exhaustive
- funlen
- nilnil
- mnd
- godox
- gocyclo
- gochecknoinits

linters-settings:
revive:
rules:
- name: var-naming
arguments:
- ["ID"]
- ["VM"]
- - skipPackageNameChecks: true

stylecheck:
checks: ["all", "-ST1003"]

gci:
sections:
- standard # Standard lib
- default # External dependencies
- prefix(github.com/bjlag/go-keeper) # Internal packages

ireturn:
allow:
- anon
- error
- empty
- stdlib
- github\.com\/charmbracelet\/bubbletea\.Model
- github\.com\/golang-migrate\/migrate\/v4\/database\.Driver
102 changes: 102 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
BUILD_VERSION ?= "v1.0.0"
BUILD_DATE ?= $(shell date +'%Y/%m/%d %H:%M:%S')

NAME = $(shell basename "$(PWD)")
DIR = $(shell pwd)
DOCKER_FILE = "docker-compose.local.yaml"

.DEFAULT_GOAL := up

.PHONY: all
all: help

## up: start app
.PHONY: up
up: docker-up wait-db migrate

## down: stop app
.PHONY: down
down: docker-down

wait-db:
@echo " > Wait DB"
@sleep 5

## clean: stop app and remove volumes
.PHONY: clean
clean: docker-down-clear

## docker-up: start docker
.PHONY: docker-up
docker-up:
@echo " > Start docker"
@docker-compose -f $(DIR)/docker/$(DOCKER_FILE) up -d

## docker-down: stop docker
.PHONY: docker-down
docker-down:
@echo " > Stop docker"
@docker-compose -f $(DIR)/docker/$(DOCKER_FILE) down --remove-orphans

## docker-down-clear: stop docker and remove volumes
.PHONY: docker-down-clear
docker-down-clear:
@echo " > Stop docker and remove volumes"
@docker-compose -f $(DIR)/docker/$(DOCKER_FILE) down -v --remove-orphans

## migrate: apply migrations
.PHONY: migrate
migrate:
@echo " > Apply migrations"
@go run $(DIR)/cmd/migrator -c="./config/migrator_server.yaml"

## lint: start linter
.PHONY: lint
lint:
@echo " > Start linter"
@golangci-lint run

## fmt: start fmt
.PHONY: fmt
fmt:
@echo " > Start fmt"
@goimports -local "github.com/bjlag/go-keeper" -d -w $$(find . -type f -name '*.go' -not -path "*_mock.go" -not -path "./internal/generated/*")

## test: start testing
.PHONY: test
test:
@echo " > Testing"
@go test -v $(DIR)/...

## tidy: start `go mod tidy`
.PHONY: tidy
tidy:
@echo " > Go mod tidy"
@GOPATH=$(GOPATH) GOBIN=$(GOBIN) go mod tidy

## proto: generate grpc client/server from proto files
.PHONY: proto
proto:
@echo " > Generate gRPC"
@protoc --go_out=. --go_opt=paths=import --go-grpc_out=. --go-grpc_opt=paths=import --go-grpc_opt=require_unimplemented_servers=false proto/*

## doc: open documentation
.PHONY: doc
doc:
godoc -http=:8888 -play

build-client:
@echo " > Building client for OSX"
@GOOS=darwin GOARCH=amd64 go build -ldflags "-X main.buildVersion=$(BUILD_VERSION) -X 'main.buildDate=$(BUILD_DATE)'" -o ./cmd/client/client_darwin_amd64 ./cmd/client/.
@echo " > Building client for Linux"
@GOOS=linux GOARCH=amd64 go build -ldflags "-X main.buildVersion=$(BUILD_VERSION) -X 'main.buildDate=$(BUILD_DATE)'" -o ./cmd/client/client_linux_amd64 ./cmd/client/.
@echo " > Building client for Windows"
@GOOS=windows GOARCH=amd64 go build -ldflags "-X main.buildVersion=$(BUILD_VERSION) -X 'main.buildDate=$(BUILD_DATE)'" -o ./cmd/client/client_windows_amd64 ./cmd/client/.

.PHONY: help
help: Makefile
@echo
@echo " Choose a command run in "$(NAME)":"
@echo
@sed -n 's/^##//p' $< | column -t -s ':' | sed -e 's/^/ /'
@echo
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# go-keeper

Выпускная работа на курсе "Яндекс Практикум: Продвинутый Go-разработчик".

GoKeeper представляет собой клиент-серверную систему, позволяющую пользователю надёжно и безопасно хранить логины, пароли, бинарные данные и прочую приватную информацию.
66 changes: 66 additions & 0 deletions cmd/client/main.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,71 @@
// Отвечает за запуск клиента.
//
// Конфигурация указывается через флаг -c, описывается в YAML файле:
// - пример ./config/client.yaml.dist
//
// Флаг -version выведет текущую версию и дату сборки.
package main

import (
"context"
"flag"
"fmt"
logNative "log"
"os/signal"
"syscall"

"github.com/ilyakaznacheev/cleanenv"
"go.uber.org/zap"

"github.com/bjlag/go-keeper/internal/app/client"
"github.com/bjlag/go-keeper/internal/infrastructure/logger"
)

const (
// Конфигурация по умолчанию, если не передать флаг конфигурации при старте приложения.
configPathDefault = "./config/client.yaml"
)

var (
viewVersion bool
buildVersion string
buildDate string
)

func main() {
defer func() {
if r := recover(); r != nil {
logNative.Fatalf("panic occurred: %v", r)
}
}()

var configPath string

flag.StringVar(&configPath, "c", configPathDefault, "Path to config file")
flag.BoolVar(&viewVersion, "version", false, "View build version and data")
flag.Parse()

if viewVersion {
fmt.Printf("Version: %s\nBuild: %s\n", buildVersion, buildDate)
return
}

var cfg client.Config
if err := cleanenv.ReadConfig(configPath, &cfg); err != nil {
panic(err)
}

log := logger.Get(cfg.Env)
defer func() {
_ = log.Sync()
}()

log.Debug("Config loaded", zap.Any("config", cfg))

ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGTERM, syscall.SIGINT, syscall.SIGQUIT)
defer cancel()

if err := client.NewApp(cfg, log).Run(ctx); err != nil {
panic(err)
}
}
95 changes: 95 additions & 0 deletions cmd/migrator/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Отвечает за применение миграций к базе данных.
// Поддерживает PostgreSQL и SQLite.
//
// Конфигурация указывается через флаг -c, описывается в YAML файле:
// - пример для клиента ./config/migrator_client.yaml.dist
// - пример для сервера ./config/migrator_server.yaml.dist
package main

import (
"errors"
"flag"
"io/fs"
logNative "log"

"github.com/golang-migrate/migrate/v4"
"github.com/ilyakaznacheev/cleanenv"
"github.com/jmoiron/sqlx"
"go.uber.org/zap"

"github.com/bjlag/go-keeper/internal/infrastructure/db/pg"
"github.com/bjlag/go-keeper/internal/infrastructure/db/sqlite"
"github.com/bjlag/go-keeper/internal/infrastructure/logger"
"github.com/bjlag/go-keeper/internal/infrastructure/migrator"
)

func main() {
defer func() {
if r := recover(); r != nil {
logNative.Fatalf("panic occurred: %v", r)
}
}()

var configPath string

flag.StringVar(&configPath, "c", "", "Path to config file")
flag.Parse()

var cfg migrator.Config
if err := cleanenv.ReadConfig(configPath, &cfg); err != nil {
panic(err)
}

log := logger.Get(cfg.Env)
defer func() {
_ = log.Sync()
}()

log.Debug("Config loaded", zap.Any("config", cfg))
log = log.With(zap.Any("db_type", cfg.Database.Type))

var (
err error
db *sqlx.DB
)

switch cfg.Database.Type {
case migrator.TypePG:
dbConf := cfg.Database
db, err = pg.New(pg.GetDSN(dbConf.Host, dbConf.Port, dbConf.Name, dbConf.User, dbConf.Password)).Connect()
case migrator.TypeSqlite:
db, err = sqlite.New("./client.db").Connect()
}
defer func() {
_ = db.Close()
}()

if err != nil {
log.Error("Failed to open db", zap.Error(err))
panic(err)
}

m, err := migrator.Get(db, cfg.Database.Type, cfg.Database.Name, cfg.SourcePath, cfg.MigrationsTable)
if err != nil {
log.Error("Failed to initialize migrator", zap.Error(err))
panic(err)
}

log.Info("Applying migrations")

if err = m.Up(); err != nil {
if errors.Is(err, migrate.ErrNoChange) {
log.Info("No changes")
return
}
var e *fs.PathError
if errors.As(err, &e) {
log.Info("No migration files")
return
}
log.Error("Migration failed", zap.Error(err))
return
}

log.Info("Migrations applied")
}
Loading