/
auth.go
149 lines (129 loc) · 3.34 KB
/
auth.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package api
import (
"context"
"crypto/sha256"
"encoding/hex"
"github.com/supme/directEmail"
"github.com/supme/gonder/models"
"log"
"net/http"
"net/url"
)
type Auth struct {
name string
userID int64
unitID int64
}
func CheckAuth(fn http.HandlerFunc) http.HandlerFunc {
auth := new(Auth)
return func(w http.ResponseWriter, r *http.Request) {
var authorize bool
user, password, _ := r.BasicAuth()
auth.userID, auth.unitID, authorize = check(user, password)
if !authorize {
if user != "" {
ip := models.GetIP(r)
apilog.Printf("%s bad user login '%s'", ip, user)
if models.Config.GonderMail != "" && models.Config.AdminMail != "" {
// ToDo use smtpSender
go func() {
email := directEmail.New()
email.FromEmail = models.Config.GonderMail
email.ToName = models.Config.AdminMail
email.Subject = "Bad login to Gonder"
email.TextPlain(ip + " bad user login '" + user + "'")
email.Render()
if err := email.Send(); err != nil {
apilog.Print("Error send mail:", err)
}
}()
}
}
w.Header().Set("WWW-Authenticate", `Basic realm="Gonder"`)
w.WriteHeader(401)
return
}
auth.name = user
uri, err := url.QueryUnescape(r.RequestURI)
if err != nil {
log.Println(err)
}
apilog.Printf("host: %s user: '%s' %s %s", models.GetIP(r), auth.name, r.Method, uri)
ctx := context.WithValue(r.Context(), "Auth", auth)
fn(w, r.WithContext(ctx))
}
}
func (a *Auth) GroupRight(group interface{}) bool {
if a.IsAdmin() {
return true
}
var r = true
var c int
err := models.Db.QueryRow("SELECT COUNT(*) FROM `auth_user_group` WHERE `auth_user_id`=? AND `group_id`=?", a.userID, group).Scan(&c)
if err != nil {
log.Println(err)
r = false
}
if c == 0 {
r = false
}
return r
}
func (a *Auth) CampaignRight(campaign interface{}) bool {
if a.IsAdmin() {
return true
}
var r = true
var c int
err := models.Db.QueryRow("SELECT COUNT(*) FROM `auth_user_group` WHERE `auth_user_id`=? AND `group_id`=(SELECT `group_id` FROM `campaign` WHERE id=?)", a.userID, campaign).Scan(&c)
if err != nil {
log.Println(err)
r = false
}
if c == 0 {
r = false
}
return r
}
func (a *Auth) Right(right string) bool {
var r bool
if a.IsAdmin() {
return true
}
err := models.Db.QueryRow("SELECT COUNT(auth_right.id) user_right FROM `auth_user` JOIN `auth_unit_right` ON auth_user.auth_unit_id = auth_unit_right.auth_unit_id JOIN `auth_right` ON auth_unit_right.auth_right_id = auth_right.id WHERE auth_user.id = ? AND auth_right.name = ?", a.userID, right).Scan(&r)
if err != nil {
log.Println(err)
return false
}
return r
}
func (a *Auth) IsAdmin() bool {
// admins has group 0
if a.unitID == 0 {
return true
}
return false
}
func check(user, password string) (int64, int64, bool) {
l := false
var passwordHash string
var userID, unitID int64
hash := sha256.New()
hash.Write([]byte(password))
md := hash.Sum(nil)
shaPassword := hex.EncodeToString(md)
err := models.Db.QueryRow("SELECT `id`, `auth_unit_id`, `password` FROM `auth_user` WHERE `name`=?", user).Scan(&userID, &unitID, &passwordHash)
if err != nil {
log.Println(err)
l = false
}
if shaPassword == passwordHash {
l = true
}
return userID, unitID, l
}
//ToDo
func Logout(w http.ResponseWriter, r *http.Request) {
r.Header.Set("Authorization", "Basic")
http.Error(w, "Logout. Bye!", 401)
}