Browse Source

started security.go

afeiszli 3 years ago
parent
commit
6455f41c1b
3 changed files with 147 additions and 1 deletions
  1. 4 0
      controllers/networkHttpController.go
  2. 143 0
      controllers/security.go
  3. 0 1
      logger/logger.go

+ 4 - 0
controllers/networkHttpController.go

@@ -44,6 +44,9 @@ func securityCheck(reqAdmin bool, next http.Handler) http.HandlerFunc {
 		var errorResponse = models.ErrorResponse{
 			Code: http.StatusUnauthorized, Message: "W1R3: It's not you it's me.",
 		}
+		if strings.Contains(r.RequestURI, "/dns") && r.Method == "GET" {
+
+		}
 
 		var params = mux.Vars(r)
 		bearerToken := r.Header.Get("Authorization")
@@ -68,6 +71,7 @@ func securityCheck(reqAdmin bool, next http.Handler) http.HandlerFunc {
 	}
 }
 
+// SecurityCheck - checks token stuff
 func SecurityCheck(reqAdmin bool, netname string, token string) (error, []string, string) {
 
 	var hasBearer = true

+ 143 - 0
controllers/security.go

@@ -0,0 +1,143 @@
+package controller
+
+import (
+	"encoding/json"
+	"errors"
+	"net/http"
+	"strings"
+
+	"github.com/gorilla/mux"
+	"github.com/gravitl/netmaker/database"
+	"github.com/gravitl/netmaker/functions"
+	"github.com/gravitl/netmaker/logic"
+	"github.com/gravitl/netmaker/models"
+	"github.com/gravitl/netmaker/servercfg"
+)
+
+//Security check DNS is middleware for every DNS function and just checks to make sure that its the master or dns token calling
+//Only admin should have access to all these network-level actions
+//DNS token should have access to only read functions
+func securityCheck(reqAdmin bool, allowDNSToken bool, next http.Handler) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var errorResponse = models.ErrorResponse{
+			Code: http.StatusUnauthorized, Message: "W1R3: It's not you it's me.",
+		}
+
+		var params = mux.Vars(r)
+		bearerToken := r.Header.Get("Authorization")
+		if allowDNSToken && authenticateDNSToken(bearerToken) {
+			r.Header.Set("user", "nameserver")
+			networks, _ := json.Marshal([]string{ALL_NETWORK_ACCESS})
+			r.Header.Set("networks", string(networks))
+			next.ServeHTTP(w, r)
+		} else {
+			err, networks, username := SecurityCheck(reqAdmin, params["networkname"], bearerToken)
+			if err != nil {
+				if strings.Contains(err.Error(), "does not exist") {
+					errorResponse.Code = http.StatusNotFound
+				}
+				errorResponse.Message = err.Error()
+				returnErrorResponse(w, r, errorResponse)
+				return
+			}
+			networksJson, err := json.Marshal(&networks)
+			if err != nil {
+				errorResponse.Message = err.Error()
+				returnErrorResponse(w, r, errorResponse)
+				return
+			}
+			r.Header.Set("user", username)
+			r.Header.Set("networks", string(networksJson))
+			next.ServeHTTP(w, r)
+		}
+	}
+}
+
+func securityCheck(reqAdmin bool, next http.Handler) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var errorResponse = models.ErrorResponse{
+			Code: http.StatusUnauthorized, Message: "W1R3: It's not you it's me.",
+		}
+
+		var params = mux.Vars(r)
+		bearerToken := r.Header.Get("Authorization")
+		err, networks, username := SecurityCheck(reqAdmin, params["networkname"], bearerToken)
+		if err != nil {
+			if strings.Contains(err.Error(), "does not exist") {
+				errorResponse.Code = http.StatusNotFound
+			}
+			errorResponse.Message = err.Error()
+			returnErrorResponse(w, r, errorResponse)
+			return
+		}
+		networksJson, err := json.Marshal(&networks)
+		if err != nil {
+			errorResponse.Message = err.Error()
+			returnErrorResponse(w, r, errorResponse)
+			return
+		}
+		r.Header.Set("user", username)
+		r.Header.Set("networks", string(networksJson))
+		next.ServeHTTP(w, r)
+	}
+}
+
+// SecurityCheck - checks token stuff
+func SecurityCheck(reqAdmin bool, netname string, token string) (error, []string, string) {
+
+	var hasBearer = true
+	var tokenSplit = strings.Split(token, " ")
+	var authToken = ""
+
+	if len(tokenSplit) < 2 {
+		hasBearer = false
+	} else {
+		authToken = tokenSplit[1]
+	}
+	userNetworks := []string{}
+	//all endpoints here require master so not as complicated
+	isMasterAuthenticated := authenticateMaster(authToken)
+	username := ""
+	if !hasBearer || !isMasterAuthenticated {
+		userName, networks, isadmin, err := logic.VerifyUserToken(authToken)
+		username = userName
+		if err != nil {
+			return errors.New("error verifying user token"), nil, username
+		}
+		if !isadmin && reqAdmin {
+			return errors.New("you are unauthorized to access this endpoint"), nil, username
+		}
+		userNetworks = networks
+		if isadmin {
+			userNetworks = []string{ALL_NETWORK_ACCESS}
+		} else {
+			networkexists, err := functions.NetworkExists(netname)
+			if err != nil && !database.IsEmptyRecord(err) {
+				return err, nil, ""
+			}
+			if netname != "" && !networkexists {
+				return errors.New("this network does not exist"), nil, ""
+			}
+		}
+	} else if isMasterAuthenticated {
+		userNetworks = []string{ALL_NETWORK_ACCESS}
+	}
+	if len(userNetworks) == 0 {
+		userNetworks = append(userNetworks, NO_NETWORKS_PRESENT)
+	}
+	return nil, userNetworks, username
+}
+
+//Consider a more secure way of setting master key
+func authenticateMaster(tokenString string) bool {
+	return tokenString == servercfg.GetMasterKey()
+}
+
+//Consider a more secure way of setting master key
+func authenticateDNSToken(tokenString string) bool {
+	tokens := strings.Split(tokenString, " ")
+	if len(tokens) < 2 {
+		return false
+	}
+	return tokens[1] == servercfg.GetDNSKey()
+}

+ 0 - 1
logger/logger.go

@@ -94,7 +94,6 @@ func Retrieve(filePath string) string {
 	if err != nil {
 		panic(err)
 	}
-	fmt.Println(string(contents))
 	return string(contents)
 }