@@ -3,13 +3,16 @@ package handler
33import (
44 "encoding/json"
55 "errors"
6+ "fmt"
67 "log"
78 "net/http"
89 "regexp"
910 "strings"
11+ "time"
1012
1113 "github.com/telkomdev/tob/config"
1214 "github.com/telkomdev/tob/dashboard/shared"
15+ "github.com/telkomdev/tob/dashboard/utils"
1316)
1417
1518var (
@@ -21,12 +24,20 @@ type WebhookMessage struct {
2124 Message string `json:"message"`
2225}
2326
27+ // LoginPayload type
28+ type LoginPayload struct {
29+ Username string `json:"username"`
30+ Password string `json:"password"`
31+ }
32+
2433// DashboardHTTPHandler type
2534type DashboardHTTPHandler struct {
26- serviceData map [string ]map [string ]interface {}
27- logger * log.Logger
28- webhookTobTokens []string
29- dashboardTitle string
35+ serviceData map [string ]map [string ]interface {}
36+ logger * log.Logger
37+ webhookTobTokens []string
38+ dashboardTitle string
39+ dashboardUsername string
40+ dashboardPassword string
3041}
3142
3243// Data type
@@ -35,6 +46,12 @@ type Data struct {
3546 DashboardTitle string `json:"dashboardTitle"`
3647}
3748
49+ // LoginResponse type
50+ type LoginResponse struct {
51+ Username string `json:"username"`
52+ JWTString string `json:"jwtString"`
53+ }
54+
3855// NewDashboardHTTPHandler DashboardHTTPHandler's constructor
3956func NewDashboardHTTPHandler (tobConfig config.Config , logger * log.Logger ) (* DashboardHTTPHandler , error ) {
4057 if dashboardTitle , ok := tobConfig ["dashboardTitle" ].(string ); ok {
@@ -102,14 +119,104 @@ func NewDashboardHTTPHandler(tobConfig config.Config, logger *log.Logger) (*Dash
102119 serviceData [name ] = services
103120 }
104121
122+ dashboardUsername , ok := tobConfig ["dashboardUsername" ].(string )
123+ if ! ok {
124+ return nil , errors .New ("cannot parse dashboardUsername from configs" )
125+ }
126+
127+ dashboardPassword , ok := tobConfig ["dashboardPassword" ].(string )
128+ if ! ok {
129+ return nil , errors .New ("cannot parse dashboardPassword from configs" )
130+ }
131+
105132 return & DashboardHTTPHandler {
106- dashboardTitle : defaultDashboardTitle ,
107- serviceData : serviceData ,
108- logger : logger ,
109- webhookTobTokens : webhookTobTokens ,
133+ dashboardTitle : defaultDashboardTitle ,
134+ serviceData : serviceData ,
135+ logger : logger ,
136+ webhookTobTokens : webhookTobTokens ,
137+ dashboardUsername : dashboardUsername ,
138+ dashboardPassword : dashboardPassword ,
110139 }, nil
111140}
112141
142+ // Login will handle user login
143+ func (h * DashboardHTTPHandler ) Login (jwtService utils.JwtService ) http.HandlerFunc {
144+ return func (resp http.ResponseWriter , req * http.Request ) {
145+
146+ if req .Method != http .MethodPost {
147+ shared .BuildJSONResponse (resp , shared.Response [shared.EmptyJSON ]{
148+ Success : false ,
149+ Code : 405 ,
150+ Message : "http method not valid" ,
151+ Data : shared.EmptyJSON {},
152+ }, 405 )
153+ return
154+ }
155+
156+ var loginPayload LoginPayload
157+
158+ err := json .NewDecoder (req .Body ).Decode (& loginPayload )
159+ if err != nil {
160+ shared .BuildJSONResponse (resp , shared.Response [shared.EmptyJSON ]{
161+ Success : false ,
162+ Code : 400 ,
163+ Message : "login payload is not valid" ,
164+ Data : shared.EmptyJSON {},
165+ }, 400 )
166+ return
167+ }
168+
169+ hashedPassword , err := utils .Sha256Hex ([]byte (loginPayload .Password ))
170+ if err != nil {
171+ shared .BuildJSONResponse (resp , shared.Response [shared.EmptyJSON ]{
172+ Success : false ,
173+ Code : 400 ,
174+ Message : "login payload is not valid" ,
175+ Data : shared.EmptyJSON {},
176+ }, 400 )
177+ return
178+ }
179+
180+ if h .dashboardUsername != loginPayload .Username || h .dashboardPassword != hashedPassword {
181+ shared .BuildJSONResponse (resp , shared.Response [shared.EmptyJSON ]{
182+ Success : false ,
183+ Code : 401 ,
184+ Message : "username or password is not valid" ,
185+ Data : shared.EmptyJSON {},
186+ }, 401 )
187+ return
188+ }
189+
190+ var claim utils.Claim
191+ claim .Alg = utils .HS256
192+ claim .Subject = h .dashboardUsername
193+ claim .User .ID = h .dashboardUsername
194+ claim .User .FullName = h .dashboardUsername
195+ claim .User .Email = h .dashboardUsername
196+
197+ jwtString , err := jwtService .Generate (& claim , time .Hour * 8766 )
198+ if err != nil {
199+ shared .BuildJSONResponse (resp , shared.Response [shared.EmptyJSON ]{
200+ Success : false ,
201+ Code : 401 ,
202+ Message : "error generating jwt" ,
203+ Data : shared.EmptyJSON {},
204+ }, 401 )
205+ return
206+ }
207+
208+ shared .BuildJSONResponse (resp , shared.Response [LoginResponse ]{
209+ Success : true ,
210+ Code : 200 ,
211+ Message : "login succeed" ,
212+ Data : LoginResponse {
213+ Username : h .dashboardUsername ,
214+ JWTString : fmt .Sprintf ("Bearer %s" , jwtString ),
215+ },
216+ }, 200 )
217+ }
218+ }
219+
113220// GetServices will return tob services
114221func (h * DashboardHTTPHandler ) GetServices () http.HandlerFunc {
115222 return func (resp http.ResponseWriter , req * http.Request ) {
0 commit comments