routebuildermdl.go 5.61 KiB
Newer Older
Roshan Patil's avatar
Roshan Patil committed
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"
Roshan Patil's avatar
Roshan Patil committed

	"github.com/gin-gonic/gin"
)

// Init routing init
func Init(o, r, c *gin.RouterGroup, JWTKey string) {
Roshan Patil's avatar
Roshan Patil committed
	o.POST("/mql", OpenHandler)
	r.POST("/mql", RestrictedHandler)
	c.POST("/mql", RoleBasedHandler)
	jwtmdl.GlobalJWTKey = JWTKey
Roshan Patil's avatar
Roshan Patil committed
}

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) {
Roshan Patil's avatar
Roshan Patil committed
	var service interface{}
	var found bool
	if isRestricted {
		if isRoleBased {
			service, found = roleBasedServices.Get(name)
		} else {
			service, found = restrictedServices.Get(name)
		}
Roshan Patil's avatar
Roshan Patil committed
	} else {
		service, found = openServices.Get(name)
	}
	if !found {
		loggermdl.LogError("Service Not Found: " + name)
		return nil, errormdl.Wrap("Service Not Found: " + name)
Roshan Patil's avatar
Roshan Patil committed
	}

	if isForm {
		serviceCache := service.(ServiceCache)
		return serviceCache.FormService(formData, principalObj)
Roshan Patil's avatar
Roshan Patil committed
	}
	serviceCache := service.(ServiceCache)
	if serviceCache.IsFormService {
		loggermdl.LogError("FORM_HEADER_MISSING")
		return nil, errormdl.Wrap("Form_Header_Missing")
Roshan Patil's avatar
Roshan Patil committed
	}
	if serviceCache.IsMasterService {
Roshan Patil's avatar
Roshan Patil committed
		return serviceCache.MasterService.Run(data)
Roshan Patil's avatar
Roshan Patil committed
	}
	rs := gjson.ParseBytes(data)
	return serviceCache.Service(&rs, principalObj)
func commonHandler(c *gin.Context, isRestricted, isRoleBased bool, principalObj servicebuildermdl.Principal) {
Roshan Patil's avatar
Roshan Patil committed
	service := c.Request.Header.Get("Service-Header")
	header := c.Request.Header.Get("Content-Type")
Roshan Patil's avatar
Roshan Patil committed
	responseDataObj := setResponseHeader(service)
Roshan Patil's avatar
Roshan Patil committed
	if isMultipartRequest(header) {
		form, multiPartError := c.MultipartForm()
		if errormdl.CheckErr(multiPartError) != nil {
			responseDataObj.Error = errormdl.CheckErr(multiPartError).Error()
			loggermdl.LogError(multiPartError)
Roshan Patil's avatar
Roshan Patil committed
			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)
Roshan Patil's avatar
Roshan Patil committed
			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
		}
Roshan Patil's avatar
Roshan Patil committed
	}
	result, err := executeService(service, reqBody, false, nil, isRestricted, isRoleBased, principalObj)
	if errormdl.CheckErr3(err) != nil {
		responseDataObj.Error = errormdl.CheckErr3(err).Error()
		loggermdl.LogError(err)
Roshan Patil's avatar
Roshan Patil committed
		c.JSON(http.StatusExpectationFailed, responseDataObj)
		return
	}
	responseDataObj.Result = result
	c.JSON(http.StatusOK, responseDataObj)
	return

}

// OpenHandler for /o
Roshan Patil's avatar
Roshan Patil committed
func OpenHandler(c *gin.Context) {
	commonHandler(c, false, false, servicebuildermdl.Principal{})
// RestrictedHandler for /r
Roshan Patil's avatar
Roshan Patil committed
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
Roshan Patil's avatar
Roshan Patil committed
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
Roshan Patil's avatar
Roshan Patil committed
}