-
Notifications
You must be signed in to change notification settings - Fork 2
/
link.go
153 lines (131 loc) · 3.99 KB
/
link.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
package main
import (
"fmt"
"net/http"
"regexp"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
)
var linkNamePattern *regexp.Regexp = regexp.MustCompile("[a-zA-Z-0-9]+")
var searchPattern *regexp.Regexp = regexp.MustCompile("[a-zA-Z-0-9]*")
// Link type containing information for the redirect entry
type Link struct {
Name string `gorm:"not null;unique_index" form:"name" binding:"required"`
Redirect string `gorm:"not null" form:"redirect" binding:"required"`
Visits int `gorm:"default:0"`
}
// get all links, in alphabetical order
func getAllLinkController(a *App) gin.HandlerFunc {
return func(c *gin.Context) {
search := c.Query("search")
if !searchPattern.Match([]byte(search)) {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"errorMessage": "Incorrect search, must use pattern '[a-zA-Z0-9]*'",
})
return
}
links, err := a.getAllLink(c.Query("search"))
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"errorMessage": fmt.Sprintf("Unable to retrieve links, error: %s", err),
})
log.Errorf("unable to retrieve all links, error: %s", err)
return
}
c.JSON(http.StatusOK, links)
}
}
// create a link, required fields are name and redirect
func createLinkController(a *App) gin.HandlerFunc {
return func(c *gin.Context) {
// Get link body
link, err := getLinkFromContext(c)
if err != nil {
log.Errorf("unable to parse request, error: %s", err)
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"errorMessage": fmt.Sprintf("Unable to parse request, error: %s", err),
})
return
}
if !linkNamePattern.Match([]byte(link.Name)) {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"errorMessage": "Incorrect link name, must use pattern '[a-zA-Z0-9]+'",
})
return
}
// Create link
err = a.createLink(link)
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"errorMessage": fmt.Sprintf("Unable to create link, error: %s", err),
})
log.WithFields(log.Fields{
"name": link.Name,
"redirect": link.Redirect,
}).Errorf("unable to create link, error: %s", err)
return
}
c.JSON(http.StatusOK, nil)
}
}
// update a link, required fields are name and redirect
func updateLinkController(a *App) gin.HandlerFunc {
return func(c *gin.Context) {
// Get path param Name
name := c.Param("Name")
if !linkNamePattern.Match([]byte(name)) {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"errorMessage": "Incorrect link name, must use pattern '[a-zA-Z0-9]+'",
})
return
}
// Get link body
link, err := getLinkFromContext(c)
if err != nil {
log.Errorf("unable to parse request, error: %s", err)
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"errorMessage": fmt.Sprintf("Unable to parse request, error: %s", err),
})
return
}
// Update link
err = a.updateLink(name, link)
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"errorMessage": fmt.Sprintf("Unable to update link, error: %s", err),
})
log.WithFields(log.Fields{
"name": link.Name,
"redirect": link.Redirect,
}).Errorf("unable to update link, error: %s", err)
return
}
c.JSON(http.StatusOK, nil)
}
}
// delete a link with path parameter Name
func deleteLinkController(a *App) gin.HandlerFunc {
return func(c *gin.Context) {
// Get path param Name
name := c.Param("Name")
if !linkNamePattern.Match([]byte(name)) {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"errorMessage": "Incorrect link name, must use pattern '[a-zA-Z0-9]+'",
})
return
}
// Delete link on Name
err := a.DB.Model(&Link{}).
Where("name = ?", name).
Delete(&Link{}).
Error
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"errorMessage": fmt.Sprintf("Unable to delete link, error: %s", err),
})
log.Errorf("unable to delete link with name=%s, error: %s", name, err)
return
}
c.JSON(http.StatusOK, nil)
}
}