587 lines
14 KiB
Go
587 lines
14 KiB
Go
package handle
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"be.ems/lib/dborm"
|
|
|
|
"github.com/gorilla/mux"
|
|
g "github.com/gosnmp/gosnmp"
|
|
|
|
"be.ems/lib/global"
|
|
"be.ems/lib/log"
|
|
"be.ems/lib/oauth"
|
|
"be.ems/lib/services"
|
|
"be.ems/lib/session"
|
|
"be.ems/restagent/config"
|
|
)
|
|
|
|
var TodoList []stTodo
|
|
|
|
type stTodo struct {
|
|
No string
|
|
Item string
|
|
Value string
|
|
}
|
|
|
|
type ErrorOAuthResponse struct {
|
|
Error map[string]interface{}
|
|
}
|
|
|
|
type FailOAuthResponse struct {
|
|
Error struct {
|
|
ErrorCode string
|
|
ErrorInfo string
|
|
}
|
|
}
|
|
|
|
type ApiResponse struct {
|
|
ResultCode string
|
|
ResultMessage interface{}
|
|
}
|
|
|
|
var globalSession = session.NewSessManager("restagent")
|
|
|
|
func init() {
|
|
conf := config.GetYamlConfig()
|
|
// Default is a pointer to a GoSNMP struct that contains sensible defaults
|
|
// eg port 161, community public, etc
|
|
g.Default.Target = conf.NE.Addr
|
|
g.Default.Port = conf.NE.Port
|
|
err := g.Default.Connect()
|
|
if err != nil {
|
|
log.Fatalf("Connect() err: %v", err)
|
|
}
|
|
//defer g.Default.Conn.Close()
|
|
}
|
|
|
|
/*
|
|
func IsValidOAuthInfo(oAuthBody OAuthBody) bool {
|
|
log.Debug("IsValidOAuthInfo processing... ")
|
|
|
|
conf := config.GetYamlConfig()
|
|
for _, o := range conf.Auth {
|
|
if oAuthBody.GrantType == o.Type && oAuthBody.UserName == o.User && oAuthBody.Value == o.Password {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func IsWrongOAuthInfo(oAuthBody OAuthBody) bool {
|
|
log.Debug("IsWrongOAuthInfo processing... ")
|
|
|
|
if oAuthBody.GrantType == "" || strings.ToLower(oAuthBody.GrantType) != "password" || oAuthBody.UserName == "" || oAuthBody.Value == "" {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
*/
|
|
|
|
func IsValidOAuthUri(r *http.Request) bool {
|
|
vars := mux.Vars(r)
|
|
Uri := vars["apiCategory"] + "/" + vars["apiVersion"] // 获取Uri
|
|
if Uri != "securityManagement/v1" {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func IsVallidContentType(r *http.Request) bool {
|
|
log.Debug("IsVallidContentType processing ...")
|
|
|
|
ctype := r.Header["Content-Type"]
|
|
if len(ctype) != 0 && !strings.Contains(ctype[0], "application/json") {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func LoginFromOMC(w http.ResponseWriter, r *http.Request) {
|
|
log.Debug("LoginFromOMC processing... ")
|
|
|
|
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen)) //io.LimitReader限制大小
|
|
if err != nil {
|
|
log.Debug(err)
|
|
services.ResponseNotFound404UriNotExist(w, r)
|
|
return
|
|
}
|
|
|
|
// check media type(content type) only support "application/json"
|
|
/* if !IsVallidContentType(r) {
|
|
log.Debug("Invalid Content-Type")
|
|
services.ResponseUnsupportedMediaType415(w)
|
|
return
|
|
}
|
|
|
|
// check extend uri, response 404
|
|
if !IsValidOAuthUri(r) {
|
|
log.Debug("Uri is invalid")
|
|
services.ResponseNotFound404UriNotExist(w, r)
|
|
return
|
|
}
|
|
|
|
*/
|
|
// Error process ....
|
|
// response 400-7
|
|
if !json.Valid([]byte(body)) {
|
|
log.Debug("Invalid Json Format")
|
|
services.ResponseBadRequest400InvalidJson(w)
|
|
return
|
|
}
|
|
|
|
var oAuthBody oauth.OAuthBody
|
|
_ = json.Unmarshal(body, &oAuthBody) //转为json
|
|
log.Debug("body:", string(body), "oAuthBody:", oAuthBody)
|
|
|
|
defer r.Body.Close()
|
|
// response 400-5
|
|
if oauth.IsWrongOAuthInfo(oAuthBody) {
|
|
log.Debug("Wrong parameter value")
|
|
services.ResponseBadRequest400WrongParamValue(w)
|
|
return
|
|
}
|
|
/*
|
|
if oauth.IsValidOAuthInfo(oAuthBody) {
|
|
plist := config.GetPermissionFromConfig(oAuthBody.UserName, oAuthBody.GrantType)
|
|
log.Debug("Permission list:", plist)
|
|
|
|
token := globalSession.NewSession(w, r, plist)
|
|
services.ResponseStatusOK200Login(w, token)
|
|
} else {
|
|
// response 400-4
|
|
log.Debug("Authentication failed, mismatch user or password")
|
|
|
|
services.ResponseBadRequest400IncorrectLogin(w)
|
|
}
|
|
*/
|
|
validUser, changePassword, _ := dborm.XormCheckLoginUser(oAuthBody.UserName,
|
|
oAuthBody.Value, config.GetYamlConfig().Auth.Crypt)
|
|
if validUser {
|
|
// plist := config.GetPermissionFromConfig(oAuthBody.UserName, oAuthBody.GrantType)
|
|
plist := []bool{true, true, true, true}
|
|
log.Debug("Permission list:", plist)
|
|
|
|
token := globalSession.NewSession(w, r, plist)
|
|
services.ResponseStatusOK200Login(w, token, changePassword)
|
|
} else {
|
|
// response 400-4
|
|
log.Error("Authentication failed, mismatch user or password")
|
|
|
|
services.ResponseBadRequest400IncorrectLogin(w)
|
|
}
|
|
return
|
|
}
|
|
|
|
func LogoutFromOMC(w http.ResponseWriter, r *http.Request) {
|
|
log.Debug("LogoutFromOMC processing... ")
|
|
|
|
// check media type(content type) only support "application/json"
|
|
if !IsVallidContentType(r) {
|
|
log.Debug("Invalid Content-Type")
|
|
services.ResponseUnsupportedMediaType415(w)
|
|
return
|
|
}
|
|
|
|
// check extend uri, response 404
|
|
if !IsValidOAuthUri(r) {
|
|
log.Debug("Uri is invalid")
|
|
services.ResponseNotFound404UriNotExist(w, r)
|
|
return
|
|
}
|
|
|
|
// error processing ...
|
|
// 401-1 response
|
|
token, ret := globalSession.IsCarriedToken(r)
|
|
if ret == false {
|
|
log.Debug("AccessToken is not carried")
|
|
services.ResponseUnauthorized401AccessTokenNotCarried(w)
|
|
return
|
|
}
|
|
|
|
// 401-2 response
|
|
if globalSession.IsValidToken(token) == false {
|
|
log.Debug("AccessToken fails or does not exist")
|
|
services.ResponseUnauthorized401AccessTokenNotExist(w)
|
|
return
|
|
}
|
|
|
|
globalSession.EndSession(w, r)
|
|
services.ResponseStatusOK200Null(w)
|
|
return
|
|
}
|
|
|
|
func HandshakeFromOMC(w http.ResponseWriter, r *http.Request) {
|
|
log.Debug("HandshakeFromOMC processing... ")
|
|
|
|
// check media type(content type) only support "application/json"
|
|
if !IsVallidContentType(r) {
|
|
log.Debug("Invalid Content-Type")
|
|
services.ResponseUnsupportedMediaType415(w)
|
|
return
|
|
}
|
|
|
|
// check extend uri, response 404
|
|
if !IsValidOAuthUri(r) {
|
|
log.Debug("Uri is invalid")
|
|
services.ResponseNotFound404UriNotExist(w, r)
|
|
return
|
|
}
|
|
|
|
// error processing ...
|
|
// 401-1 response
|
|
token, ret := globalSession.IsCarriedToken(r)
|
|
if ret == false {
|
|
log.Debug("AccessToken is not carried")
|
|
services.ResponseUnauthorized401AccessTokenNotCarried(w)
|
|
return
|
|
}
|
|
|
|
if !globalSession.ShakeSession(token) {
|
|
// 401-2 response
|
|
log.Debug("AccessToken fails or does not exist")
|
|
services.ResponseUnauthorized401AccessTokenNotExist(w)
|
|
return
|
|
}
|
|
|
|
// 200 response
|
|
services.ResponseStatusOK200Null(w)
|
|
return
|
|
}
|
|
|
|
var (
|
|
MAX_RMUID_NUM = config.GetRmUIDMaxNumFromConfig()
|
|
MAX_ALARMID_NUM = config.GetAlarmIDMaxNumFromConfig()
|
|
MAX_PMUID_NUM = config.GetPmIDMaxNumFromConfig()
|
|
MAX_SUBID_NUM = config.GetSubIDMaxNumFromConfig()
|
|
MAX_URI_LEN = config.GetUriMaxLenFromConfig()
|
|
RMUID_REGEXP = config.GetRmUIDRegexpFromConfig()
|
|
)
|
|
|
|
func CheckParameterName(r *http.Request) []string {
|
|
var errorParams []string
|
|
vars := r.URL.Query()
|
|
for k, v := range vars {
|
|
log.Debug("vars:", k, v)
|
|
if k != "rmUIDs" && k != "fields" {
|
|
errorParams = append(errorParams, k)
|
|
}
|
|
}
|
|
|
|
return errorParams
|
|
}
|
|
|
|
func GetRmUIDArr(r *http.Request) []string {
|
|
vars := r.URL.Query()
|
|
rmUIDs, ok := vars["rmUIDs"]
|
|
if !ok {
|
|
log.Debug("rmUIDs is not exist")
|
|
return nil
|
|
}
|
|
|
|
var rmUIDValues []string
|
|
for _, r := range rmUIDs {
|
|
if r != "" {
|
|
rmUIDValues = global.MergeStringArr(rmUIDValues, strings.Split(r, `,`))
|
|
}
|
|
}
|
|
|
|
return rmUIDValues
|
|
}
|
|
|
|
func GetAttrNameArr(r *http.Request) []string {
|
|
vars := r.URL.Query()
|
|
fields, ok := vars["fields"]
|
|
if !ok {
|
|
log.Debug("attributeNames does not exist")
|
|
return nil
|
|
}
|
|
var attrNames []string
|
|
for _, a := range fields {
|
|
if a != "" {
|
|
attrNames = global.MergeStringArr(attrNames, strings.Split(a, `,`))
|
|
}
|
|
}
|
|
|
|
return attrNames
|
|
}
|
|
|
|
func CheckValidRmUID(rmUIDs []string) []string {
|
|
log.Debug("GetLocalRmUID processing... ")
|
|
|
|
var invalidRmUIDs []string
|
|
for _, r := range rmUIDs {
|
|
if !global.MatchRmUID(RMUID_REGEXP, r) {
|
|
invalidRmUIDs = append(invalidRmUIDs, r)
|
|
}
|
|
}
|
|
|
|
return invalidRmUIDs
|
|
}
|
|
|
|
func CheckLocalRmUID(rmUIDs []string) string {
|
|
log.Debug("GetLocalRmUID processing... ")
|
|
|
|
rmUID := config.GetRmUIDFromConfig()
|
|
for _, r := range rmUIDs {
|
|
if r == rmUID {
|
|
return rmUID
|
|
}
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
func GetNRMByUri(w http.ResponseWriter, r *http.Request) {
|
|
log.Debug("GetNRMByUri processing... ")
|
|
|
|
// response 414-4 uri too long ? (optional)
|
|
// todo ... ?
|
|
if bytes.Count([]byte(r.RequestURI), nil) > MAX_URI_LEN {
|
|
log.Debug("Request Uri too long:", bytes.Count([]byte(r.RequestURI), nil))
|
|
services.ResponseRequestURITooLong414UriTooLong(w)
|
|
return
|
|
}
|
|
|
|
// check media type(content type) only support "application/json"
|
|
// response 415-1
|
|
if !IsVallidContentType(r) {
|
|
log.Debug("Invalid Content-Type")
|
|
services.ResponseUnsupportedMediaType415(w)
|
|
return
|
|
}
|
|
|
|
// error processing ...
|
|
// 401-1 response
|
|
token, ret := globalSession.IsCarriedToken(r)
|
|
if ret == false {
|
|
log.Debug("AccessToken is not carried")
|
|
services.ResponseUnauthorized401AccessTokenNotCarried(w)
|
|
return
|
|
}
|
|
|
|
// 401-2 response
|
|
if globalSession.IsValidToken(token) == false {
|
|
log.Debug("AccessToken fails or does not exist")
|
|
services.ResponseUnauthorized401AccessTokenNotExist(w)
|
|
return
|
|
}
|
|
// response 403 Forbidden, permissions deny
|
|
// todo...
|
|
plist := globalSession.GetPermissionFromSession(token)
|
|
log.Debug("permission list:", plist)
|
|
if len(plist) == 0 || plist[0] == false {
|
|
log.Debug("User permission deny")
|
|
services.ResponseForbidden403NotPermission(w)
|
|
return
|
|
}
|
|
|
|
vars := mux.Vars(r)
|
|
qeuryUri := vars["apiCategory"] + "/" + vars["elementTypeValue"] + "/" + vars["objectTypeValue"]
|
|
log.Debug("Get by Uri: ", qeuryUri)
|
|
|
|
apiVer := vars["apiVersion"]
|
|
if apiVer != "v1" {
|
|
log.Debug("Uri is invalid")
|
|
services.ResponseNotFound404UriNotExist(w, r)
|
|
return
|
|
}
|
|
|
|
// response 406-1
|
|
rmUIDValues := GetRmUIDArr(r)
|
|
if rmUIDValues == nil {
|
|
log.Debug("missing parameter: rmUIDs")
|
|
services.ResponseNotAcceptable406MissingParam(w)
|
|
return
|
|
}
|
|
|
|
// response 406-2
|
|
errorParams := CheckParameterName(r)
|
|
if errorParams != nil {
|
|
log.Debug("parameter name error: ", errorParams)
|
|
services.ResponseNotAcceptable406ParamError(w, errorParams)
|
|
return
|
|
}
|
|
|
|
// response 400-5
|
|
if len(rmUIDValues) == 0 {
|
|
log.Debug("rmUIDs is wrong or NULL")
|
|
services.ResponseBadRequest400WrongParamValue(w)
|
|
return
|
|
}
|
|
|
|
// response 414-1
|
|
if len(rmUIDValues) > MAX_RMUID_NUM {
|
|
log.Debug("rmUID greater than", MAX_RMUID_NUM)
|
|
services.ResponseRequestURITooLong414NRMNumExceed(w, MAX_RMUID_NUM)
|
|
return
|
|
}
|
|
|
|
// response 400-1
|
|
// check rmUID is valid
|
|
// todo ...
|
|
invalidRmUIDs := CheckValidRmUID(rmUIDValues)
|
|
if len(invalidRmUIDs) != 0 {
|
|
log.Debug("rmUID is invalid")
|
|
services.ResponseBadRequest400RmUIDsIsInvalid(w, invalidRmUIDs)
|
|
return
|
|
}
|
|
|
|
// response 404-2
|
|
rmUID := CheckLocalRmUID(rmUIDValues)
|
|
if rmUID == "" {
|
|
log.Debug("rmUID does not exist")
|
|
services.ResponseNotFound404NRMNotExist(w, rmUIDValues)
|
|
return
|
|
}
|
|
|
|
// response 404-1, uri is not exist in map
|
|
attrNames := GetAttrNameArr(r)
|
|
var Oids []string
|
|
Oids = *config.GetOidByFileds(qeuryUri, attrNames, &Oids)
|
|
if len(Oids) == 0 {
|
|
log.Debug("Nothing of config map")
|
|
services.ResponseNotFound404UriNotExist(w, r)
|
|
return
|
|
}
|
|
|
|
// response 404-1, uri is not exist in map
|
|
var nameOids []config.NameOid
|
|
nameOids = *config.GetDataOidByFields(qeuryUri, attrNames, &nameOids)
|
|
if len(nameOids) == 0 {
|
|
log.Debug("Nothing of config map")
|
|
services.ResponseNotFound404UriNotExist(w, r)
|
|
return
|
|
}
|
|
|
|
result, err2 := g.Default.Get(Oids) // Get() accepts up to g.MAX_OIDS
|
|
if err2 != nil {
|
|
log.Fatalf("Get() err: %v", err2)
|
|
|
|
}
|
|
|
|
// var nameValues []config.NameValue
|
|
var nameValue config.NameValue
|
|
|
|
nameValues := make(map[string]interface{})
|
|
nameValues["rmUID"] = rmUID
|
|
for i, variable := range result.Variables {
|
|
nameValue.Name = nameOids[i].Name
|
|
log.Debugf("%d: oid: %s name: %s\n", i, variable.Name, nameValue.Name)
|
|
// if nameOids[i].Oid == variable.Name && global.IsContain(attributeNames, nameValue.Name) {
|
|
if nameOids[i].Oid == variable.Name {
|
|
// the Value of each variable returned by Get() implements
|
|
// interface{}. You could do a type switch...
|
|
switch variable.Type {
|
|
case g.OctetString:
|
|
bytes := variable.Value.([]byte)
|
|
log.Debugf("string: %s\n", string(bytes))
|
|
nameValue.Value = string(bytes)
|
|
nameValues[nameValue.Name] = nameValue.Value
|
|
case g.Integer:
|
|
value := variable.Value.(int)
|
|
log.Debugf("integer: %d\n", value)
|
|
nameValue.Value = strconv.Itoa(value)
|
|
nameValues[nameValue.Name] = nameValue.Value
|
|
case g.IPAddress:
|
|
value := variable.Value.(string)
|
|
log.Debugf("IPAddress: %s\n", variable.Value)
|
|
nameValue.Value = value
|
|
nameValues[nameValue.Name] = nameValue.Value
|
|
default:
|
|
// ... or often you're just interested in numeric values.
|
|
// ToBigInt() will return the Value as a BigInt, for plugging
|
|
// into your calculations.
|
|
log.Debugf("number: %d\n", g.ToBigInt(variable.Value))
|
|
}
|
|
}
|
|
}
|
|
|
|
getResponse := services.DataResponse{nameValues}
|
|
services.ResponseWithJson(w, http.StatusOK, getResponse)
|
|
}
|
|
|
|
func RestfulPut(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
queryNo := vars["no"]
|
|
var targetTodo stTodo
|
|
for _, Todo := range TodoList {
|
|
if Todo.No == queryNo {
|
|
targetTodo = Todo
|
|
}
|
|
}
|
|
response := ApiResponse{"200", targetTodo}
|
|
services.ResponseWithJson(w, http.StatusOK, response)
|
|
}
|
|
|
|
func RestfulHead(w http.ResponseWriter, r *http.Request) {
|
|
var targetTodo stTodo
|
|
|
|
response := ApiResponse{"200", targetTodo}
|
|
services.ResponseWithJson(w, http.StatusOK, response)
|
|
|
|
}
|
|
|
|
func RemoveElement(TodoList []stTodo, No string) stTodo {
|
|
// var targetTodo stTodo
|
|
j := 0
|
|
if len(TodoList) == 0 {
|
|
return TodoList[j]
|
|
}
|
|
|
|
for i := 0; i < len(TodoList); i++ {
|
|
if TodoList[i].No != No {
|
|
if i != j {
|
|
TodoList[i], TodoList[j] = TodoList[j], TodoList[i]
|
|
}
|
|
j++
|
|
}
|
|
}
|
|
log.Debug(TodoList[j].No, TodoList[j].Item)
|
|
return TodoList[j]
|
|
}
|
|
|
|
func RestfulDelete(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
queryNo := vars["no"] //获取No
|
|
|
|
log.Debug("RestfulDelete processing... ")
|
|
|
|
targetTodo := RemoveElement(TodoList, queryNo)
|
|
response := ApiResponse{"200", targetTodo}
|
|
services.ResponseWithJson(w, http.StatusOK, response)
|
|
}
|
|
|
|
func RestfulOptions(w http.ResponseWriter, r *http.Request) {
|
|
var targetTodo stTodo
|
|
|
|
response := ApiResponse{"200", targetTodo}
|
|
services.ResponseWithJson(w, http.StatusOK, response)
|
|
|
|
}
|
|
|
|
func RestfulTrace(w http.ResponseWriter, r *http.Request) {
|
|
var targetTodo stTodo
|
|
|
|
response := ApiResponse{"200", targetTodo}
|
|
services.ResponseWithJson(w, http.StatusOK, response)
|
|
|
|
}
|
|
|
|
func RestfulPatch(w http.ResponseWriter, r *http.Request) {
|
|
var targetTodo stTodo
|
|
|
|
response := ApiResponse{"200", targetTodo}
|
|
services.ResponseWithJson(w, http.StatusOK, response)
|
|
|
|
}
|