Skip to content
Snippets Groups Projects
Commit 0e999271 authored by Quique's avatar Quique
Browse files

Merge branch 'master' of 0xacab.org:meskio/cicer into password

parents c38d5a64 1a1cd4b2
No related branches found
No related tags found
1 merge request!7UI to change your own password
...@@ -34,8 +34,7 @@ func (a *api) SignIn(w http.ResponseWriter, req *http.Request) { ...@@ -34,8 +34,7 @@ func (a *api) SignIn(w http.ResponseWriter, req *http.Request) {
return return
} }
hash := hashPass(c.Password, member.Salt) if !passwordValid(c.Password, member) {
if subtle.ConstantTimeCompare(hash, member.PassHash) == 0 {
log.Printf("Invalid pass for %s", c.Login) log.Printf("Invalid pass for %s", c.Login)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
...@@ -234,6 +233,11 @@ func newHashPass(password string) (hash []byte, salt []byte, err error) { ...@@ -234,6 +233,11 @@ func newHashPass(password string) (hash []byte, salt []byte, err error) {
return return
} }
func passwordValid(password string, member Member) bool {
hash := hashPass(password, member.Salt)
return subtle.ConstantTimeCompare(hash, member.PassHash) == 1
}
func hashPass(password string, salt []byte) []byte { func hashPass(password string, salt []byte) []byte {
const ( const (
time = 1 time = 1
......
...@@ -11,6 +11,10 @@ import ( ...@@ -11,6 +11,10 @@ import (
"gorm.io/gorm" "gorm.io/gorm"
) )
var (
ErroBadPassword = errors.New("Bad password")
)
type Member struct { type Member struct {
gorm.Model `json:"-"` gorm.Model `json:"-"`
Num int `json:"num" gorm:"unique;index"` Num int `json:"num" gorm:"unique;index"`
...@@ -26,7 +30,8 @@ type Member struct { ...@@ -26,7 +30,8 @@ type Member struct {
type MemberReq struct { type MemberReq struct {
Member Member
Password string `json:"password"` OldPassword string `json:"old_password"`
Password string `json:"password"`
} }
func (a *api) AddMember(w http.ResponseWriter, req *http.Request) { func (a *api) AddMember(w http.ResponseWriter, req *http.Request) {
...@@ -143,7 +148,7 @@ func (a *api) UpdateMember(w http.ResponseWriter, req *http.Request) { ...@@ -143,7 +148,7 @@ func (a *api) UpdateMember(w http.ResponseWriter, req *http.Request) {
return return
} }
m, err := a.updateMember(num, member) m, err := a.updateMember(num, member, false)
if err != nil { if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
...@@ -175,14 +180,16 @@ func (a *api) UpdateMemberMe(num int, w http.ResponseWriter, req *http.Request) ...@@ -175,14 +180,16 @@ func (a *api) UpdateMemberMe(num int, w http.ResponseWriter, req *http.Request)
member.Num = 0 member.Num = 0
member.Balance = -1 member.Balance = -1
m, err := a.updateMember(num, member) m, err := a.updateMember(num, member, true)
if err != nil { if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
return } else if errors.Is(err, ErroBadPassword) {
w.WriteHeader(http.StatusBadRequest)
} else {
log.Printf("Can't update member %d: %v", num, err)
w.WriteHeader(http.StatusInternalServerError)
} }
log.Printf("Can't update member %d: %v", num, err)
w.WriteHeader(http.StatusInternalServerError)
return return
} }
...@@ -196,12 +203,15 @@ func (a *api) UpdateMemberMe(num int, w http.ResponseWriter, req *http.Request) ...@@ -196,12 +203,15 @@ func (a *api) UpdateMemberMe(num int, w http.ResponseWriter, req *http.Request)
} }
} }
func (a *api) updateMember(num int, member MemberReq) (Member, error) { func (a *api) updateMember(num int, member MemberReq, checkPass bool) (Member, error) {
var dbMember Member var dbMember Member
err := a.db.Where("num = ?", num).First(&dbMember).Error err := a.db.Where("num = ?", num).First(&dbMember).Error
if err != nil { if err != nil {
return dbMember, err return dbMember, err
} }
if checkPass && !passwordValid(member.OldPassword, dbMember) {
return dbMember, ErroBadPassword
}
if member.Num != 0 { if member.Num != 0 {
dbMember.Num = member.Num dbMember.Num = member.Num
......
...@@ -110,7 +110,14 @@ func TestMemberUpdateMe(t *testing.T) { ...@@ -110,7 +110,14 @@ func TestMemberUpdateMe(t *testing.T) {
member := testMember member := testMember
member.Password = "foobar" member.Password = "foobar"
member.Email = "other@example.com" member.Email = "other@example.com"
member.OldPassword = "not my password"
resp := tapi.do("PUT", "/member/me", member, nil) resp := tapi.do("PUT", "/member/me", member, nil)
if resp.StatusCode != http.StatusBadRequest {
t.Error("Did accept an invalid password:", resp.Status)
}
member.OldPassword = testMember.Password
resp = tapi.do("PUT", "/member/me", member, nil)
if resp.StatusCode != http.StatusAccepted { if resp.StatusCode != http.StatusAccepted {
t.Fatal("Can't update member:", resp.Status) t.Fatal("Can't update member:", resp.Status)
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment