forked from 0xERR0R/blocky
-
Notifications
You must be signed in to change notification settings - Fork 0
/
api_endpoints.go
139 lines (116 loc) · 3.97 KB
/
api_endpoints.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
package api
import (
"encoding/json"
"net/http"
"strings"
"time"
"github.com/bdittmer/blocky/util"
"github.com/go-chi/chi"
log "github.com/sirupsen/logrus"
)
// BlockingControl interface to control the blocking status
type BlockingControl interface {
EnableBlocking()
DisableBlocking(duration time.Duration, disableGroups []string) error
BlockingStatus() BlockingStatus
}
// ListRefresher interface to control the list refresh
type ListRefresher interface {
RefreshLists()
}
// BlockingEndpoint endpoint for the blocking status control
type BlockingEndpoint struct {
control BlockingControl
}
// ListRefreshEndpoint endpoint for list refresh
type ListRefreshEndpoint struct {
refresher ListRefresher
}
// RegisterEndpoint registers an implementation as HTTP endpoint
func RegisterEndpoint(router chi.Router, t interface{}) {
if a, ok := t.(BlockingControl); ok {
registerBlockingEndpoints(router, a)
}
if a, ok := t.(ListRefresher); ok {
registerListRefreshEndpoints(router, a)
}
}
func registerListRefreshEndpoints(router chi.Router, refresher ListRefresher) {
l := &ListRefreshEndpoint{refresher}
router.Post(PathListsRefresh, l.apiListRefresh)
}
// apiListRefresh is the http endpoint to trigger the refresh of all lists
// @Summary List refresh
// @Description Refresh all lists
// @Tags lists
// @Success 200 "Lists were reloaded"
// @Router /lists/refresh [post]
func (l *ListRefreshEndpoint) apiListRefresh(_ http.ResponseWriter, _ *http.Request) {
l.refresher.RefreshLists()
}
func registerBlockingEndpoints(router chi.Router, control BlockingControl) {
s := &BlockingEndpoint{control}
// register API endpoints
router.Get(PathBlockingEnablePath, s.apiBlockingEnable)
router.Get(PathBlockingDisablePath, s.apiBlockingDisable)
router.Get(PathBlockingStatusPath, s.apiBlockingStatus)
}
// apiBlockingEnable is the http endpoint to enable the blocking status
// @Summary Enable blocking
// @Description enable the blocking status
// @Tags blocking
// @Success 200 "Blocking is enabled"
// @Router /blocking/enable [get]
func (s *BlockingEndpoint) apiBlockingEnable(_ http.ResponseWriter, _ *http.Request) {
log.Info("enabling blocking...")
s.control.EnableBlocking()
}
// apiBlockingDisable is the http endpoint to disable the blocking status
// @Summary Disable blocking
// @Description disable the blocking status
// @Tags blocking
// @Param duration query string false "duration of blocking (Example: 300s, 5m, 1h, 5m30s)" Format(duration)
// @Param groups query string false "groups to disable (comma separated). If empty, disable all groups" Format(string)
// @Success 200 "Blocking is disabled"
// @Failure 400 "Wrong duration format"
// @Failure 400 "Unknown group"
// @Router /blocking/disable [get]
func (s *BlockingEndpoint) apiBlockingDisable(rw http.ResponseWriter, req *http.Request) {
var (
duration time.Duration
groups []string
err error
)
// parse duration from query parameter
durationParam := req.URL.Query().Get("duration")
if len(durationParam) > 0 {
duration, err = time.ParseDuration(durationParam)
if err != nil {
log.Errorf("wrong duration format '%s'", durationParam)
rw.WriteHeader(http.StatusBadRequest)
return
}
}
groupsParam := req.URL.Query().Get("groups")
if len(groupsParam) > 0 {
groups = strings.Split(groupsParam, ",")
}
err = s.control.DisableBlocking(duration, groups)
if err != nil {
log.Error("can't disable the blocking: ", err)
rw.WriteHeader(http.StatusBadRequest)
}
}
// apiBlockingStatus is the http endpoint to get current blocking status
// @Summary Blocking status
// @Description get current blocking status
// @Tags blocking
// @Produce json
// @Success 200 {object} api.BlockingStatus "Returns current blocking status"
// @Router /blocking/status [get]
func (s *BlockingEndpoint) apiBlockingStatus(rw http.ResponseWriter, _ *http.Request) {
status := s.control.BlockingStatus()
response, _ := json.Marshal(status)
_, err := rw.Write(response)
util.LogOnError("unable to write response ", err)
}