/
middleware.go
131 lines (105 loc) · 2.33 KB
/
middleware.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
package tenant
import (
"net"
"net/http"
"github.com/askasoft/pango-xdemo/app"
"github.com/askasoft/pango-xdemo/app/models"
"github.com/askasoft/pango/log"
"github.com/askasoft/pango/xin"
)
//----------------------------------------------------
// Auth Handler
func AuthPassed(c *xin.Context) {
cip := c.ClientIP()
app.AFIPS.Delete(cip)
c.Next()
}
func AuthFailed(c *xin.Context) {
cip := c.ClientIP()
err := app.AFIPS.Increment(cip, 1, 1)
if err != nil {
log.Errorf("Failed to increment AFIPS for '%s'", cip)
}
}
func BasicAuthFailed(c *xin.Context) {
AuthFailed(c)
app.XBA.Unauthorized(c)
}
func CookieAuthFailed(c *xin.Context) {
AuthFailed(c)
app.XCA.Unauthorized(c)
}
//----------------------------------------------------
func SetCtxLogProp(c *xin.Context) {
tt := FromCtx(c)
c.Logger.SetProp("TENANT", string(tt))
}
func CheckTenant(c *xin.Context) {
tt := FromCtx(c)
ok, err := ExistsTenant(tt.Schema())
if err != nil {
c.Logger.Errorf("Failed to check schema '%s': %v", tt.Schema(), err)
c.AbortWithError(http.StatusInternalServerError, err)
return
}
if !ok {
c.AbortWithStatus(http.StatusNotFound)
return
}
c.Next()
}
//----------------------------------------------------
// Auth Protector
func CheckClientIP(c *xin.Context, u *models.User) bool {
cidrs := u.CIDRs()
if len(cidrs) == 0 {
tt := FromCtx(c)
cidrs = tt.GetCIDRs()
}
ip := net.ParseIP(c.ClientIP())
if ip == nil {
return false
}
if len(cidrs) > 0 {
trusted := false
for _, cidr := range cidrs {
if cidr.Contains(ip) {
trusted = true
break
}
}
return trusted
}
return true
}
// IPProtect allow access by cidr of user or tenant
func IPProtect(c *xin.Context) {
au := AuthUser(c)
if !CheckClientIP(c, au) {
c.AbortWithStatus(http.StatusForbidden)
return
}
c.Next()
}
//----------------------------------------------------
// Role Protector
func RoleProtect(c *xin.Context, role string) {
au := AuthUser(c)
if !au.HasRole(role) {
c.AbortWithStatus(http.StatusForbidden)
return
}
c.Next()
}
func RoleSuperProtect(c *xin.Context) {
RoleProtect(c, models.RoleSuper)
}
func RoleAdminProtect(c *xin.Context) {
RoleProtect(c, models.RoleAdmin)
}
func RoleEditorProtect(c *xin.Context) {
RoleProtect(c, models.RoleEditor)
}
func RoleViewerProtect(c *xin.Context) {
RoleProtect(c, models.RoleViewer)
}