func TestFileSummary(t *testing.T) {
	Convey("Test file-summary of remote file system", t, func() {
		testData, err := testing_utils.NewTestDataContainer("testdata/copy-files", 6)
		So(err, ShouldBeNil)

		copiedDetails, err := copyTestDataToTempDir(testData, "")
		So(err, ShouldBeNil)
		defer copiedDetails.Cleanup()

		sessionFileSystem, err := testingGetNewSessionFileSystem()
		So(err, ShouldBeNil)
		checksumSvc := checksums.New()

		remoteOrigDir := copiedDetails.CopiedToTempDir
		testData.ForeachRelativeFile(func(relPath string) {
			actualFileSummary, err := sessionFileSystem.FileSummary(filepath.Join(remoteOrigDir, relPath))
			So(err, ShouldBeNil)
			So(actualFileSummary, ShouldNotBeNil)

			fullRemoteFilePath := filepath.Join(copiedDetails.CopiedToTempDir, relPath)
			expectedSummary, err := getFileSummaryForFile(checksumSvc, fullRemoteFilePath)
			So(err, ShouldBeNil)

			So(actualFileSummary.Checksum.HexString(), ShouldEqual, expectedSummary.Checksum.HexString())
			So(actualFileSummary.ModTime.Equal(expectedSummary.ModTime), ShouldBeTrue)
		})
	})
}
func TestDirSummary(t *testing.T) {
	Convey("Test dir-summary of remote file system", t, func() {
		testData, err := testing_utils.NewTestDataContainer("testdata/copy-files", 6)
		So(err, ShouldBeNil)

		copiedDetails, err := copyTestDataToTempDir(testData, "")
		So(err, ShouldBeNil)
		defer copiedDetails.Cleanup()

		sessionFileSystem, err := testingGetNewSessionFileSystem()
		So(err, ShouldBeNil)
		checksumSvc := checksums.New()

		remoteOrigDir := copiedDetails.CopiedToTempDir
		summary, err := sessionFileSystem.DirSummary(remoteOrigDir)
		So(err, ShouldBeNil)
		So(summary, ShouldNotBeNil)

		So(summary.FlattenedFileSummaries, ShouldNotResemble, []*filepath_summary.FileSummary{})
		So(len(summary.FlattenedFileSummaries), ShouldNotEqual, 0)

		testData.ForeachRelativeFile(func(relPath string) {
			var actualFileSummary *filepath_summary.FileSummary
			for _, fileSummary := range summary.FlattenedFileSummaries {
				if fileSummary.RelativePath == relPath {
					actualFileSummary = fileSummary
					break
				}
			}
			if actualFileSummary == nil {
				So(fmt.Errorf("Did not find summary for file '%s'", relPath), ShouldBeNil)
			}

			fullRemoteFilePath := filepath.Join(copiedDetails.BaseTempDir, relPath)
			expectedSummary, err := getFileSummaryForFile(checksumSvc, fullRemoteFilePath)
			So(err, ShouldBeNil)

			So(actualFileSummary.Checksum.HexString(), ShouldEqual, expectedSummary.Checksum.HexString())
			So(actualFileSummary.ModTime.Equal(expectedSummary.ModTime), ShouldBeTrue)
		})

		So(len(summary.FlattenedFileSummaries), ShouldEqual, len(testData.RelativeFiles))
	})
}
Example #3
0
func (a *app) Run(logger service.Logger) {
	var logFilePath string
	usr, err := user.Current()
	if err == nil {
		logFilePath = filepath.Join(usr.HomeDir, ".config/go-psexec/server-hidden.log")
	} else {
		logFilePath = "server-hidden.log"
	}

	rollingFile := &lumberjack.Logger{
		Filename:   logFilePath,
		MaxSize:    20, // megabytes
		MaxBackups: 20,
		MaxAge:     28, //days
	}

	apex.SetLevel(apex.DebugLevel) //Global level
	apex.SetHandler(json.New(rollingFile))

	tmpLogger := &defaultLogger{
		logger,
		apex.WithField("exe", filepath.Base(os.Args[0])),
	}
	a.logger = tmpLogger

	defer func() {
		if r := recover(); r != nil {
			a.logger.Errorf("Panic recovery in service RUN function: %T %+v", r, r)
		}
	}()

	a.logger.Infof("Running server version %s", TempVersion)

	a.gracefulTimeout = 30 * time.Second //Because a command could be busy executing

	pvtKey, err := shared.ReadPemKey(*serverPemFlag)
	if err != nil {
		logger.Errorf("Cannot read server pem file, error: %s. Exiting server.", err.Error())
		return
	}
	a.privateKey = pvtKey

	checksumsSvc := checksums.New()
	handlerServices := &HandlerServices{
		FilePathSummaries: filepath_summary.New(checksumsSvc),
	}

	a.h = &handler{logger, a.privateKey, handlerServices}

	allowedKeys, err := shared.LoadAllowedPublicKeysFile(*allowedPublicKeysFileFlag)
	if err != nil {
		logger.Errorf("Cannot read allowed public keys, error: %s. Exiting server.", err.Error())
		return
	}
	if len(allowedKeys) == 0 {
		logger.Errorf("Allowed public key file '%s' was read but contains no keys. Exiting server.", *allowedPublicKeysFileFlag)
		return
	}

	a.setAllowedPublicKeys(allowedKeys)

	watcher, err := shared.StartWatcher(*allowedPublicKeysFileFlag, a)
	if err != nil {

	} else {
		a.watcherPublicKeys = watcher
	}

	e := echo.New()
	if a.debugMode {
		e.SetDebug(true)
	}

	e.Use(middleware.Recover())
	if a.accessLogger {
		loggerCfg := middleware.DefaultLoggerConfig
		loggerCfg.Output = tmpLogger
		e.Use(middleware.LoggerWithConfig(loggerCfg))
	}

	t := &htmlTemplateRenderer{}
	e.SetRenderer(t)

	// Unrestricted group
	e.POST("/token", a.h.handleGenerateTokenFunc)
	e.GET("/webui", a.h.handleWebUIFunc)

	// Restricted group
	r := e.Group("/auth")
	r.Use(GetClientPubkey())
	r.GET("/ping", a.h.handlePingFunc)
	r.GET("/version", a.h.handleVersionFunc)
	r.POST("/stream", a.h.handleStreamFunc)
	r.POST("/start", a.h.handleStartFunc)
	r.POST("/upload-tar", a.h.handleUploadTarFunc)
	r.GET("/download-tar", a.h.handleDownloadTarFunc)
	r.POST("/delete", a.h.handleDeleteFunc)
	r.POST("/move", a.h.handleMoveFunc)
	r.POST("/copy", a.h.handleCopyFunc)
	r.POST("/symlink", a.h.handleSymlinkFunc)
	r.GET("/stats", a.h.handleStatsFunc)
	r.GET("/path-summary", a.h.handlePathSummaryFunc)
	r.GET("/get-temp-dir", a.h.handleGetTempDirFunc)
	r.GET("/get-os-type", a.h.handleGetOsTypeFunc)

	a.logger.Infof("Now serving on '%s'", *addressFlag)

	server := standard.New(*addressFlag)
	server.SetHandler(e)
	server.SetLogger(e.Logger())
	if e.Debug() {
		e.Logger().Debug("running in debug mode")
	}

	a.srv = &graceful.Server{
		Timeout: a.gracefulTimeout,
		Server:  server.Server,
	}

	a.registerInterruptSignal()

	err = a.srv.ListenAndServe()
	if err != nil {
		if !strings.Contains(err.Error(), "closed network connection") {
			logger.Errorf("Unable to ListenAndServe, error: %s", err.Error())
			time.Sleep(time.Second) //Sleep a second to give log time to write out
		}
	}
}