From 080e91973c33bfaa0f0972e08b77afc2fece138b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferdinand=20M=C3=BCtsch?= Date: Tue, 21 May 2019 23:09:47 +0200 Subject: [PATCH] Generate default user. --- README.md | 16 +++++++++++----- main.go | 25 +++++++++++++++++++++++-- models/user.go | 5 +++++ 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 88137fa..79bea11 100644 --- a/README.md +++ b/README.md @@ -16,12 +16,17 @@ * Set target port in `config.ini` * Build executable: `go build` * Run server: `./wakapi` -* On your development computers, edit your local `~/.wakatime.cfg` file and add `api_url = https://your.server:someport/api/heartbeat` +* Edit your local `~/.wakatime.cfg` file + * `api_url = https://your.server:someport/api/heartbeat` + * `api_key = the_api_key_printed_to_the_console_after_starting_the_server` +* Open [http://localhost:3000](http://localhost:3000) in your browser -**First run** (create user account): When running the server for the very first time, the database gets populated. Afterwards you have to create yourself a user account. Until proper user sign up and login is implemented, this is done via SQL, like this. -* `mysql -u yourusername -p -H your.hostname` -* `USE yourdatabasename;` -* `INSERT INTO users (id, api_key) VALUES ('your_cool_nickname', '728f084c-85e0-41de-aa2a-b6cc871200c1');` (the latter value is your api key from `~/.wakatime.cfg`) +### User Accounts +* When starting wakapi for the first time, a default user _**admin**_ with password _**admin**_ is created. The corresponding API key is printed to the console. +* Additional users, at the moment, can be added only via SQL statements on your database, like this: + * Connect to your database server: `mysql -u yourusername -p -H your.hostname` (alternatively use GUI tools like _MySQL Workbench_) + * Select your database: `USE yourdatabasename;` + * ADd the new user: `INSERT INTO users (id, password, api_key) VALUES ('your_nickname', MD5('your_password'), '728f084c-85e0-41de-aa2a-b6cc871200c1');` (the latter value should be a random [UUIDv4](https://tools.ietf.org/html/rfc4122), as can be found in your `~/.wakatime.cfg`) ## Best Practices It is recommended to use wakapi behind a **reverse proxy**, like [Caddy](https://caddyserver.com) or _nginx_ to enable **TLS encryption** (HTTPS). @@ -34,6 +39,7 @@ However, if you want to expose your wakapi instance to the public anyway, you ne * Enhanced UI * Loading spinner * Responsiveness +* Support for SQLite database * Dockerize * Unit tests diff --git a/main.go b/main.go index a751773..4e5b2f3 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,8 @@ package main import ( + "crypto/md5" + "encoding/hex" "fmt" "log" "net/http" @@ -13,6 +15,7 @@ import ( "github.com/jinzhu/gorm" "github.com/joho/godotenv" "github.com/rs/cors" + uuid "github.com/satori/go.uuid" ini "gopkg.in/ini.v1" "github.com/n1try/wakapi/middlewares" @@ -87,7 +90,8 @@ func main() { db.AutoMigrate(&models.User{}) db.AutoMigrate(&models.Heartbeat{}).AddForeignKey("user_id", "users(id)", "RESTRICT", "RESTRICT") - // Migrate custom languages + // Custom migrations and initial data + addDefaultUser(db, config) migrateLanguages(db, config) // Services @@ -148,6 +152,23 @@ func migrateLanguages(db *gorm.DB, cfg *models.Config) { if result.Error != nil { log.Fatal(result.Error) } - log.Printf("Migrated %+v rows for custom language %+s.\n", result.RowsAffected, k) + if result.RowsAffected > 0 { + log.Printf("Migrated %+v rows for custom language %+s.\n", result.RowsAffected, k) + } + } +} + +func addDefaultUser(db *gorm.DB, cfg *models.Config) { + pw := md5.Sum([]byte(models.DefaultPassword)) + pwString := hex.EncodeToString(pw[:]) + apiKey := uuid.Must(uuid.NewV4()).String() + u := &models.User{ID: models.DefaultUser, Password: pwString, ApiKey: apiKey} + result := db.FirstOrCreate(u, &models.User{ID: u.ID}) + if result.Error != nil { + log.Println("Unable to create default user.") + log.Fatal(result.Error) + } + if result.RowsAffected > 0 { + log.Printf("Created default user '%s' with password '%s' and API key '%s'.\n", u.ID, models.DefaultPassword, u.ApiKey) } } diff --git a/models/user.go b/models/user.go index 7cb5cdc..98fa99b 100644 --- a/models/user.go +++ b/models/user.go @@ -1,5 +1,10 @@ package models +const ( + DefaultUser string = "admin" + DefaultPassword string = "admin" +) + type User struct { ID string `json:"id" gorm:"primary_key"` ApiKey string `json:"api_key" gorm:"unique"`