-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.go
138 lines (110 loc) · 3.7 KB
/
main.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
package main
import (
"crypto/subtle"
"fmt"
"log"
"net/http"
"net/http/fcgi"
"os"
"runtime"
"github.com/dgrijalva/jwt-go"
"github.com/joho/godotenv"
)
var mySigningKey []byte
var appAddr string
var username string
var password string
var realm string
var credentialsFile string
var databaseURL string
var featuresURL string
func init() {
var envFile string
envFile = ".uberwald.env"
err := godotenv.Load(envFile)
if err != nil {
log.Fatal("Error loading .env file")
}
runtime.GOMAXPROCS(runtime.NumCPU())
appAddr = os.Getenv("APPADDR") // e.g. "APPADDR=0.0.0.0:3000"
mySigningKey = []byte(os.Getenv("MYSIGNINGKEY")) // e.g. "MYSIGNINGKEY=XXXXXXXXXXXXXXXXXXXXXXXX"
username = os.Getenv("USERNAME")
password = os.Getenv("PASSWORD")
realm = os.Getenv("REALM")
credentialsFile = os.Getenv("CREDENTIALSFILE")
databaseURL = os.Getenv("DATABASEURL")
featuresURL = os.Getenv("FEATURESURL")
}
func isAuthorized(endpoint func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header["Token"] != nil {
token, err := jwt.Parse(r.Header["Token"][0], func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("There was an error")
}
return mySigningKey, nil
})
if err != nil {
fmt.Fprintf(w, err.Error())
}
if token.Valid {
endpoint(w, r)
}
} else {
http.Error(w, "Not Authorized", 401)
}
})
}
// BasicAuth wraps a handler requiring HTTP basic auth for it using the given
// username and password and the specified realm, which shouldn't contain quotes.
//
// Most web browser display a dialog with something like:
//
// The website says: "<realm>"
//
// Which is really stupid so you may want to set the realm to a message rather than
// an actual realm.
func BasicAuth(handler http.HandlerFunc, username, password, realm string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
user, pass, ok := r.BasicAuth()
if !ok || subtle.ConstantTimeCompare([]byte(user), []byte(username)) != 1 || subtle.ConstantTimeCompare([]byte(pass), []byte(password)) != 1 {
w.Header().Set("WWW-Authenticate", `Basic realm="`+realm+`"`)
http.Error(w, "Unauthorized.", http.StatusUnauthorized)
return
}
handler(w, r)
}
}
func basicAuth(h http.Handler, username, password, realm string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
user, pass, ok := r.BasicAuth()
if !ok || subtle.ConstantTimeCompare([]byte(user), []byte(username)) != 1 || subtle.ConstantTimeCompare([]byte(pass), []byte(password)) != 1 {
w.Header().Set("WWW-Authenticate", `Basic realm="`+realm+`"`)
http.Error(w, "Unauthorized.", http.StatusUnauthorized)
return
}
h.ServeHTTP(w, r)
})
}
func main() {
var err error
mux := http.NewServeMux()
if appAddr != "" {
// Run as a local web server
mux.HandleFunc("/urwaldpate/update/geojsonhint.js", sendJS)
mux.HandleFunc("/urwaldpate/update", BasicAuth(update, username, password, realm))
mux.HandleFunc("/urwaldpate/update/upload", BasicAuth(upload, username, password, realm))
mux.HandleFunc("/urwaldpate/hektar", isAuthorized(hektar))
err = http.ListenAndServe(appAddr, mux)
} else {
// Run as FCGI via standard I/O
fs := http.FileServer(http.Dir("static"))
mux.Handle("/fcgi-bin/uberwald/", http.StripPrefix("/fcgi-bin/uberwald", basicAuth(fs, username, password, realm)))
mux.HandleFunc("/fcgi-bin/uberwald/upload", BasicAuth(upload, username, password, realm))
mux.HandleFunc("/fcgi-bin/uberwald/hektar", isAuthorized(hektar))
err = fcgi.Serve(nil, mux)
}
if err != nil {
log.Fatal(err)
}
}