package routebuildermdl import ( "io/ioutil" "mime/multipart" "net/http" "strings" "corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/authmdl/roleenforcemdl" "corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/loggermdl" "corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/authmdl/jwtmdl" "github.com/tidwall/gjson" "corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/errormdl" "corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/servicebuildermdl" "github.com/gin-gonic/gin" ) // Init routing init func Init(o, r, c *gin.RouterGroup, JWTKey string) { o.POST("/mql", OpenHandler) r.POST("/mql", RestrictedHandler) c.POST("/mql", RoleBasedHandler) jwtmdl.GlobalJWTKey = JWTKey } func setResponseHeader(serviceName string) responseData { rd := responseData{} val, ok := GetResponseHeader(serviceName) if ok { rd.ResponseHeader = val } return rd } func isMultipartRequest(header string) bool { return strings.HasPrefix(header, "multipart/form-data") } func executeService(name string, data []byte, isForm bool, formData *multipart.Form, isRestricted, isRoleBased bool, principalObj servicebuildermdl.Principal) (interface{}, error) { var service interface{} var found bool if isRestricted { if isRoleBased { service, found = roleBasedServices.Get(name) } else { service, found = restrictedServices.Get(name) } } else { service, found = openServices.Get(name) } if !found { loggermdl.LogError("Service Not Found: " + name) return nil, errormdl.Wrap("Service Not Found: " + name) } if isForm { serviceCache := service.(ServiceCache) return serviceCache.FormService(formData, principalObj) } serviceCache := service.(ServiceCache) if serviceCache.IsFormService { loggermdl.LogError("FORM_HEADER_MISSING") return nil, errormdl.Wrap("Form_Header_Missing") } if serviceCache.IsMasterService { return serviceCache.MasterService.Run(data) } rs := gjson.ParseBytes(data) return serviceCache.Service(&rs, principalObj) } func commonHandler(c *gin.Context, isRestricted, isRoleBased bool, principalObj servicebuildermdl.Principal) { service := c.Request.Header.Get("Service-Header") header := c.Request.Header.Get("Content-Type") responseDataObj := setResponseHeader(service) if isMultipartRequest(header) { form, multiPartError := c.MultipartForm() if errormdl.CheckErr(multiPartError) != nil { responseDataObj.Error = errormdl.CheckErr(multiPartError).Error() loggermdl.LogError(multiPartError) c.JSON(http.StatusExpectationFailed, responseDataObj) return } result, err := executeService(service, nil, true, form, isRestricted, isRoleBased, principalObj) if errormdl.CheckErr1(err) != nil { responseDataObj.Error = errormdl.CheckErr1(err).Error() loggermdl.LogError(err) c.JSON(http.StatusExpectationFailed, responseDataObj) return } responseDataObj.Result = result c.JSON(http.StatusOK, responseDataObj) return } var reqBody []byte if c.Request.Body != nil { var readError error reqBody, readError = ioutil.ReadAll(c.Request.Body) if errormdl.CheckErr2(readError) != nil { responseDataObj.Error = errormdl.CheckErr2(readError).Error() loggermdl.LogError(readError) c.JSON(http.StatusExpectationFailed, responseDataObj) return } } result, err := executeService(service, reqBody, false, nil, isRestricted, isRoleBased, principalObj) if errormdl.CheckErr3(err) != nil { responseDataObj.Error = errormdl.CheckErr3(err).Error() loggermdl.LogError(err) c.JSON(http.StatusExpectationFailed, responseDataObj) return } responseDataObj.Result = result c.JSON(http.StatusOK, responseDataObj) return } // OpenHandler for /o func OpenHandler(c *gin.Context) { commonHandler(c, false, false, servicebuildermdl.Principal{}) } // RestrictedHandler for /r func RestrictedHandler(c *gin.Context) { pricipalObj, extractError := extractPricipalObject(c) if extractError != nil { loggermdl.LogError(extractError) c.JSON(http.StatusExpectationFailed, extractError.Error()) return } commonHandler(c, true, false, pricipalObj) } // RoleBasedHandler for /r/c func RoleBasedHandler(c *gin.Context) { pricipalObj, extractError := extractPricipalObject(c) if extractError != nil { loggermdl.LogError(extractError) c.JSON(http.StatusExpectationFailed, extractError.Error()) return } commonHandler(c, true, true, pricipalObj) } func extractPricipalObject(c *gin.Context) (servicebuildermdl.Principal, error) { principal := servicebuildermdl.Principal{} if jwtmdl.GlobalJWTKey == "" { return principal, nil } claim, decodeError := jwtmdl.DecodeToken(c.Request) if errormdl.CheckErr(decodeError) != nil { loggermdl.LogError(decodeError) return principal, errormdl.CheckErr(decodeError) } // ba, marshalError := ffjson.Marshal(claim) // if errormdl.CheckErr(marshalError) != nil { // return principal, errormdl.CheckErr(marshalError) // } // unmarshalError := ffjson.Unmarshal(ba, &principal) // if errormdl.CheckErr(unmarshalError) != nil { // return principal, errormdl.CheckErr(unmarshalError) // } // value, ok := gjson.ParseBytes(ba).Value().(servicebuildermdl.Principal) // if !ok { // return principal, errormdl.Wrap("Object is not of type principal") // } groups, grperr := roleenforcemdl.GetGroupNames(claim, "groups") if errormdl.CheckErr(grperr) != nil { loggermdl.LogError(grperr) return principal, errormdl.CheckErr(grperr) } userID, ok := claim["userId"].(string) if !ok || len(userID) < 2 { loggermdl.LogError("Unable to parse UserID from JWT Token") return principal, errormdl.Wrap("Unable to parse UserID from JWT Token") } principal.Groups = groups principal.UserID = userID return principal, nil }