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

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

@ -30,16 +30,22 @@ type Config struct {
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