-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathweb.go
155 lines (132 loc) · 3.51 KB
/
web.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package main
import (
"github.com/gin-gonic/gin"
"github.com/mhvis/planon/planonrpc"
"net/http"
"time"
)
func listenAndServe(apiKeys []string, p *planonrpc.Service) {
r := gin.Default()
r.Use(auth(apiKeys))
r.POST("/getReservations", getReservations(p))
r.POST("/reserveRoom", reserveRoom(p))
r.POST("/endReservation", endReservation(p))
r.POST("/extendReservation", extendReservation(p))
r.POST("/getPropertyList", getPropertyList(p))
r.POST("/getFloorsOfProperty", getFloorsOfProperty(p))
r.POST("/getFreeRooms", getFreeRooms(p))
r.POST("/getMe", getMe(p))
r.Run()
}
// Handlers
func getReservations(p *planonrpc.Service) gin.HandlerFunc {
return func(c *gin.Context) {
start, ok := parseTime(c, c.PostForm("start"))
if !ok {
return
}
end, ok := parseTime(c, c.PostForm("end"))
if !ok {
return
}
reservations, err := p.GetReservations(c.PostForm("room_id"), start, end)
setResponse(c, reservations, err)
}
}
func reserveRoom(p *planonrpc.Service) gin.HandlerFunc {
return func(c *gin.Context) {
start, ok := parseTime(c, c.PostForm("start"))
if !ok {
return
}
end, ok := parseTime(c, c.PostForm("end"))
if !ok {
return
}
err := p.ReserveRoom(c.PostForm("room_id"), c.PostForm("name"), start, end)
setResponse(c, nil, err)
}
}
func endReservation(p *planonrpc.Service) gin.HandlerFunc {
return func(c *gin.Context) {
start, ok := parseTime(c, c.PostForm("start"))
if !ok {
return
}
end, ok := parseTime(c, c.PostForm("end"))
if !ok {
return
}
err := p.EndReservation(c.PostForm("room_id"), start, end)
setResponse(c, nil, err)
}
}
func getPropertyList(p *planonrpc.Service) gin.HandlerFunc {
return func(c *gin.Context) {
properties, err := p.GetPropertyList()
setResponse(c, properties, err)
}
}
func extendReservation(p *planonrpc.Service) gin.HandlerFunc {
return func(c *gin.Context) {
end, ok := parseTime(c, c.PostForm("end"))
if !ok {
return
}
err := p.ExtendReservation(c.PostForm("reservation_id"), end)
setResponse(c, nil, err)
}
}
func getFloorsOfProperty(p *planonrpc.Service) gin.HandlerFunc {
return func(c *gin.Context) {
floors, err := p.GetFloorsOfProperty(c.PostForm("property_id"))
setResponse(c, floors, err)
}
}
func getFreeRooms(p *planonrpc.Service) gin.HandlerFunc {
return func(c *gin.Context) {
rooms, err := p.GetFreeRooms(c.PostForm("property_id"))
setResponse(c, rooms, err)
}
}
func getMe(p *planonrpc.Service) gin.HandlerFunc {
return func(c *gin.Context) {
person, err := p.GetMe()
setResponse(c, person, err)
}
}
// Middleware & helper functions
func auth(validKeys []string) gin.HandlerFunc {
return func(c *gin.Context) {
key := c.GetHeader("X-API-Key")
// Check if key is valid
for _, validKey := range validKeys {
if key == validKey {
return
}
}
// If not valid, abort response
c.Abort()
c.Status(http.StatusUnauthorized)
}
}
// Tries to parse the given time string as RFC3339.
// If it fails, it updates the response and the second bool will be false.
func parseTime(c *gin.Context, s string) (time.Time, bool) {
t, err := time.Parse(time.RFC3339, s)
if err != nil {
c.String(http.StatusBadRequest, err.Error())
return t, false
}
return t, true
}
// Sets the response body with the given data or error and sets the status code accordingly.
func setResponse(c *gin.Context, data interface{}, err error) {
if err != nil {
c.String(http.StatusTeapot, err.Error())
} else if data != nil {
c.IndentedJSON(http.StatusOK, data)
} else {
c.Status(http.StatusNoContent)
}
}