feat: user hash password

pull/34/head
email 3 years ago
parent 516ca61b73
commit 6f3663cd96

@ -5,21 +5,22 @@ type User struct {
CreatedTs int64 `json:"createdTs"`
UpdatedTs int64 `json:"updatedTs"`
OpenId string `json:"openId"`
Name string `json:"name"`
Password string `json:"-"`
OpenId string `json:"openId"`
Name string `json:"name"`
PasswordHash string `json:"-"`
}
type UserCreate struct {
OpenId string `json:"openId"`
Name string `json:"name"`
Password string `json:"password"`
OpenId string
Name string
PasswordHash string
}
type UserPatch struct {
Id int
OpenId *string
OpenId *string
PasswordHash *string
Name *string `json:"name"`
Password *string `json:"password"`
@ -29,9 +30,8 @@ type UserPatch struct {
type UserFind struct {
Id *int `json:"id"`
Name *string `json:"name"`
Password *string
OpenId *string
Name *string `json:"name"`
OpenId *string
}
type UserRenameCheck struct {

@ -42,7 +42,7 @@ func checkDSN(dataDir string) (string, error) {
func GetProfile() Profile {
mode := flag.String("mode", "dev", "")
port := flag.Int("port", 8080, "")
data := flag.String("data", "/var/opt/memos", "")
data := flag.String("data", "", "")
flag.Parse()
dataDir, err := checkDSN(*data)

@ -14,4 +14,4 @@
docker run --name memos --restart always --publish 8080:8080 --volume ~/path/to/your/data/:/var/opt/memos/ neosmemo/memos:next -mode release
```
The default user account is `guest` with password `123456`.
The default user account is `guest` with password `secret`.

@ -8,6 +8,7 @@ import (
"net/http"
"github.com/labstack/echo/v4"
"golang.org/x/crypto/bcrypt"
)
func (s *Server) registerAuthRoutes(g *echo.Group) {
@ -28,9 +29,10 @@ func (s *Server) registerAuthRoutes(g *echo.Group) {
return echo.NewHTTPError(http.StatusUnauthorized, fmt.Sprintf("User not found: %s", login.Name))
}
// Compare the stored password
if login.Password != user.Password {
return echo.NewHTTPError(http.StatusBadRequest, "Incorrect password").SetInternal(err)
// Compare the stored hashed password, with the hashed version of the password that was received.
if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(login.Password)); err != nil {
// If the two passwords don't match, return a 401 status.
return echo.NewHTTPError(http.StatusUnauthorized, "Incorrect password").SetInternal(err)
}
err = setUserSession(c, user)
@ -60,6 +62,13 @@ func (s *Server) registerAuthRoutes(g *echo.Group) {
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted signup request").SetInternal(err)
}
if len(signup.Name) <= 5 {
return echo.NewHTTPError(http.StatusBadRequest, "Username is too short, minimum length is 6.")
}
if len(signup.Password) <= 5 {
return echo.NewHTTPError(http.StatusBadRequest, "Password is too short, minimum length is 6.")
}
userFind := &api.UserFind{
Name: &signup.Name,
}
@ -71,10 +80,15 @@ func (s *Server) registerAuthRoutes(g *echo.Group) {
return echo.NewHTTPError(http.StatusUnauthorized, fmt.Sprintf("Existed user found: %s", signup.Name))
}
passwordHash, err := bcrypt.GenerateFromPassword([]byte(signup.Password), bcrypt.DefaultCost)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to generate password hash").SetInternal(err)
}
userCreate := &api.UserCreate{
Name: signup.Name,
Password: signup.Password,
OpenId: common.GenUUID(),
Name: signup.Name,
PasswordHash: string(passwordHash),
OpenId: common.GenUUID(),
}
user, err = s.UserService.CreateUser(userCreate)
if err != nil {

@ -7,6 +7,7 @@ import (
"net/http"
"github.com/labstack/echo/v4"
"golang.org/x/crypto/bcrypt"
)
func (s *Server) registerUserRoutes(g *echo.Group) {
@ -75,8 +76,7 @@ func (s *Server) registerUserRoutes(g *echo.Group) {
}
userFind := &api.UserFind{
Id: &userId,
Password: &userPasswordCheck.Password,
Id: &userId,
}
user, err := s.UserService.FindUser(userFind)
if err != nil {
@ -84,7 +84,8 @@ func (s *Server) registerUserRoutes(g *echo.Group) {
}
isValid := false
if user != nil {
// Compare the stored hashed password, with the hashed version of the password that was received.
if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(userPasswordCheck.Password)); err == nil {
isValid = true
}
@ -109,6 +110,16 @@ func (s *Server) registerUserRoutes(g *echo.Group) {
userPatch.OpenId = &openId
}
if userPatch.Password != nil && *userPatch.Password != "" {
passwordHash, err := bcrypt.GenerateFromPassword([]byte(*userPatch.Password), bcrypt.DefaultCost)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to generate password hash").SetInternal(err)
}
passwordHashStr := string(passwordHash)
userPatch.PasswordHash = &passwordHashStr
}
user, err := s.UserService.PatchUser(userPatch)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to patch user").SetInternal(err)

@ -2,7 +2,7 @@
CREATE TABLE user (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
password TEXT NOT NULL,
password_hash TEXT NOT NULL,
open_id TEXT NOT NULL,
created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')),
updated_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')),
@ -117,10 +117,21 @@ WHERE
END;
INSERT INTO user
(`id`, `name`, `password`, `open_id`)
INSERT INTO
user (
`id`,
`name`,
`open_id`,
`password_hash`
)
VALUES
(1, 'guest', '123456', 'guest_open_id');
(
1,
'guest',
'guest_open_id',
-- "secret"
'$2a$14$ajq8Q7fbtFRQvXpdCq7Jcuy.Rx1h/L4J60Otx.gyNLbAYctGMJ9tK'
);
INSERT INTO memo
(`content`, `creator_id`)

@ -52,14 +52,14 @@ func createUser(db *DB, create *api.UserCreate) (*api.User, error) {
row, err := db.Db.Query(`
INSERT INTO user (
name,
password,
password_hash,
open_id
)
VALUES (?, ?, ?)
RETURNING id, name, password, open_id, created_ts, updated_ts
RETURNING id, name, password_hash, open_id, created_ts, updated_ts
`,
create.Name,
create.Password,
create.PasswordHash,
create.OpenId,
)
if err != nil {
@ -72,7 +72,7 @@ func createUser(db *DB, create *api.UserCreate) (*api.User, error) {
if err := row.Scan(
&user.Id,
&user.Name,
&user.Password,
&user.PasswordHash,
&user.OpenId,
&user.CreatedTs,
&user.UpdatedTs,
@ -89,8 +89,8 @@ func patchUser(db *DB, patch *api.UserPatch) (*api.User, error) {
if v := patch.Name; v != nil {
set, args = append(set, "name = ?"), append(args, v)
}
if v := patch.Password; v != nil {
set, args = append(set, "password = ?"), append(args, v)
if v := patch.PasswordHash; v != nil {
set, args = append(set, "password_hash = ?"), append(args, v)
}
if v := patch.OpenId; v != nil {
set, args = append(set, "open_id = ?"), append(args, v)
@ -102,7 +102,7 @@ func patchUser(db *DB, patch *api.UserPatch) (*api.User, error) {
UPDATE user
SET `+strings.Join(set, ", ")+`
WHERE id = ?
RETURNING id, name, password, open_id, created_ts, updated_ts
RETURNING id, name, password_hash, open_id, created_ts, updated_ts
`, args...)
if err != nil {
return nil, FormatError(err)
@ -114,7 +114,7 @@ func patchUser(db *DB, patch *api.UserPatch) (*api.User, error) {
if err := row.Scan(
&user.Id,
&user.Name,
&user.Password,
&user.PasswordHash,
&user.OpenId,
&user.CreatedTs,
&user.UpdatedTs,
@ -145,7 +145,7 @@ func findUserList(db *DB, find *api.UserFind) ([]*api.User, error) {
SELECT
id,
name,
password,
password_hash,
open_id,
created_ts,
updated_ts
@ -164,7 +164,7 @@ func findUserList(db *DB, find *api.UserFind) ([]*api.User, error) {
if err := rows.Scan(
&user.Id,
&user.Name,
&user.Password,
&user.PasswordHash,
&user.OpenId,
&user.CreatedTs,
&user.UpdatedTs,

@ -101,7 +101,7 @@ const Signin: React.FC<Props> = () => {
try {
signinBtnsClickLoadingState.setLoading();
await api.login("guest", "123456");
await api.login("guest", "secret");
const user = await userService.doSignIn();
if (user) {

Loading…
Cancel
Save