-
Notifications
You must be signed in to change notification settings - Fork 2
/
smartapp.go
96 lines (77 loc) · 2.4 KB
/
smartapp.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
package smartappgin
import (
"crypto/rsa"
"github.com/SmartThingsOSS/smartapp-go/pkg/smartapp"
"github.com/SmartThingsOSS/smartapp-go/pkg/smartappcore"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
)
type RequestInterceptor func(params *smartappcore.SmartAppParams)
type ResponseInterceptor func(response *smartapp.ExecutionResponse, err error)
type SmartApp interface {
Handler() gin.HandlerFunc
SetPublicKey(publicKey *rsa.PublicKey)
SetRequestInterceptor(interceptor RequestInterceptor)
SetResponseInterceptor(interceptor ResponseInterceptor)
}
type DefaultSmartApp struct {
App smartappcore.SmartApp
Authenticator *smartappcore.Authenticator
RequestInterceptor RequestInterceptor
ResponseInterceptor ResponseInterceptor
}
func NewSmartApp(definition smartappcore.SmartAppDefinition) SmartApp {
return &DefaultSmartApp{
App: smartappcore.NewSmartApp(definition),
RequestInterceptor: func(params *smartappcore.SmartAppParams) {},
ResponseInterceptor: func(response *smartapp.ExecutionResponse, err error) {},
}
}
func (a *DefaultSmartApp) SetPublicKey(publicKey *rsa.PublicKey) {
if publicKey != nil {
a.Authenticator = smartappcore.NewAuthenticator(publicKey)
}
}
func (a *DefaultSmartApp) SetRequestInterceptor(interceptor RequestInterceptor) {
if interceptor != nil {
a.RequestInterceptor = interceptor
}
}
func (a *DefaultSmartApp) SetResponseInterceptor(interceptor ResponseInterceptor) {
if interceptor != nil {
a.ResponseInterceptor = interceptor
}
}
func (a *DefaultSmartApp) Handler() gin.HandlerFunc {
return func(ctx *gin.Context) {
var request smartapp.ExecutionRequest
var response *smartapp.ExecutionResponse
var err error
if err := ctx.ShouldBindWith(&request, binding.JSON); err != nil {
ctx.AbortWithError(422, err)
}
params := &smartappcore.SmartAppParams{
Request: &request,
Context: ctx,
}
a.RequestInterceptor(params)
if a.Authenticator != nil && request.Lifecycle != smartapp.AppLifecyclePING {
err := a.Authenticator.Verifier.Verify(ctx.Request)
if err != nil {
ctx.Status(401)
return
}
}
response, err = a.App.Handle(params)
a.ResponseInterceptor(response, err)
if err != nil {
ctx.Error(err)
return
}
statusCode := 500
if response.StatusCode > 0 && response.StatusCode < 600 {
statusCode = int(response.StatusCode)
}
ctx.JSON(statusCode, response)
}
}