| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365 | package ee_controllersimport (	"encoding/json"	"errors"	"net/http"	"github.com/gorilla/mux"	"github.com/gravitl/netmaker/database"	"github.com/gravitl/netmaker/logger"	"github.com/gravitl/netmaker/logic"	"github.com/gravitl/netmaker/logic/pro"	"github.com/gravitl/netmaker/models"	"github.com/gravitl/netmaker/models/promodels")func NetworkUsersHandlers(r *mux.Router) {	r.HandleFunc("/api/networkusers", logic.SecurityCheck(true, http.HandlerFunc(getAllNetworkUsers))).Methods(http.MethodGet)	r.HandleFunc("/api/networkusers/{network}", logic.SecurityCheck(true, http.HandlerFunc(getNetworkUsers))).Methods(http.MethodGet)	r.HandleFunc("/api/networkusers/{network}/{networkuser}", logic.SecurityCheck(true, http.HandlerFunc(getNetworkUser))).Methods(http.MethodGet)	r.HandleFunc("/api/networkusers/{network}", logic.SecurityCheck(true, http.HandlerFunc(createNetworkUser))).Methods(http.MethodPost)	r.HandleFunc("/api/networkusers/{network}", logic.SecurityCheck(true, http.HandlerFunc(updateNetworkUser))).Methods(http.MethodPut)	r.HandleFunc("/api/networkusers/data/{networkuser}/me", logic.NetUserSecurityCheck(false, false, http.HandlerFunc(getNetworkUserData))).Methods(http.MethodGet)	r.HandleFunc("/api/networkusers/{network}/{networkuser}", logic.SecurityCheck(true, http.HandlerFunc(deleteNetworkUser))).Methods(http.MethodDelete)}// == RETURN TYPES ==// NetworkName - represents a network name/IDtype NetworkName string// NetworkUserDataMap - map of all data per network for a usertype NetworkUserDataMap map[NetworkName]NetworkUserData// NetworkUserData - data struct for network userstype NetworkUserData struct {	Nodes    []models.Node         `json:"nodes" bson:"nodes" yaml:"nodes"`	Clients  []models.ExtClient    `json:"clients" bson:"clients" yaml:"clients"`	Vpn      []models.Node         `json:"vpns" bson:"vpns" yaml:"vpns"`	Networks []models.Network      `json:"networks" bson:"networks" yaml:"networks"`	User     promodels.NetworkUser `json:"user" bson:"user" yaml:"user"`}// == END RETURN TYPES ==// returns a map of a network user's data across all networksfunc getNetworkUserData(w http.ResponseWriter, r *http.Request) {	w.Header().Set("Content-Type", "application/json")	var params = mux.Vars(r)	networkUserName := params["networkuser"]	logger.Log(1, r.Header.Get("user"), "requested fetching network user data for user", networkUserName)	networks, err := logic.GetNetworks()	if err != nil {		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))		return	}	if networkUserName == "" {		logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("netuserToGet"), "badrequest"))		return	}	u, err := logic.GetUser(networkUserName)	if err != nil {		logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("could not find user"), "badrequest"))		return	}	// initialize the return data of network users	returnData := make(NetworkUserDataMap)	// go through each network and get that user's data	// if user has no access, give no data	// if user is a net admin, give all nodes	// if user has node access, give user's nodes if any	// if user has client access, git user's clients if any	for i := range networks {		netID := networks[i].NetID		newData := NetworkUserData{			Nodes:    []models.Node{},			Clients:  []models.ExtClient{},			Vpn:      []models.Node{},			Networks: []models.Network{},		}		netUser, err := pro.GetNetworkUser(netID, promodels.NetworkUserID(networkUserName))		// check if user has access		if err == nil && netUser.AccessLevel != pro.NO_ACCESS {			newData.User = promodels.NetworkUser{				AccessLevel: netUser.AccessLevel,				ClientLimit: netUser.ClientLimit,				NodeLimit:   netUser.NodeLimit,				Nodes:       netUser.Nodes,				Clients:     netUser.Clients,			}			newData.User.SetDefaults()			// check network level permissions			if doesNetworkAllow := pro.IsUserAllowed(&networks[i], networkUserName, u.Groups); doesNetworkAllow || netUser.AccessLevel == pro.NET_ADMIN {				netNodes, err := logic.GetNetworkNodes(netID)				if err != nil {					if database.IsEmptyRecord(err) && netUser.AccessLevel == pro.NET_ADMIN {						newData.Networks = append(newData.Networks, networks[i])					} else {						logger.Log(0, "failed to retrieve nodes on network", netID, "for user", string(netUser.ID))					}				} else {					if netUser.AccessLevel <= pro.NODE_ACCESS { // handle nodes						// if access level is NODE_ACCESS, filter nodes						if netUser.AccessLevel == pro.NODE_ACCESS {							for i := range netNodes {								if logic.StringSliceContains(netUser.Nodes, netNodes[i].ID.String()) {									newData.Nodes = append(newData.Nodes, netNodes[i])								}							}						} else { // net admin so, get all nodes and ext clients on network...							newData.Nodes = netNodes							for i := range netNodes {								if netNodes[i].IsIngressGateway {									newData.Vpn = append(newData.Vpn, netNodes[i])									if clients, err := logic.GetExtClientsByID(netNodes[i].ID.String(), netID); err == nil {										newData.Clients = append(newData.Clients, clients...)									}								}							}							newData.Networks = append(newData.Networks, networks[i])						}					}					if netUser.AccessLevel <= pro.CLIENT_ACCESS && netUser.AccessLevel != pro.NET_ADMIN {						for _, c := range netUser.Clients {							if client, err := logic.GetExtClient(c, netID); err == nil {								newData.Clients = append(newData.Clients, client)							}						}						for i := range netNodes {							if netNodes[i].IsIngressGateway {								newData.Vpn = append(newData.Vpn, netNodes[i])							}						}					}				}			}			returnData[NetworkName(netID)] = newData		}	}	w.WriteHeader(http.StatusOK)	json.NewEncoder(w).Encode(returnData)}// returns a map of all network users mapped to each networkfunc getAllNetworkUsers(w http.ResponseWriter, r *http.Request) {	w.Header().Set("Content-Type", "application/json")	logger.Log(1, r.Header.Get("user"), "requested fetching all network users")	type allNetworkUsers = map[string][]promodels.NetworkUser	networks, err := logic.GetNetworks()	if err != nil {		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))		return	}	var allNetUsers = make(allNetworkUsers, len(networks))	for i := range networks {		netusers, err := pro.GetNetworkUsers(networks[i].NetID)		if err != nil {			logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))			return		}		for _, v := range netusers {			allNetUsers[networks[i].NetID] = append(allNetUsers[networks[i].NetID], v)		}	}	w.WriteHeader(http.StatusOK)	json.NewEncoder(w).Encode(allNetUsers)}func getNetworkUsers(w http.ResponseWriter, r *http.Request) {	w.Header().Set("Content-Type", "application/json")	var params = mux.Vars(r)	netname := params["network"]	logger.Log(1, r.Header.Get("user"), "requested fetching network users for network", netname)	_, err := logic.GetNetwork(netname)	if err != nil {		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))		return	}	netusers, err := pro.GetNetworkUsers(netname)	if err != nil {		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))		return	}	w.WriteHeader(http.StatusOK)	json.NewEncoder(w).Encode(netusers)}func getNetworkUser(w http.ResponseWriter, r *http.Request) {	w.Header().Set("Content-Type", "application/json")	var params = mux.Vars(r)	netname := params["network"]	logger.Log(1, r.Header.Get("user"), "requested fetching network user", params["networkuser"], "on network", netname)	_, err := logic.GetNetwork(netname)	if err != nil {		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))		return	}	netuserToGet := params["networkuser"]	if netuserToGet == "" {		logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("netuserToGet"), "badrequest"))		return	}	netuser, err := pro.GetNetworkUser(netname, promodels.NetworkUserID(netuserToGet))	if err != nil {		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))		return	}	w.WriteHeader(http.StatusOK)	json.NewEncoder(w).Encode(netuser)}func createNetworkUser(w http.ResponseWriter, r *http.Request) {	w.Header().Set("Content-Type", "application/json")	var params = mux.Vars(r)	netname := params["network"]	logger.Log(1, r.Header.Get("user"), "requested creating a network user on network", netname)	network, err := logic.GetNetwork(netname)	if err != nil {		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))		return	}	var networkuser promodels.NetworkUser	// we decode our body request params	err = json.NewDecoder(r.Body).Decode(&networkuser)	if err != nil {		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))		return	}	err = pro.CreateNetworkUser(&network, &networkuser)	if err != nil {		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))		return	}	w.WriteHeader(http.StatusOK)}func updateNetworkUser(w http.ResponseWriter, r *http.Request) {	w.Header().Set("Content-Type", "application/json")	var params = mux.Vars(r)	netname := params["network"]	logger.Log(1, r.Header.Get("user"), "requested updating a network user on network", netname)	network, err := logic.GetNetwork(netname)	if err != nil {		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))		return	}	var networkuser promodels.NetworkUser	// we decode our body request params	err = json.NewDecoder(r.Body).Decode(&networkuser)	if err != nil {		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))		return	}	if networkuser.ID == "" || !pro.DoesNetworkUserExist(netname, networkuser.ID) {		logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("invalid user "+string(networkuser.ID)), "badrequest"))		return	}	if networkuser.AccessLevel < pro.NET_ADMIN || networkuser.AccessLevel > pro.NO_ACCESS {		logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("invalid user access level provided"), "badrequest"))		return	}	if networkuser.ClientLimit < 0 || networkuser.NodeLimit < 0 {		logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("negative user limit provided"), "badrequest"))		return	}	u, err := logic.GetUser(string(networkuser.ID))	if err != nil {		logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("invalid user "+string(networkuser.ID)), "badrequest"))		return	}	if !pro.IsUserAllowed(&network, u.UserName, u.Groups) {		logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("user must be in allowed groups or users"), "badrequest"))		return	}	if networkuser.AccessLevel == pro.NET_ADMIN {		currentUser, err := logic.GetUser(string(networkuser.ID))		if err != nil {			logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("user model not found for "+string(networkuser.ID)), "badrequest"))			return		}		if !logic.StringSliceContains(currentUser.Networks, netname) {			// append network name to user model to conform to old model			if err = logic.UpdateUserNetworks(				append(currentUser.Networks, netname),				currentUser.Groups,				currentUser.IsAdmin,				&models.ReturnUser{					Groups:   currentUser.Groups,					IsAdmin:  currentUser.IsAdmin,					Networks: currentUser.Networks,					UserName: currentUser.UserName,				},			); err != nil {				logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("user model failed net admin update "+string(networkuser.ID)+" (are they an admin?"), "badrequest"))				return			}		}	}	err = pro.UpdateNetworkUser(netname, &networkuser)	if err != nil {		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))		return	}	w.WriteHeader(http.StatusOK)}func deleteNetworkUser(w http.ResponseWriter, r *http.Request) {	var params = mux.Vars(r)	netname := params["network"]	logger.Log(1, r.Header.Get("user"), "requested deleting network user", params["networkuser"], "on network", netname)	_, err := logic.GetNetwork(netname)	if err != nil {		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))		return	}	netuserToDelete := params["networkuser"]	if netuserToDelete == "" {		logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("no group name provided"), "badrequest"))		return	}	if err := pro.DeleteNetworkUser(netname, netuserToDelete); err != nil {		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))		return	}	w.WriteHeader(http.StatusOK)}
 |