mirror of
https://github.com/muety/wakapi.git
synced 2023-08-10 21:12:56 +03:00
Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
25b32e2fec | |||
128f2965cc | |||
9dae5a1f77 | |||
002003a957 | |||
50eba49547 | |||
75dd070b3d | |||
98d7d02935 |
16
.env.example
16
.env.example
@ -1,10 +1,10 @@
|
||||
ENV=prod
|
||||
WAKAPI_DB_TYPE=mysql # mysql, postgres, sqlite3
|
||||
WAKAPI_DB_NAME=wakapi_db # file path for sqlite, e.g. /tmp/wakapi.db
|
||||
WAKAPI_DB_USER=myuser
|
||||
WAKAPI_DB_PASSWORD=shhh
|
||||
WAKAPI_DB_HOST=localhost
|
||||
WAKAPI_DB_PORT=3306
|
||||
WAKAPI_PASSWORD_SALT=shhh
|
||||
WAKAPI_DB_TYPE=sqlite3 # mysql, postgres, sqlite3
|
||||
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 # ignored when using sqlite
|
||||
WAKAPI_DB_PASSWORD=shhh # ignored when using sqlite
|
||||
WAKAPI_DB_HOST=localhost # ignored when using sqlite
|
||||
WAKAPI_DB_PORT=3306 # ignored when using sqlite
|
||||
WAKAPI_PASSWORD_SALT=shhh # CHANGE !
|
||||
WAKAPI_DEFAULT_USER_NAME=admin
|
||||
WAKAPI_DEFAULT_USER_PASSWORD=admin123 # CHANGE!
|
||||
WAKAPI_DEFAULT_USER_PASSWORD=admin123 # CHANGE !
|
@ -16,6 +16,7 @@ RUN cd /src && go build -o wakapi
|
||||
# – WAKAPI_DB_HOST
|
||||
# – WAKAPI_DB_PORT
|
||||
# – WAKAPI_DB_NAME
|
||||
# – WAKAPI_PASSWORD_SALT
|
||||
# – WAKAPI_DEFAULT_USER_NAME
|
||||
# – WAKAPI_DEFAULT_USER_PASSWORD
|
||||
|
||||
@ -28,14 +29,17 @@ ENV WAKAPI_DB_USER ''
|
||||
ENV WAKAPI_DB_PASSWORD ''
|
||||
ENV WAKAPI_DB_HOST ''
|
||||
ENV WAKAPI_DB_NAME=/data/wakapi.db
|
||||
ENV WAKAPI_PASSWORD_SALT ''
|
||||
ENV WAKAPI_DEFAULT_USER_NAME admin
|
||||
ENV WAKAPI_DEFAULT_USER_PASSWORD admin
|
||||
|
||||
COPY --from=build-env /src/wakapi /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
|
||||
|
||||
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 data /app/data
|
||||
|
12
README.md
12
README.md
@ -17,7 +17,11 @@ If you like this project, please consider supporting it 🙂. You can donate eit
|
||||
|
||||
## Prerequisites
|
||||
**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
|
||||
|
||||
**On your local machine:**
|
||||
@ -25,12 +29,10 @@ If you like this project, please consider supporting it 🙂. You can donate eit
|
||||
|
||||
## Server Setup
|
||||
### Run from source
|
||||
1. Enable Go module support: `export GO111MODULE=on`
|
||||
1. Get code: `go get github.com/muety/wakapi`
|
||||
1. Go to project root: `cd "$GOPATH/src/github.com/muety/wakapi"`
|
||||
1. Clone the project
|
||||
1. Copy `.env.example` to `.env` and set database credentials
|
||||
1. Adapt `config.ini` to your needs
|
||||
1. Build executable: `go build`
|
||||
1. Build executable: `GO111MODULE=on go build`
|
||||
1. Run server: `./wakapi`
|
||||
|
||||
### Run with Docker
|
||||
|
@ -2,6 +2,7 @@
|
||||
listen = 127.0.0.1
|
||||
port = 3000
|
||||
base_path = /
|
||||
insecure_cookies = false
|
||||
|
||||
[app]
|
||||
cleanup = false
|
||||
|
@ -57,7 +57,7 @@ func (m *AuthenticateMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Reques
|
||||
if strings.HasPrefix(r.URL.Path, "/api") {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
} 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)
|
||||
}
|
||||
return
|
||||
|
@ -30,16 +30,22 @@ type Config struct {
|
||||
CleanUp bool
|
||||
DefaultUserName string
|
||||
DefaultUserPassword string
|
||||
// this is actually a pepper (https://en.wikipedia.org/wiki/Pepper_(cryptography))
|
||||
PasswordSalt string
|
||||
SecureCookieHashKey string
|
||||
SecureCookieBlockKey string
|
||||
InsecureCookies bool
|
||||
CustomLanguages map[string]string
|
||||
LanguageColors map[string]string
|
||||
SecureCookie *securecookie.SecureCookie
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -103,6 +109,7 @@ func readConfig() *Config {
|
||||
|
||||
dbMaxConn := cfg.Section("database").Key("max_connections").MustUint(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"))
|
||||
if err != nil {
|
||||
port = cfg.Section("server").Key("port").MustInt()
|
||||
@ -163,6 +170,7 @@ func readConfig() *Config {
|
||||
DbDialect: dbType,
|
||||
DbMaxConn: dbMaxConn,
|
||||
CleanUp: cleanUp,
|
||||
InsecureCookies: insecureCookies,
|
||||
SecureCookie: secureCookie,
|
||||
PasswordSalt: passwordSalt,
|
||||
DefaultUserName: defaultUserName,
|
||||
|
@ -93,7 +93,7 @@ func (h *IndexHandler) Login(w http.ResponseWriter, r *http.Request) {
|
||||
Name: models.AuthCookieKey,
|
||||
Value: encoded,
|
||||
Path: "/",
|
||||
Secure: true,
|
||||
Secure: !h.config.InsecureCookies,
|
||||
HttpOnly: true,
|
||||
}
|
||||
http.SetCookie(w, cookie)
|
||||
@ -105,7 +105,7 @@ func (h *IndexHandler) Logout(w http.ResponseWriter, r *http.Request) {
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,8 @@ func IsMd5(hash 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
|
||||
}
|
||||
|
||||
@ -79,7 +80,8 @@ func CheckPasswordMd5(user *models.User, password string) bool {
|
||||
|
||||
// inplace
|
||||
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 {
|
||||
u.Password = string(bytes)
|
||||
}
|
||||
|
@ -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{
|
||||
Name: name,
|
||||
Value: "",
|
||||
Path: "/",
|
||||
Secure: true,
|
||||
Secure: secure,
|
||||
HttpOnly: true,
|
||||
})
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
1.5.1
|
||||
1.5.5
|
Reference in New Issue
Block a user