2021-12-19 17:30:51 +01:00

81 lines
2.6 KiB
Go

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
}