mirror of
https://github.com/gravitl/netmaker.git
synced 2025-09-09 06:35:23 +08:00
Merge pull request #1959 from gravitl/refactor_authenticate
Use host id in claims instead of node id
This commit is contained in:
commit
cc483014e9
2 changed files with 96 additions and 1 deletions
|
@ -12,6 +12,7 @@ import (
|
||||||
"github.com/gravitl/netmaker/logic"
|
"github.com/gravitl/netmaker/logic"
|
||||||
"github.com/gravitl/netmaker/models"
|
"github.com/gravitl/netmaker/models"
|
||||||
"github.com/gravitl/netmaker/mq"
|
"github.com/gravitl/netmaker/mq"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
type hostNetworksUpdatePayload struct {
|
type hostNetworksUpdatePayload struct {
|
||||||
|
@ -26,6 +27,7 @@ func hostHandlers(r *mux.Router) {
|
||||||
r.HandleFunc("/api/hosts/{hostid}/networks/{network}", logic.SecurityCheck(true, http.HandlerFunc(deleteHostFromNetwork))).Methods(http.MethodDelete)
|
r.HandleFunc("/api/hosts/{hostid}/networks/{network}", logic.SecurityCheck(true, http.HandlerFunc(deleteHostFromNetwork))).Methods(http.MethodDelete)
|
||||||
r.HandleFunc("/api/hosts/{hostid}/relay", logic.SecurityCheck(false, http.HandlerFunc(createHostRelay))).Methods(http.MethodPost)
|
r.HandleFunc("/api/hosts/{hostid}/relay", logic.SecurityCheck(false, http.HandlerFunc(createHostRelay))).Methods(http.MethodPost)
|
||||||
r.HandleFunc("/api/hosts/{hostid}/relay", logic.SecurityCheck(false, http.HandlerFunc(deleteHostRelay))).Methods(http.MethodDelete)
|
r.HandleFunc("/api/hosts/{hostid}/relay", logic.SecurityCheck(false, http.HandlerFunc(deleteHostRelay))).Methods(http.MethodDelete)
|
||||||
|
r.HandleFunc("/api/hosts/adm/authenticate", authenticateHost).Methods(http.MethodPost)
|
||||||
}
|
}
|
||||||
|
|
||||||
// swagger:route GET /api/hosts hosts getHosts
|
// swagger:route GET /api/hosts hosts getHosts
|
||||||
|
@ -285,3 +287,96 @@ func deleteHostFromNetwork(w http.ResponseWriter, r *http.Request) {
|
||||||
logger.Log(2, r.Header.Get("user"), fmt.Sprintf("removed host %s from network %s", currHost.Name, network))
|
logger.Log(2, r.Header.Get("user"), fmt.Sprintf("removed host %s from network %s", currHost.Name, network))
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// swagger:route POST /api/hosts/adm/authenticate hosts authenticateHost
|
||||||
|
//
|
||||||
|
// Host based authentication for making further API calls.
|
||||||
|
//
|
||||||
|
// Schemes: https
|
||||||
|
//
|
||||||
|
// Security:
|
||||||
|
// oauth
|
||||||
|
//
|
||||||
|
// Responses:
|
||||||
|
// 200: successResponse
|
||||||
|
func authenticateHost(response http.ResponseWriter, request *http.Request) {
|
||||||
|
var authRequest models.AuthParams
|
||||||
|
var errorResponse = models.ErrorResponse{
|
||||||
|
Code: http.StatusInternalServerError, Message: "W1R3: It's not you it's me.",
|
||||||
|
}
|
||||||
|
|
||||||
|
decoder := json.NewDecoder(request.Body)
|
||||||
|
decoderErr := decoder.Decode(&authRequest)
|
||||||
|
defer request.Body.Close()
|
||||||
|
|
||||||
|
if decoderErr != nil {
|
||||||
|
errorResponse.Code = http.StatusBadRequest
|
||||||
|
errorResponse.Message = decoderErr.Error()
|
||||||
|
logger.Log(0, request.Header.Get("user"), "error decoding request body: ",
|
||||||
|
decoderErr.Error())
|
||||||
|
logic.ReturnErrorResponse(response, request, errorResponse)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
errorResponse.Code = http.StatusBadRequest
|
||||||
|
if authRequest.ID == "" {
|
||||||
|
errorResponse.Message = "W1R3: ID can't be empty"
|
||||||
|
logger.Log(0, request.Header.Get("user"), errorResponse.Message)
|
||||||
|
logic.ReturnErrorResponse(response, request, errorResponse)
|
||||||
|
return
|
||||||
|
} else if authRequest.Password == "" {
|
||||||
|
errorResponse.Message = "W1R3: Password can't be empty"
|
||||||
|
logger.Log(0, request.Header.Get("user"), errorResponse.Message)
|
||||||
|
logic.ReturnErrorResponse(response, request, errorResponse)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
host, err := logic.GetHost(authRequest.ID)
|
||||||
|
if err != nil {
|
||||||
|
errorResponse.Code = http.StatusBadRequest
|
||||||
|
errorResponse.Message = err.Error()
|
||||||
|
logger.Log(0, request.Header.Get("user"),
|
||||||
|
"error retrieving host: ", err.Error())
|
||||||
|
logic.ReturnErrorResponse(response, request, errorResponse)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = bcrypt.CompareHashAndPassword([]byte(host.HostPass), []byte(authRequest.Password))
|
||||||
|
if err != nil {
|
||||||
|
errorResponse.Code = http.StatusUnauthorized
|
||||||
|
errorResponse.Message = "unauthorized"
|
||||||
|
logger.Log(0, request.Header.Get("user"),
|
||||||
|
"error validating user password: ", err.Error())
|
||||||
|
logic.ReturnErrorResponse(response, request, errorResponse)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenString, err := logic.CreateJWT(authRequest.ID, authRequest.MacAddress, "")
|
||||||
|
if tokenString == "" {
|
||||||
|
errorResponse.Code = http.StatusUnauthorized
|
||||||
|
errorResponse.Message = "unauthorized"
|
||||||
|
logger.Log(0, request.Header.Get("user"),
|
||||||
|
fmt.Sprintf("%s: %v", errorResponse.Message, err))
|
||||||
|
logic.ReturnErrorResponse(response, request, errorResponse)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var successResponse = models.SuccessResponse{
|
||||||
|
Code: http.StatusOK,
|
||||||
|
Message: "W1R3: Host " + authRequest.ID + " Authorized",
|
||||||
|
Response: models.SuccessfulLoginResponse{
|
||||||
|
AuthToken: tokenString,
|
||||||
|
ID: authRequest.ID,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
successJSONResponse, jsonError := json.Marshal(successResponse)
|
||||||
|
|
||||||
|
if jsonError != nil {
|
||||||
|
errorResponse.Code = http.StatusBadRequest
|
||||||
|
errorResponse.Message = err.Error()
|
||||||
|
logger.Log(0, request.Header.Get("user"),
|
||||||
|
"error marshalling resp: ", err.Error())
|
||||||
|
logic.ReturnErrorResponse(response, request, errorResponse)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.WriteHeader(http.StatusOK)
|
||||||
|
response.Header().Set("Content-Type", "application/json")
|
||||||
|
response.Write(successJSONResponse)
|
||||||
|
}
|
||||||
|
|
|
@ -130,7 +130,7 @@ func VerifyUserToken(tokenString string) (username string, networks []string, is
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyToken - [nodes] Only
|
// VerifyToken - [nodes] Only
|
||||||
func VerifyToken(tokenString string) (nodeID string, mac string, network string, err error) {
|
func VerifyToken(tokenString string) (hostID string, mac string, network string, err error) {
|
||||||
claims := &models.Claims{}
|
claims := &models.Claims{}
|
||||||
|
|
||||||
// this may be a stupid way of serving up a master key
|
// this may be a stupid way of serving up a master key
|
||||||
|
|
Loading…
Add table
Reference in a new issue