package api import ( "docker4ssh/database" "docker4ssh/ssh" "encoding/json" "go.uber.org/zap" "golang.org/x/crypto/bcrypt" "net/http" ) type authGetResponse struct { User string `json:"user"` HasPassword bool `json:"has_password"` } func AuthGet(w http.ResponseWriter, r *http.Request, user *ssh.User) (interface{}, int) { auth, ok := database.GetDatabase().GetAuthByContainer(user.Container.FullContainerID) if ok { return authGetResponse{ User: *auth.User, HasPassword: auth.Password != nil, }, http.StatusOK } else { return APIError{Message: "no auth is set"}, http.StatusNotFound } } type authPostRequest struct { User *string `json:"user"` Password *string `json:"password"` } func AuthPost(w http.ResponseWriter, r *http.Request, user *ssh.User) (interface{}, int) { var request authPostRequest json.NewDecoder(r.Body).Decode(&request) defer r.Body.Close() db := database.GetDatabase() auth, _ := db.GetAuthByContainer(user.Container.FullContainerID) if request.User != nil { if *request.User == "" { return APIError{Message: "new username cannot be empty"}, http.StatusNotAcceptable } if err := db.SetAuth(user.Container.FullContainerID, database.Auth{ User: request.User, }); err != nil { zap.S().Errorf("Error while updating user for user %s: %v", user.ID, err) return APIError{Message: "failed to process user"}, http.StatusInternalServerError } zap.S().Infof("Updated password for %s", user.Container.ContainerID) } if request.Password != nil && *request.Password == "" { if err := db.DeleteAuth(user.Container.FullContainerID); err != nil { zap.S().Errorf("Error while deleting auth for user %s: %v", user.ID, err) return APIError{Message: "failed to delete auth"}, http.StatusInternalServerError } zap.S().Infof("Deleted authenticiation for %s", user.Container.ContainerID) } else if request.Password != nil { pwd, err := bcrypt.GenerateFromPassword([]byte(*request.Password), bcrypt.DefaultCost) if err != nil { zap.S().Errorf("Error while updating password for user %s: %v", user.ID, err) return APIError{Message: "failed to process password"}, http.StatusInternalServerError } var username string if auth.User == nil { username = user.Container.FullContainerID } else { username = *auth.User } if err = db.SetAuth(user.Container.FullContainerID, database.NewUnsafeAuth(username, pwd)); err != nil { return APIError{Message: "failed to update authentication"}, http.StatusInternalServerError } zap.S().Infof("Updated password for %s", user.Container.ContainerID) } return nil, http.StatusOK }