forked from kataras/iris
-
Notifications
You must be signed in to change notification settings - Fork 0
/
auth.go
124 lines (101 loc) 路 3.03 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
package user
import (
"errors"
"strconv"
"strings"
"github.com/kataras/iris"
)
// paths
const (
PathLogin = "/user/login"
PathLogout = "/user/logout"
)
// the session key for the user id comes from the Session.
const (
sessionIDKey = "UserID"
)
// AuthController is the user authentication controller, a custom shared controller.
type AuthController struct {
iris.SessionController
Source *DataSource
User Model `iris:"model"`
}
// BeginRequest saves login state to the context, the user id.
func (c *AuthController) BeginRequest(ctx iris.Context) {
c.SessionController.BeginRequest(ctx)
if userID := c.Session.Get(sessionIDKey); userID != nil {
ctx.Values().Set(sessionIDKey, userID)
}
}
func (c *AuthController) fireError(err error) {
if err != nil {
c.Ctx.Application().Logger().Debug(err.Error())
c.Status = 400
c.Data["Title"] = "User Error"
c.Data["Message"] = strings.ToUpper(err.Error())
c.Tmpl = "shared/error.html"
}
}
func (c *AuthController) redirectTo(id int64) {
if id > 0 {
c.Path = "/user/" + strconv.Itoa(int(id))
}
}
func (c *AuthController) createOrUpdate(firstname, username, password string) (user Model, err error) {
username = strings.Trim(username, " ")
if username == "" || password == "" || firstname == "" {
return user, errors.New("empty firstname, username or/and password")
}
userToInsert := Model{
Firstname: firstname,
Username: username,
password: password,
} // password is hashed by the Source.
newUser, err := c.Source.InsertOrUpdate(userToInsert)
if err != nil {
return user, err
}
return newUser, nil
}
func (c *AuthController) isLoggedIn() bool {
// we don't search by session, we have the user id
// already by the `SaveState` middleware.
return c.Values.Get(sessionIDKey) != nil
}
func (c *AuthController) verify(username, password string) (user Model, err error) {
if username == "" || password == "" {
return user, errors.New("please fill both username and password fields")
}
u, found := c.Source.GetByUsername(username)
if !found {
// if user found with that username not found at all.
return user, errors.New("user with that username does not exist")
}
if ok, err := ValidatePassword(password, u.HashedPassword); err != nil || !ok {
// if user found but an error occurred or the password is not valid.
return user, errors.New("please try to login with valid credentials")
}
return u, nil
}
// if logged in then destroy the session
// and redirect to the login page
// otherwise redirect to the registration page.
func (c *AuthController) logout() {
if c.isLoggedIn() {
// c.Manager is the Sessions manager created
// by the embedded SessionController, automatically.
c.Manager.DestroyByID(c.Session.ID())
return
}
c.Path = PathLogin
}
// AllowUser will check if this client is a logged user,
// if not then it will redirect that guest to the login page
// otherwise it will allow the execution of the next handler.
func AllowUser(ctx iris.Context) {
if ctx.Values().Get(sessionIDKey) != nil {
ctx.Next()
return
}
ctx.Redirect(PathLogin)
}