| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 | package controllerimport (	"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")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")		if strings.Contains(r.RequestURI, "/dns") && strings.ToUpper(r.Method) == "GET" && authenticateDNSToken(bearerToken) {			// do dns stuff			r.Header.Set("user", "nameserver")			networks, _ := json.Marshal([]string{ALL_NETWORK_ACCESS})			r.Header.Set("networks", string(networks))			next.ServeHTTP(w, r)			return		}		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 stufffunc 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 keyfunc authenticateMaster(tokenString string) bool {	return tokenString == servercfg.GetMasterKey()}//Consider a more secure way of setting master keyfunc authenticateDNSToken(tokenString string) bool {	tokens := strings.Split(tokenString, " ")	if len(tokens) < 2 {		return false	}	return tokens[1] == servercfg.GetDNSKey()}func continueIfUserMatch(next http.Handler) http.HandlerFunc {	return func(w http.ResponseWriter, r *http.Request) {		var errorResponse = models.ErrorResponse{			Code: http.StatusUnauthorized, Message: "W1R3: This doesn't look like you.",		}		var params = mux.Vars(r)		var requestedUser = params["username"]		if requestedUser != r.Header.Get("user") {			returnErrorResponse(w, r, errorResponse)			return		}		next.ServeHTTP(w, r)	}}
 |