-
Notifications
You must be signed in to change notification settings - Fork 0
/
handle_login.go
87 lines (71 loc) · 2.67 KB
/
handle_login.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package amoss_login
import (
"encoding/json"
"log"
"math"
"math/rand"
"net/http"
"time"
"github.com/cliffordlab/amoss_services/mathb"
"github.com/cliffordlab/amoss_services/participant"
"golang.org/x/crypto/bcrypt"
)
const errorResJSON = `{"error":"json parsing error","error description":"key or value of json is formatted incorrectly"}`
const errorInvalidIDOrPassword = `{"error":"invalid participant ID or password"}`
//LoginHandler struct used to handle login requests
type LoginHandler struct {
Name string
}
type AmossLoginRequest struct {
ParticipantID int64 `json:"participantID"`
Password string `json:"password"`
Study string `json:"study"`
}
func (lh LoginHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
log.Println("User login request...")
dec := json.NewDecoder(r.Body)
var amr AmossLoginRequest
if err := dec.Decode(&amr); err != nil {
log.Println(err)
w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains")
w.Write([]byte(errorResJSON))
return
}
var currentParticipant participant.Participant
// checkID used to login
log.Println("User logging in with participant ID...")
currentParticipant.ID = amr.ParticipantID
log.Println("Participant ID acquired...")
log.Println("this is the participant ID: " + string(currentParticipant.ID))
ptidLen := int(math.Log10(float64(currentParticipant.ID)) + 1)
digitsToPlaceAtEnd := 10 - ptidLen
for i := 0; i < digitsToPlaceAtEnd; i++ {
currentParticipant.ID = currentParticipant.ID*10 + 0
}
log.Println("this is the participant ID after digitsPlaceAtEnd: " + string(currentParticipant.ID))
participant.Salt(¤tParticipant, currentParticipant.ID, w)
if currentParticipant.Salt == "" {
return
}
password := currentParticipant.Salt + amr.Password
participant.Password(currentParticipant.ID, ¤tParticipant)
if err := bcrypt.CompareHashAndPassword([]byte(currentParticipant.PasswordHash), []byte(password)); err != nil {
log.Println(err)
w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains")
w.Write([]byte(errorInvalidIDOrPassword))
return
}
// save new salt and password hash
var src = rand.NewSource(time.Now().UnixNano())
newSalt := mathb.RandString(58, src)
newPassword := newSalt + amr.Password
// Generate new "hash" to store from user password
newPasswordHash, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost)
if err != nil {
log.Println("bcrypt hash failed")
}
currentParticipant.Salt = newSalt
currentParticipant.PasswordHash = string(newPasswordHash)
participant.AlterSaltAndPasswordHash(¤tParticipant)
participant.LoginParticipant(¤tParticipant, w)
}