1
0
mirror of https://github.com/muety/wakapi.git synced 2023-08-10 21:12:56 +03:00

Compare commits

..

7 Commits
1.5.1 ... 1.5.5

Author SHA1 Message Date
Ferdinand Mütsch
25b32e2fec chore: update dockerfile 2020-05-30 12:27:10 +02:00
Ferdinand Mütsch
128f2965cc docs: update readme 2020-05-30 12:14:37 +02:00
Ferdinand Mütsch
9dae5a1f77 feat: allow insecure cookies (resolve #27) 2020-05-30 12:11:25 +02:00
Ferdinand Mütsch
002003a957 chore: make sqlite the default database to easily get started 2020-05-30 12:07:29 +02:00
Ferdinand Mütsch
50eba49547 fix: don't trim hash 2020-05-29 00:04:48 +02:00
Ferdinand Mütsch
75dd070b3d chore: trim white spaces from passwords before hashing them 2020-05-28 23:29:55 +02:00
Ferdinand Mütsch
98d7d02935 docs: update readme 2020-05-28 22:36:00 +02:00
10 changed files with 54 additions and 37 deletions

View File

@@ -1,10 +1,10 @@
ENV=prod ENV=prod
WAKAPI_DB_TYPE=mysql # mysql, postgres, sqlite3 WAKAPI_DB_TYPE=sqlite3 # mysql, postgres, sqlite3
WAKAPI_DB_NAME=wakapi_db # file path for sqlite, e.g. /tmp/wakapi.db WAKAPI_DB_NAME=wakapi_db.db # database name for mysql / postgres or file path for sqlite (e.g. /tmp/wakapi.db)
WAKAPI_DB_USER=myuser WAKAPI_DB_USER=myuser # ignored when using sqlite
WAKAPI_DB_PASSWORD=shhh WAKAPI_DB_PASSWORD=shhh # ignored when using sqlite
WAKAPI_DB_HOST=localhost WAKAPI_DB_HOST=localhost # ignored when using sqlite
WAKAPI_DB_PORT=3306 WAKAPI_DB_PORT=3306 # ignored when using sqlite
WAKAPI_PASSWORD_SALT=shhh WAKAPI_PASSWORD_SALT=shhh # CHANGE !
WAKAPI_DEFAULT_USER_NAME=admin WAKAPI_DEFAULT_USER_NAME=admin
WAKAPI_DEFAULT_USER_PASSWORD=admin123 # CHANGE! WAKAPI_DEFAULT_USER_PASSWORD=admin123 # CHANGE !

View File

@@ -16,6 +16,7 @@ RUN cd /src && go build -o wakapi
# WAKAPI_DB_HOST # WAKAPI_DB_HOST
# WAKAPI_DB_PORT # WAKAPI_DB_PORT
# WAKAPI_DB_NAME # WAKAPI_DB_NAME
# WAKAPI_PASSWORD_SALT
# WAKAPI_DEFAULT_USER_NAME # WAKAPI_DEFAULT_USER_NAME
# WAKAPI_DEFAULT_USER_PASSWORD # WAKAPI_DEFAULT_USER_PASSWORD
@@ -28,14 +29,17 @@ ENV WAKAPI_DB_USER ''
ENV WAKAPI_DB_PASSWORD '' ENV WAKAPI_DB_PASSWORD ''
ENV WAKAPI_DB_HOST '' ENV WAKAPI_DB_HOST ''
ENV WAKAPI_DB_NAME=/data/wakapi.db ENV WAKAPI_DB_NAME=/data/wakapi.db
ENV WAKAPI_PASSWORD_SALT ''
ENV WAKAPI_DEFAULT_USER_NAME admin ENV WAKAPI_DEFAULT_USER_NAME admin
ENV WAKAPI_DEFAULT_USER_PASSWORD admin ENV WAKAPI_DEFAULT_USER_PASSWORD admin
COPY --from=build-env /src/wakapi /app/ COPY --from=build-env /src/wakapi /app/
COPY --from=build-env /src/config.ini /app/ COPY --from=build-env /src/config.ini /app/
COPY --from=build-env /src/version.txt /app/
COPY --from=build-env /src/.env.example /app/.env COPY --from=build-env /src/.env.example /app/.env
RUN sed -i 's/listen = 127.0.0.1/listen = 0.0.0.0/g' /app/config.ini RUN sed -i 's/listen = 127.0.0.1/listen = 0.0.0.0/g' /app/config.ini
RUN sed -i 's/insecure_cookies = false/insecure_cookies = true/g' /app/config.ini
ADD static /app/static ADD static /app/static
ADD data /app/data ADD data /app/data

View File

@@ -17,7 +17,11 @@ If you like this project, please consider supporting it 🙂. You can donate eit
## Prerequisites ## Prerequisites
**On the server side:** **On the server side:**
* Go > 1.13 (with `$GOPATH` properly set) * Go >= 1.13 (with `$GOPATH` properly set)
* gcc (to compile [go-sqlite3](https://github.com/mattn/go-sqlite3))
* Fedora / RHEL: `dnf install @development-tools`
* Ubuntu / Debian: `apt install build-essential`
* Windows: See [here](https://github.com/mattn/go-sqlite3/issues/214#issuecomment-253216476)
* _Optional_: A MySQL- or Postgres database * _Optional_: A MySQL- or Postgres database
**On your local machine:** **On your local machine:**
@@ -25,12 +29,10 @@ If you like this project, please consider supporting it 🙂. You can donate eit
## Server Setup ## Server Setup
### Run from source ### Run from source
1. Enable Go module support: `export GO111MODULE=on` 1. Clone the project
1. Get code: `go get github.com/muety/wakapi`
1. Go to project root: `cd "$GOPATH/src/github.com/muety/wakapi"`
1. Copy `.env.example` to `.env` and set database credentials 1. Copy `.env.example` to `.env` and set database credentials
1. Adapt `config.ini` to your needs 1. Adapt `config.ini` to your needs
1. Build executable: `go build` 1. Build executable: `GO111MODULE=on go build`
1. Run server: `./wakapi` 1. Run server: `./wakapi`
### Run with Docker ### Run with Docker

View File

@@ -2,6 +2,7 @@
listen = 127.0.0.1 listen = 127.0.0.1
port = 3000 port = 3000
base_path = / base_path = /
insecure_cookies = false
[app] [app]
cleanup = false cleanup = false

View File

@@ -57,7 +57,7 @@ func (m *AuthenticateMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Reques
if strings.HasPrefix(r.URL.Path, "/api") { if strings.HasPrefix(r.URL.Path, "/api") {
w.WriteHeader(http.StatusUnauthorized) w.WriteHeader(http.StatusUnauthorized)
} else { } else {
utils.ClearCookie(w, models.AuthCookieKey) utils.ClearCookie(w, models.AuthCookieKey, !m.config.InsecureCookies)
http.Redirect(w, r, fmt.Sprintf("%s/?error=unauthorized", m.config.BasePath), http.StatusFound) http.Redirect(w, r, fmt.Sprintf("%s/?error=unauthorized", m.config.BasePath), http.StatusFound)
} }
return return

View File

@@ -15,31 +15,37 @@ import (
var cfg *Config var cfg *Config
type Config struct { type Config struct {
Env string Env string
Version string Version string
Port int Port int
Addr string Addr string
BasePath string BasePath string
DbHost string DbHost string
DbPort uint DbPort uint
DbUser string DbUser string
DbPassword string DbPassword string
DbName string DbName string
DbDialect string DbDialect string
DbMaxConn uint DbMaxConn uint
CleanUp bool CleanUp bool
DefaultUserName string DefaultUserName string
DefaultUserPassword string DefaultUserPassword string
// this is actually a pepper (https://en.wikipedia.org/wiki/Pepper_(cryptography))
PasswordSalt string PasswordSalt string
SecureCookieHashKey string SecureCookieHashKey string
SecureCookieBlockKey string SecureCookieBlockKey string
InsecureCookies bool
CustomLanguages map[string]string CustomLanguages map[string]string
LanguageColors map[string]string LanguageColors map[string]string
SecureCookie *securecookie.SecureCookie SecureCookie *securecookie.SecureCookie
} }
func (c *Config) IsDev() bool { func (c *Config) IsDev() bool {
return c.Env == "dev" return IsDev(c.Env)
}
func IsDev(env string) bool {
return env == "dev" || env == "development"
} }
func SetConfig(config *Config) { func SetConfig(config *Config) {
@@ -103,6 +109,7 @@ func readConfig() *Config {
dbMaxConn := cfg.Section("database").Key("max_connections").MustUint(1) dbMaxConn := cfg.Section("database").Key("max_connections").MustUint(1)
addr := cfg.Section("server").Key("listen").MustString("127.0.0.1") addr := cfg.Section("server").Key("listen").MustString("127.0.0.1")
insecureCookies := IsDev(env) || cfg.Section("server").Key("insecure_cookies").MustBool(false)
port, err := strconv.Atoi(os.Getenv("PORT")) port, err := strconv.Atoi(os.Getenv("PORT"))
if err != nil { if err != nil {
port = cfg.Section("server").Key("port").MustInt() port = cfg.Section("server").Key("port").MustInt()
@@ -163,6 +170,7 @@ func readConfig() *Config {
DbDialect: dbType, DbDialect: dbType,
DbMaxConn: dbMaxConn, DbMaxConn: dbMaxConn,
CleanUp: cleanUp, CleanUp: cleanUp,
InsecureCookies: insecureCookies,
SecureCookie: secureCookie, SecureCookie: secureCookie,
PasswordSalt: passwordSalt, PasswordSalt: passwordSalt,
DefaultUserName: defaultUserName, DefaultUserName: defaultUserName,

View File

@@ -93,7 +93,7 @@ func (h *IndexHandler) Login(w http.ResponseWriter, r *http.Request) {
Name: models.AuthCookieKey, Name: models.AuthCookieKey,
Value: encoded, Value: encoded,
Path: "/", Path: "/",
Secure: true, Secure: !h.config.InsecureCookies,
HttpOnly: true, HttpOnly: true,
} }
http.SetCookie(w, cookie) http.SetCookie(w, cookie)
@@ -105,7 +105,7 @@ func (h *IndexHandler) Logout(w http.ResponseWriter, r *http.Request) {
loadTemplates() loadTemplates()
} }
utils.ClearCookie(w, models.AuthCookieKey) utils.ClearCookie(w, models.AuthCookieKey, !h.config.InsecureCookies)
http.Redirect(w, r, fmt.Sprintf("%s/", h.config.BasePath), http.StatusFound) http.Redirect(w, r, fmt.Sprintf("%s/", h.config.BasePath), http.StatusFound)
} }

View File

@@ -63,7 +63,8 @@ func IsMd5(hash string) bool {
} }
func CheckPasswordBcrypt(user *models.User, password, salt string) bool { func CheckPasswordBcrypt(user *models.User, password, salt string) bool {
err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password+salt)) plainPassword := []byte(strings.TrimSpace(password) + salt)
err := bcrypt.CompareHashAndPassword([]byte(user.Password), plainPassword)
return err == nil return err == nil
} }
@@ -79,7 +80,8 @@ func CheckPasswordMd5(user *models.User, password string) bool {
// inplace // inplace
func HashPassword(u *models.User, salt string) error { func HashPassword(u *models.User, salt string) error {
bytes, err := bcrypt.GenerateFromPassword([]byte(u.Password+salt), bcrypt.DefaultCost) plainSaltedPassword := []byte(strings.TrimSpace(u.Password) + salt)
bytes, err := bcrypt.GenerateFromPassword(plainSaltedPassword, bcrypt.DefaultCost)
if err == nil { if err == nil {
u.Password = string(bytes) u.Password = string(bytes)
} }

View File

@@ -13,12 +13,12 @@ func RespondJSON(w http.ResponseWriter, status int, object interface{}) {
} }
} }
func ClearCookie(w http.ResponseWriter, name string) { func ClearCookie(w http.ResponseWriter, name string, secure bool) {
http.SetCookie(w, &http.Cookie{ http.SetCookie(w, &http.Cookie{
Name: name, Name: name,
Value: "", Value: "",
Path: "/", Path: "/",
Secure: true, Secure: secure,
HttpOnly: true, HttpOnly: true,
}) })
} }

View File

@@ -1 +1 @@
1.5.1 1.5.5