示例#1
0
func TestScriptExecution(t *testing.T) {
	Convey("Using a temporary file", t, func() {
		scriptPermissions := os.FileMode(0700)

		outChan := make(chan string, 1)
		executeScript := func(script *os.File) error {
			script.Close()

			out, err := sys.DefaultExecutor.Execute(script.Name())

			outChan <- out

			return err
		}

		Convey("Given a script file", func() {
			scriptContent := "#! /usr/bin/env bash\n"
			scriptContent += "echo -n Yeehaw\n"
			scriptContent += "\n"

			tmpFile := &context.TempFile{
				Permissions: scriptPermissions,
				Content:     scriptContent,
			}

			Convey("It should execute the script and return its output", func() {
				err := <-context.Using(tmpFile, executeScript)

				So(err, ShouldBeNil)
				So(<-outChan, ShouldEqual, "Yeehaw")
			})
		})

	})
}
示例#2
0
func TestSSHKeyAuthorization(t *testing.T) {
	Convey("Given an SSH authorized keys file and public keys", t, func() {
		rsa_key, err := ioutil.ReadFile("test_keys/test_rsa.pub")
		So(err, ShouldBeNil)

		dsa_key, err := ioutil.ReadFile("test_keys/test_dsa.pub")
		So(err, ShouldBeNil)

		tmpAuthKeysFile := &context.TempFile{
			Content:     "",
			Permissions: os.FileMode(0600),
		}

		Convey("It should append the SSH keys to the authorized keys file", func() {
			authorizeKey := func(f *os.File) error {
				err := ssh.AuthorizeKeys(f, []byte(rsa_key), []byte(dsa_key))
				if err != nil {
					return err
				}
				f.Close()

				// Checks whether the keys are authorized.
				_, err = sys.DefaultExecutor.Execute("ssh-keygen", "-l", "-f", f.Name())

				return err
			}

			err := <-context.Using(tmpAuthKeysFile, authorizeKey)
			So(err, ShouldBeNil)
		})
	})
}
示例#3
0
func TestUsingContexts(t *testing.T) {
	Convey("Given a context and a context use function", t, func() {
		NotEvenErr := errors.New("not a good number")

		checkIfEven := func(no int) error {
			if no%2 == 1 {
				return NotEvenErr
			}
			return nil
		}

		Convey("It should use the context in the order, Enter -> Use -> Exit", func() {
			ch := make(chan Signal)
			randomNumber := &RandomNumberContext{
				seed:         2,
				EventChannel: ch,
			}

			errch := context.Using(randomNumber, checkIfEven)

			event1, event2, event3 := <-ch, <-ch, <-ch

			So(event1, ShouldEqual, Enter)
			So(event2, ShouldEqual, Use)
			So(event3, ShouldEqual, Exit)

			err := <-errch
			So(err, ShouldBeNil)
		})

		Convey("It should propagate the errors encountered during use", func() {
			ch := make(chan Signal, 3)
			randomNumber := &RandomNumberContext{
				seed:         3,
				EventChannel: ch,
			}
			errch := context.Using(randomNumber, checkIfEven)

			err := <-errch
			So(err, ShouldEqual, NotEvenErr)
		})
	})
}
示例#4
0
// executeScript writes the given contents to a temporary file and executes the file.
func (imp *Implementation) executeScript(c string) error {
	tempFile := &context.TempFile{
		Content:     c,
		Permissions: 0600,
	}

	return <-context.Using(tempFile, func(f *os.File) error {
		f.Close()
		_, err := imp.Execute("sh", f.Name())

		return err
	})
}
示例#5
0
// Verify uses 'ssh-keygen' utility to verify an SSH key.
// It returns an error if a problem occurs or the key is invalid.
// The caller should diagnose the error for more information.
func Verify(key Key) error {
	tmpFile := &context.TempFile{
		Content: string(key),
	}

	var checkSSHValidity = func(f *os.File) error {
		_, err := sys.DefaultExecutor.Execute("ssh-keygen", "-l", "-f", f.Name())
		return err
	}

	errch := context.Using(tmpFile, checkSSHValidity)

	return <-errch
}
示例#6
0
// AuthorizeKeysFor initializes the SSH directory structure for the user and
// appends the given public keys to user's authorized keys file.
func AuthorizeKeysFor(usr *user.User, publicKeys []Key) error {
	err := InitializeFor(usr)
	if err != nil {
		return err
	}

	authorizationFile := &context.File{
		Path:        filepath.Join(usr.HomeDir, AuthorizedKeysPath),
		Permissions: os.FileMode(0600),
	}

	// TODO(tmrts): Check for duplicate keys.
	// TODO(tmrts): Add keys to /etc/ssh if keys exist.
	return <-context.Using(authorizationFile, func(f *os.File) error {
		return AuthorizeKeys(f, publicKeys...)
	})
}
示例#7
0
func (sysd *Implementation) CreateComponent(name, contents string) (initd.Component, error) {
	newUnit := &Unit{
		name: name,
		path: filepath.Join(sysd.UnitDir, name),
	}

	newFile := &context.NewFile{
		Path:        newUnit.Path(),
		Permissions: 0644,
	}

	errch := context.Using(newFile, func(f *os.File) error {
		_, err := f.WriteString(contents)

		return err
	})

	return newUnit, <-errch
}
示例#8
0
func TestDependencyInjection(t *testing.T) {
	Convey("Given a dependency and a replacement for that dependency with the same type", t, func() {
		So(ToLower("HELLO"), ShouldEqual, "hello")

		fakeToLower := func(string) string {
			return "This function has been hijacked."
		}

		Convey("It should inject the replacement to the dependency", func() {
			restoreDependency := ToLower.Inject(fakeToLower)

			So(ToLower("HELLO"), ShouldEqual, "This function has been hijacked.")
			So(ToLower("WORLD"), ShouldEqual, "This function has been hijacked.")

			restoreDependency()

			So(ToLower("HELLO"), ShouldEqual, "hello")
		})

		Convey("Within an injection context", func() {
			mockToLower := &injection.ContextManager{
				Dependency:  &ToLower,
				Replacement: fakeToLower,
			}

			Convey("It should use the injected function within the context", func() {
				outch := make(chan string)
				context.Using(mockToLower, func() error {
					outch <- ToLower("HELLO")
					return nil
				})

				So(<-outch, ShouldEqual, "This function has been hijacked.")
			})

			Convey("It should restore the injected function after the context is exited", func() {
				So(ToLower("HELLO"), ShouldEqual, "hello")
			})
		})
	})
}
示例#9
0
func TestScriptValidation(t *testing.T) {
	Convey("Using a temporary file", t, func() {
		scriptPermissions := os.FileMode(0600)

		isScript := make(chan bool, 1)
		performScriptValidation := func(script *os.File) error {
			script.Close()

			hasShabang, err := sys.FileHasShabang(script.Name())

			isScript <- hasShabang

			return err
		}

		Convey("Given a file without Shabang", func() {
			tmpFile := &context.TempFile{
				Permissions: scriptPermissions,
				Content:     "Some stuff\n",
			}

			Convey("It should return false", func() {
				err := <-context.Using(tmpFile, performScriptValidation)

				So(err, ShouldBeNil)
				So(<-isScript, ShouldBeFalse)
			})
		})

		Convey("Given a file with malformed Shabang", func() {
			tmpFile := &context.TempFile{
				Permissions: scriptPermissions,
				Content:     "# ! /bin/bash\nSome command\n",
			}

			Convey("It should return false", func() {
				err := <-context.Using(tmpFile, performScriptValidation)

				So(err, ShouldBeNil)
				So(<-isScript, ShouldBeFalse)
			})
		})

		Convey("Given an empty file with Shabang", func() {
			tmpFile := &context.TempFile{
				Permissions: scriptPermissions,
				Content:     "#! /bin/bash\n\n",
			}

			Convey("It should return true", func() {
				err := <-context.Using(tmpFile, performScriptValidation)

				So(err, ShouldBeNil)
				So(<-isScript, ShouldBeTrue)
			})
		})

		Convey("Given a script file with Shabang", func() {
			tmpFile := &context.TempFile{
				Permissions: scriptPermissions,
				Content:     "#! /bin/bash\nprintf ${PWD}\n",
			}

			Convey("It should return true", func() {
				err := <-context.Using(tmpFile, performScriptValidation)

				So(err, ShouldBeNil)
				So(<-isScript, ShouldBeTrue)
			})
		})
	})
}