This repository was archived by the owner on Jun 5, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmiddleware.go
127 lines (110 loc) · 3.62 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
package sandpeople
import (
"context"
"fmt"
"log"
"net/http"
"strings"
)
func getHeader(r *http.Request, name string) string {
headerList := r.Header["X-Sandstorm-"+name]
if len(headerList) == 0 {
return ""
}
return headerList[0]
}
// RequireUser checks the `X-Sandstorm-User-Id` header and determines if the user is logged in or not. If they are, then the
// next middleware is called. If not, then the request is redirected to the path you specify.
func RequireUser(path string) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
log.Println("RequireUser(): entry")
// check to see if there are any of these headers
v := getHeader(r, "User-Id")
if v == "" {
http.Redirect(w, r, path, http.StatusFound)
return
}
if v == "" {
http.Redirect(w, r, path, http.StatusFound)
} else {
next.ServeHTTP(w, r)
}
}
return http.HandlerFunc(fn)
}
}
// HasPerm checks the `X-Sandstorm-Permissions` header and determines if the user has the permission asked for. If they
// do, then the next middleware is called. If not, then the request is redirected to the path you specify.
func HasPerm(perm string, path string) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
log.Println("HasPerm(): entry")
v := getHeader(r, "Permissions")
fmt.Printf("permissions=%s\n", v)
if v == "" {
http.Redirect(w, r, path, http.StatusFound)
return
}
// loop over all permissions
found := false
permissions := strings.Split(v, ",")
for _, permission := range permissions {
if perm == permission {
found = true
}
}
if found {
next.ServeHTTP(w, r)
} else {
http.Redirect(w, r, path, http.StatusFound)
}
}
return http.HandlerFunc(fn)
}
}
// MakeUser gets all of the `X-Sandstorm-*` headers and puts a *User into the request context, and calls the next
// middleware. If the user is not logged in, then the *User will be nil. You can retrieve the user by calling
// GetUser(r).
func MakeUser(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
id := getHeader(r, "User-Id")
if id == "" {
ctx := context.WithValue(r.Context(), userIdKey, nil)
next.ServeHTTP(w, r.WithContext(ctx))
return
}
user := User{
ID: id,
Name: getHeader(r, "Username"),
Permissions: strings.Split(getHeader(r, "Permissions"), ","),
Pronoun: getHeader(r, "User-Pronouns"),
Handle: getHeader(r, "Preferred-Handle"),
Avatar: getHeader(r, "User-Picture"),
}
// default the Pronoun
if user.Pronoun == "" {
user.Pronoun = "neutral"
}
ctx := context.WithValue(r.Context(), userIdKey, &user)
next.ServeHTTP(w, r.WithContext(ctx))
}
return http.HandlerFunc(fn)
}
// MockUser injects `X-Sandstorm-*` headers into the request so that we can fake a user outside of a SandStorm
// environment.
func MockUser(user User) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
fmt.Printf("injecting user\n")
r.Header["X-Sandstorm-User-Id"] = []string{user.ID}
r.Header["X-Sandstorm-Permissions"] = []string{strings.Join(user.Permissions, ",")}
r.Header["X-Sandstorm-Username"] = []string{user.Name}
r.Header["X-Sandstorm-User-Pronouns"] = []string{user.Pronoun}
r.Header["X-Sandstorm-Preferred-Handle"] = []string{user.Handle}
r.Header["X-Sandstorm-User-Picture"] = []string{user.Avatar}
next.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}
}