-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
146 lines (116 loc) · 3.63 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
139
140
141
142
143
144
145
146
package main
import (
"fmt"
"net/http"
"strings"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/contrib/sessions"
"github.com/thoas/go-funk"
)
// Note: This is just an example for a tutorial
var (
VALID_AUTHENTICATIONS = []string{"user", "admin", "subscriber"}
)
type User struct {
Username string `form:"username" json:"username" xml:"username" binding:"required"`
AuthType string `form:"authType" json:"authType" xml:"authType" binding:"required"`
}
func main() {
router := gin.Default()
store := sessions.NewCookieStore([]byte("sessionSuperSecret"))
router.Use(sessions.Sessions("sessionName", store))
api := router.Group("/api/v1")
// no authentication endpoints
{
api.POST("/login", loginHandler)
api.GET("/message/:msg", noAuthMessageHandler)
}
// basic authentication endpoints
{
basicAuth := api.Group("/")
basicAuth.Use(AuthenticationRequired())
{
basicAuth.GET("/logout", logoutHandler)
}
}
// admin authentication endpoints
{
adminAuth := api.Group("/admin")
adminAuth.Use(AuthenticationRequired("admin"))
{
adminAuth.GET("/message/:msg", adminMessageHandler)
}
}
// subscriber authentication endpoints
{
subscriberAuth := api.Group("/")
subscriberAuth.Use(AuthenticationRequired("subscriber"))
{
subscriberAuth.GET("/subscriber/message/:msg", subscriberMessageHandler)
}
}
apiV2 := router.Group("/api/v2")
router.Use(AuthenticationRequired("admin", "subscriber"))
// admin and subscriber authentication endpoints
{
apiV2.POST("/post/message/:msg", postMessageHandler)
}
router.Run(":8080")
}
func loginHandler(c *gin.Context) {
var user User
if err := c.ShouldBind(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
session := sessions.Default(c)
if strings.Trim(user.Username, " ") == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "username can't be empty"})
}
if ! funk.ContainsString(VALID_AUTHENTICATIONS, user.AuthType) {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid auth type"})
}
// Note: This is just an example, in real world AuthType would be set by business logic and not the user
session.Set("user", user.Username)
session.Set("authType", user.AuthType)
err := session.Save()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to generate session token"})
return
}
c.JSON(http.StatusOK, gin.H{"message": "authentication successful"})
}
func logoutHandler(c *gin.Context) {
session := sessions.Default(c)
// this would only be hit if the user was authenticated
session.Delete("user")
session.Delete("authType")
err := session.Save()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to generate session token"})
return
}
c.JSON(http.StatusOK, gin.H{"message": "successfully logged out"})
}
func noAuthMessageHandler(c *gin.Context) {
msg := c.Param("msg")
c.JSON(http.StatusOK, gin.H{"message": msg})
}
func subscriberMessageHandler(c *gin.Context) {
msg := c.Param("msg")
session := sessions.Default(c)
user := session.Get("user")
c.JSON(http.StatusOK, gin.H{"message": fmt.Sprintf("Hello Subscriber %s, here's your message: %s", user, msg)})
}
func adminMessageHandler(c *gin.Context) {
msg := c.Param("msg")
session := sessions.Default(c)
user := session.Get("user")
c.JSON(http.StatusOK, gin.H{"message": fmt.Sprintf("Hello Admin %s, here's your message: %s", user, msg)})
}
func postMessageHandler(c *gin.Context) {
msg := c.Param("msg")
session := sessions.Default(c)
user := session.Get("user")
c.JSON(http.StatusOK, gin.H{"message": fmt.Sprintf("Hello Admin/Subscriber %s, your message: %s will be posted", user, msg)})
}