package editor /* Notes for Auth The Authorization specifies the authentication mechanism (in this case Basic) followed by the username and password. Although, the string aHR0cHdhdGNoOmY= may look encrypted it is simply a base64 encoded version of :. Would be readily available to anyone who could intercept the HTTP request. */ import ( "os" "strconv" "strings" "github.com/kataras/iris" "github.com/kataras/iris/config" "github.com/kataras/iris/logger" "github.com/kataras/iris/npm" "github.com/kataras/iris/utils" ) const ( // Name the name of the Plugin, which is "EditorPlugin" Name = "EditorPlugin" ) type ( // Plugin is an Editor Plugin the struct which implements the iris.IPlugin // it holds a logger from the iris' station // username,password for basic auth // directory which the client side code is // keyfile,certfile for TLS listening // and a host which is listening for Plugin struct { config *config.Editor logger *logger.Logger enabled bool // default true keyfile string certfile string // after alm started process *os.Process } ) // New creates and returns an Editor Plugin instance func New(cfg ...config.Editor) *Plugin { c := config.DefaultEditor().Merge(cfg) e := &Plugin{enabled: true, config: &c} return e } // User set a user, accepts two parameters: username (string), string (string) func (e *Plugin) User(username string, password string) *Plugin { e.config.Username = username e.config.Password = password return e } // Dir sets the directory which the client side source code alive func (e *Plugin) Dir(workingDir string) *Plugin { e.config.WorkingDir = workingDir return e } // Port sets the port (int) for the editor plugin's standalone server func (e *Plugin) Port(port int) *Plugin { e.config.Port = port return e } // // SetEnable if true enables the editor plugin, otherwise disables it func (e *Plugin) SetEnable(enable bool) { e.enabled = enable } // GetName returns the name of the Plugin func (e *Plugin) GetName() string { return Name } // GetDescription EditorPlugin is a bridge between Iris and the alm-tools, the browser-based IDE for client-side sources. func (e *Plugin) GetDescription() string { return Name + " is a bridge between Iris and the alm-tools, the browser-based IDE for client-side sources. \n" } // PreListen runs before the server's listens, saves the keyfile,certfile and the host from the Iris station to listen for func (e *Plugin) PreListen(s *iris.Iris) { e.logger = s.Logger() e.keyfile = s.Server().Config.KeyFile e.certfile = s.Server().Config.CertFile if e.config.Host == "" { h := s.Server().Config.ListeningAddr if idx := strings.Index(h, ":"); idx >= 0 { h = h[0:idx] } if h == "" { h = "127.0.0.1" } e.config.Host = h } e.start() } // PreClose kills the editor's server when Iris is closed func (e *Plugin) PreClose(s *iris.Iris) { if e.process != nil { err := e.process.Kill() if err != nil { e.logger.Printf("\nError while trying to terminate the (Editor)Plugin, please kill this process by yourself, process id: %d", e.process.Pid) } } } // start starts the job func (e *Plugin) start() { if e.config.Username == "" || e.config.Password == "" { e.logger.Println("Error before running alm-tools. You have to set username & password for security reasons, otherwise this plugin won't run.") return } if !npm.Exists("alm/bin/alm") { e.logger.Println("Installing alm-tools, please wait...") res := npm.Install("alm") if res.Error != nil { e.logger.Print(res.Error.Error()) return } e.logger.Print(res.Message) } cmd := utils.CommandBuilder("node", npm.Abs("alm/src/server.js")) cmd.AppendArguments("-a", e.config.Username+":"+e.config.Password, "-h", e.config.Host, "-t", strconv.Itoa(e.config.Port), "-d", e.config.WorkingDir[0:len(e.config.WorkingDir)-1]) // for auto-start in the browser: cmd.AppendArguments("-o") if e.keyfile != "" && e.certfile != "" { cmd.AppendArguments("--httpskey", e.keyfile, "--httpscert", e.certfile) } //For debug only: //cmd.Stdout = os.Stdout //cmd.Stderr = os.Stderr //os.Stdin = os.Stdin err := cmd.Start() if err != nil { e.logger.Println("Error while running alm-tools. Trace: " + err.Error()) return } //we lose the internal error handling but ok... e.logger.Printf("Editor is running at %s:%d | %s", e.config.Host, e.config.Port, e.config.WorkingDir) }