@@ -12,39 +12,35 @@ import (
12
12
flow "github.com/nerdynz/flow"
13
13
"github.com/nerdynz/security"
14
14
"github.com/nerdynz/view"
15
- "github.com/sirupsen/logrus "
15
+ "github.com/unrolled/render "
16
16
)
17
17
18
18
// CustomRouter wraps gorilla mux with database, redis and renderer
19
19
type CustomRouter struct {
20
20
// Router *mux.Router
21
21
Mux * bone.Mux
22
+ Renderer * render.Render
23
+ Key security.Key
22
24
Store * datastore.Datastore
23
- AuthHandler func (store * datastore.Datastore , fn http. HandlerFunc , authMethod string ) http. HandlerFunc
25
+ AuthHandler func (w http. ResponseWriter , req * http. Request , ctx * flow. Context , store * datastore.Datastore , fn CustomHandlerFunc , authMethod string )
24
26
}
25
27
26
- func New (store * datastore.Datastore ) * CustomRouter {
28
+ type CustomHandlerFunc func (w http.ResponseWriter , req * http.Request , ctx * flow.Context , store * datastore.Datastore )
29
+
30
+ func New (renderer * render.Render , s * datastore.Datastore , key security.Key ) * CustomRouter {
27
31
customRouter := & CustomRouter {}
28
32
r := bone .New ()
29
33
r .CaseSensitive = false
30
- // r.Handle("/public/", http.StripPrefix("/public/", http.FileServer(http.Dir("./public/"))))
31
- // r.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("./assets/"))))
32
- // r.Handle("/attachments/", http.StripPrefix("/attachments/", http.FileServer(http.Dir(store.Settings.AttachmentsFolder))))
33
34
customRouter .Mux = r
34
- customRouter .Store = store
35
+ customRouter .Store = s
36
+ customRouter .Key = key
37
+ customRouter .Renderer = renderer
35
38
customRouter .AuthHandler = authenticate
36
39
return customRouter
37
40
}
38
41
39
- func CustomAuth (store * datastore.Datastore , authFn func (store * datastore.Datastore , fn http.HandlerFunc , authMethod string ) http.HandlerFunc ) * CustomRouter {
40
- customRouter := & CustomRouter {}
41
- r := bone .New ()
42
- r .CaseSensitive = false
43
- // r.Handle("/public/", http.StripPrefix("/public/", http.FileServer(http.Dir("./public/"))))
44
- // r.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("./assets/"))))
45
- // r.Handle("/attachments/", http.StripPrefix("/attachments/", http.FileServer(http.Dir(store.Settings.AttachmentsFolder))))
46
- customRouter .Mux = r
47
- customRouter .Store = store
42
+ func CustomAuth (renderer * render.Render , s * datastore.Datastore , key security.Key , authFn func (w http.ResponseWriter , req * http.Request , ctx * flow.Context , store * datastore.Datastore , fn CustomHandlerFunc , authMethod string )) * CustomRouter {
43
+ customRouter := New (renderer , s , key )
48
44
customRouter .AuthHandler = authFn
49
45
return customRouter
50
46
}
@@ -57,55 +53,56 @@ func (customRouter *CustomRouter) Application(route string, path string) *bone.R
57
53
58
54
func (customRouter * CustomRouter ) GET (route string , routeFunc CustomHandlerFunc , securityType string ) * bone.Route {
59
55
//route = strings.ToLower(route)
60
- return customRouter .Mux .GetFunc (route , customRouter .customHandler ("GET" , customRouter . Store , routeFunc , securityType ))
56
+ return customRouter .Mux .GetFunc (route , customRouter .handler ("GET" , routeFunc , securityType ))
61
57
}
62
58
63
59
// POST - Post handler
64
60
func (customRouter * CustomRouter ) POST (route string , routeFunc CustomHandlerFunc , securityType string ) * bone.Route {
65
61
//route = strings.ToLower(route)
66
- return customRouter .Mux .PostFunc (route , customRouter .customHandler ("POST" , customRouter . Store , routeFunc , securityType ))
62
+ return customRouter .Mux .PostFunc (route , customRouter .handler ("POST" , routeFunc , securityType ))
67
63
}
68
64
69
65
// PST - Post handler with pst for tidier lines
70
66
func (customRouter * CustomRouter ) PST (route string , routeFunc CustomHandlerFunc , securityType string ) * bone.Route {
71
67
//route = strings.ToLower(route)
72
- return customRouter .Mux .PostFunc (route , customRouter .customHandler ("POST" , customRouter . Store , routeFunc , securityType ))
68
+ return customRouter .Mux .PostFunc (route , customRouter .handler ("POST" , routeFunc , securityType ))
73
69
}
74
70
75
71
// PUT - Put handler
76
72
func (customRouter * CustomRouter ) PUT (route string , routeFunc CustomHandlerFunc , securityType string ) * bone.Route {
77
73
//route = strings.ToLower(route)
78
- return customRouter .Mux .PutFunc (route , customRouter .customHandler ("PUT" , customRouter . Store , routeFunc , securityType ))
74
+ return customRouter .Mux .PutFunc (route , customRouter .handler ("PUT" , routeFunc , securityType ))
79
75
}
80
76
81
77
// PATCH - Patch handler
82
78
func (customRouter * CustomRouter ) PATCH (route string , routeFunc CustomHandlerFunc , securityType string ) * bone.Route {
83
79
//route = strings.ToLower(route)
84
- return customRouter .Mux .PatchFunc (route , customRouter .customHandler ("PATCH" , customRouter . Store , routeFunc , securityType ))
80
+ return customRouter .Mux .PatchFunc (route , customRouter .handler ("PATCH" , routeFunc , securityType ))
85
81
}
86
82
87
83
// OPTIONS - Options handler
88
84
func (customRouter * CustomRouter ) OPTIONS (route string , routeFunc CustomHandlerFunc , securityType string ) * bone.Route {
89
85
//route = strings.ToLower(route)
90
- return customRouter .Mux .OptionsFunc (route , customRouter .customHandler ("OPTIONS" , customRouter . Store , routeFunc , securityType ))
86
+ return customRouter .Mux .OptionsFunc (route , customRouter .handler ("OPTIONS" , routeFunc , securityType ))
91
87
}
92
88
93
89
// DELETE - Delete handler
94
90
func (customRouter * CustomRouter ) DELETE (route string , routeFunc CustomHandlerFunc , securityType string ) * bone.Route {
95
91
//route = strings.ToLower(route)
96
- return customRouter .Mux .DeleteFunc (route , customRouter .customHandler ("DELETE" , customRouter . Store , routeFunc , securityType ))
92
+ return customRouter .Mux .DeleteFunc (route , customRouter .handler ("DELETE" , routeFunc , securityType ))
97
93
}
98
94
99
95
// DEL - Delete handler
100
96
func (customRouter * CustomRouter ) DEL (route string , routeFunc CustomHandlerFunc , securityType string ) * bone.Route {
101
97
//route = strings.ToLower(route)
102
- return customRouter .Mux .DeleteFunc (route , customRouter .customHandler ("DELETE" , customRouter . Store , routeFunc , securityType ))
98
+ return customRouter .Mux .DeleteFunc (route , customRouter .handler ("DELETE" , routeFunc , securityType ))
103
99
}
104
100
105
- func (customRouter * CustomRouter ) customHandler (reqType string , store * datastore.Datastore , fn CustomHandlerFunc , authMethod string ) http.HandlerFunc {
106
- return customRouter .AuthHandler (store , func (w http.ResponseWriter , req * http.Request ) {
107
- fn (flow .New (w , req , store ))
108
- }, authMethod )
101
+ func (customRouter * CustomRouter ) handler (reqType string , fn CustomHandlerFunc , authMethod string ) http.HandlerFunc {
102
+ return func (w http.ResponseWriter , req * http.Request ) {
103
+ flow := flow .New (w , req , customRouter .Renderer , customRouter .Store , customRouter .Key )
104
+ customRouter .AuthHandler (w , req , flow , customRouter .Store , fn , authMethod )
105
+ }
109
106
}
110
107
111
108
// // DefaultHandler wraps default http functions in auth it does not pass the data store to them
@@ -115,88 +112,75 @@ func (customRouter *CustomRouter) customHandler(reqType string, store *datastore
115
112
// }, authMethod)
116
113
// }
117
114
118
- func authenticate (store * datastore.Datastore , fn http.HandlerFunc , authMethod string ) http.HandlerFunc {
119
- return func (w http.ResponseWriter , req * http.Request ) {
120
- // canonical host
121
- if store .Settings .CanonicalURL != "" && store .Settings .ServerIsLVE { // set in ENV
122
- canonical := store .Settings .CanonicalURL
123
- root := strings .ToLower (req .Host )
124
- if ! strings .HasSuffix (root , "/" ) {
125
- root += "/"
115
+ func authenticate (w http.ResponseWriter , req * http.Request , ctx * flow.Context , store * datastore.Datastore , fn CustomHandlerFunc , authMethod string ) {
116
+ // canonical host
117
+ canonical := ctx .Settings .Get ("CANNONICAL_URL" )
118
+ if canonical != "" && ctx .Settings .IsProduction () { // set in ENV
119
+ root := strings .ToLower (req .Host )
120
+ if ! strings .HasSuffix (root , "/" ) {
121
+ root += "/"
122
+ }
123
+ if ! strings .HasSuffix (canonical , "/" ) {
124
+ canonical += "/"
125
+ }
126
+ // logrus.Info("root", root)
127
+ // logrus.Info("root", canonical)
128
+ if canonical != root {
129
+ redirectURL := "http://"
130
+ if ctx .Settings .GetBool ("IS_HTTPS" ) {
131
+ redirectURL = "https://"
126
132
}
127
- if ! strings .HasSuffix (canonical , "/" ) {
128
- canonical += "/"
133
+ redirectURL += strings .TrimRight (canonical , "/" )
134
+ if req .URL .Path != "" {
135
+ redirectURL += req .URL .Path
136
+ // logrus.Info("0", redirectURL)
129
137
}
130
- // logrus.Info("root", root)
131
- // logrus.Info("root", canonical)
132
- if canonical != root {
133
- redirectURL := "http://"
134
- if store .Settings .IsSecured {
135
- redirectURL = "https://"
136
- }
137
- redirectURL += strings .TrimRight (canonical , "/" )
138
- if req .URL .Path != "" {
139
- redirectURL += req .URL .Path
140
- // logrus.Info("0", redirectURL)
141
- }
142
- if req .URL .RawQuery != "" {
143
- redirectURL += "?" + req .URL .RawQuery
144
- // logrus.Info("2", redirectURL)
145
- }
146
- if req .URL .Fragment != "" {
147
- redirectURL += "#" + req .URL .Fragment
148
- // logrus.Info("2", redirectURL)
149
- }
150
-
151
- http .Redirect (w , req , redirectURL , http .StatusMovedPermanently )
152
- return
138
+ if req .URL .RawQuery != "" {
139
+ redirectURL += "?" + req .URL .RawQuery
140
+ // logrus.Info("2", redirectURL)
141
+ }
142
+ if req .URL .Fragment != "" {
143
+ redirectURL += "#" + req .URL .Fragment
144
+ // logrus.Info("2", redirectURL)
153
145
}
154
- }
155
-
156
- // CSRF
157
- // if store.Settings.CheckCSRFViaReferrer {
158
146
159
- // }
160
- if authMethod == security .NoAuth {
161
- fn (w , req )
147
+ http .Redirect (w , req , redirectURL , http .StatusMovedPermanently )
162
148
return
163
149
}
150
+ }
164
151
165
- tableName := "person" // default
166
- api := bone .GetValue (req , "api" )
167
- if api == "api" || api == "admin" {
168
- // default - backwards compatibility
169
- tableName = "person" // we already did this above, this is just for clarity. the default should ALWAYS BE person
170
- } else if api != "" {
171
- tableName = api
172
- }
152
+ if authMethod == security .NoAuth {
153
+ fn (w , req , ctx , store )
154
+ return
155
+ }
173
156
174
- // if we are at this point then we want a login
175
- // check for a logged in user. We always check this incase we need it
176
- loggedInUser , err := security .New (req , store ).LoggedInUser ()
177
- if err != nil {
178
- if err .Error () == "redis: nil" {
179
- // ignore it, its expired from cache
180
- } else {
181
- logrus .Error ("Something wrong with Auth" , err )
182
- }
183
- }
184
- if loggedInUser != nil && loggedInUser .TableName == tableName { // we are in the correct section of the website
185
- fn (w , req )
186
- return
157
+ // if we are at this point then we want a login
158
+ loggedInUser , _ , err := ctx .Padlock .LoggedInUser ()
159
+ if err != nil {
160
+ if err .Error () == "redis: nil" {
161
+ // ignore it, its expired from cache
162
+ ctx .ErrorJSON (http .StatusForbidden , "Login Expired" , err )
163
+ } else {
164
+ ctx .ErrorJSON (http .StatusForbidden , "Auth Failure" , err )
187
165
}
166
+ return
167
+ }
188
168
189
- // if we have reached this point then the user doesn't have access
190
- if authMethod == security .Disallow {
191
- view .JSON (w , http .StatusForbidden , "Not Logged In" )
192
- return
193
- } else if authMethod == security .Redirect {
194
- http .Redirect (w , req , "/Login" , http .StatusFound )
195
- }
169
+ if loggedInUser != nil {
170
+ fn (w , req , ctx , store )
171
+ return
196
172
}
197
- }
198
173
199
- type CustomHandlerFunc func (context * flow.Context )
174
+ // if we have reached this point then the user doesn't have access
175
+ if authMethod == security .Disallow {
176
+ ctx .ErrorJSON (http .StatusForbidden , "You're not currently logged in" , err )
177
+ return
178
+
179
+ }
180
+ if authMethod == security .Redirect {
181
+ ctx .Redirect ("/Login" , http .StatusSeeOther )
182
+ }
183
+ }
200
184
201
185
func appHandler (file string ) func (w http.ResponseWriter , req * http.Request ) {
202
186
return func (w http.ResponseWriter , req * http.Request ) {
0 commit comments