Beispiel #1
0
// creates a copy of the authorized_keys and returns it, with the file cursor
// pointing at the first byte of the file.
func copyFile() (tsurufs.File, error) {
	path := authKey()
	fi, statErr := fs.Filesystem().Stat(path)
	if statErr != nil && !os.IsNotExist(statErr) {
		return nil, statErr
	}
	dstPath := path + ".tmp"
	dst, err := fs.Filesystem().OpenFile(dstPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
	if err != nil {
		return nil, err
	}
	if !os.IsNotExist(statErr) {
		original, err := fs.Filesystem().Open(path)
		if err != nil {
			return nil, err
		}
		defer original.Close()
		n, err := io.Copy(dst, original)
		if err != nil {
			dst.Close()
			return nil, err
		}
		if n != fi.Size() {
			dst.Close()
			return nil, io.ErrShortWrite
		}
		dst.Seek(0, 0)
	}
	return dst, nil
}
Beispiel #2
0
func CopyZipFile(f *zip.File, d, p string) error {
	if p != "" {
		dirname := path.Dir(p)
		if dirname != "." {
			err := os.MkdirAll(path.Join(d, dirname), 0755)
			if err != nil {
				return err
			}
		}
		rc, err := f.Open()
		defer rc.Close()
		if err != nil {
			return err
		}
		path := path.Join(d, p)
		stat, err := os.Stat(path)
		if err != nil || !stat.IsDir() {
			file, err := fs.Filesystem().OpenFile(path, os.O_WRONLY|os.O_CREATE, 0755)
			if err != nil {
				return err
			}
			defer file.Close()
			_, err = io.Copy(file, rc)
			if err != nil {
				return err
			}
		}
	}
	return nil
}
Beispiel #3
0
// Adds a hook script.
func Add(name string, repos []string, content []byte) error {
	configParam := "git:bare:template"
	if len(repos) > 0 {
		configParam = "git:bare:location"
	}
	path, err := config.GetString(configParam)
	if err != nil {
		return err
	}
	s := []string{path, "hooks", name}
	scriptPath := strings.Join(s, "/")
	if len(repos) > 0 {
		for _, repo := range repos {
			repo += ".git"
			s = []string{path, repo, "hooks", name}
			scriptPath = strings.Join(s, "/")
			err = fs.Filesystem().MkdirAll(scriptPath+"hooks", 0755)
			if err != nil {
				return err
			}
			err = createHookFile(scriptPath, content)
			if err != nil {
				return err
			}
		}
	} else {
		return createHookFile(scriptPath, content)
	}
	return nil
}
Beispiel #4
0
func remove(k *Key) error {
	formatted := k.format()
	file, err := fs.Filesystem().OpenFile(authKey(), os.O_RDWR|os.O_EXCL, 0644)
	if err != nil {
		return err
	}
	defer file.Close()
	lines := make([]string, 0, 10)
	reader := bufio.NewReader(file)
	line, _ := reader.ReadString('\n')
	for line != "" {
		if line != formatted {
			lines = append(lines, line)
		}
		line, _ = reader.ReadString('\n')
	}
	file.Truncate(0)
	file.Seek(0, 0)
	content := strings.Join(lines, "")
	n, err := file.WriteString(content)
	if err != nil {
		return err
	}
	if n != len(content) {
		return io.ErrShortWrite
	}
	return nil
}
Beispiel #5
0
// New creates a representation of a git repository. It creates a Git
// repository using the "bare-dir" setting and saves repository's meta data in
// the database.
func New(name string, users []string, isPublic bool) (*Repository, error) {
	log.Debugf("Creating repository %q", name)
	r := &Repository{Name: name, Users: users, IsPublic: isPublic}
	if v, err := r.isValid(); !v {
		log.Errorf("repository.New: Invalid repository %q: %s", name, err)
		return r, err
	}
	if err := newBare(name); err != nil {
		log.Errorf("repository.New: Error creating bare repository for %q: %s", name, err)
		return r, err
	}
	barePath := barePath(name)
	if barePath != "" && isPublic {
		ioutil.WriteFile(barePath+"/git-daemon-export-ok", []byte(""), 0644)
		if f, err := fs.Filesystem().Create(barePath + "/git-daemon-export-ok"); err == nil {
			f.Close()
		}
	}
	conn, err := db.Conn()
	if err != nil {
		return nil, err
	}
	defer conn.Close()
	err = conn.Repository().Insert(&r)
	if mgo.IsDup(err) {
		log.Errorf("repository.New: Duplicate repository %q", name)
		return r, fmt.Errorf("A repository with this name already exists.")
	}
	return r, err
}
Beispiel #6
0
// Rename renames a repository.
func Rename(oldName, newName string) error {
	log.Debugf("Renaming repository %q to %q", oldName, newName)
	repo, err := Get(oldName)
	if err != nil {
		log.Errorf("repository.Rename: Repository %q not found: %s", oldName, err)
		return err
	}
	newRepo := repo
	newRepo.Name = newName
	conn, err := db.Conn()
	if err != nil {
		return err
	}
	defer conn.Close()
	err = conn.Repository().Insert(newRepo)
	if err != nil {
		log.Errorf("repository.Rename: Error adding new repository %q: %s", newName, err)
		return err
	}
	err = conn.Repository().RemoveId(oldName)
	if err != nil {
		log.Errorf("repository.Rename: Error removing old repository %q: %s", oldName, err)
		return err
	}
	return fs.Filesystem().Rename(barePath(oldName), barePath(newName))
}
Beispiel #7
0
func (s *S) authKeysContent(c *gocheck.C) string {
	authKeysPath := path.Join(os.Getenv("HOME"), ".ssh", "authorized_keys")
	f, err := fs.Filesystem().OpenFile(authKeysPath, os.O_RDWR|os.O_EXCL, 0755)
	c.Assert(err, gocheck.IsNil)
	content, err := ioutil.ReadAll(f)
	return string(content)
}
Beispiel #8
0
// New creates a representation of a git repository. It creates a Git
// repository using the "bare-dir" setting and saves repository's meta data in
// the database.
func New(name string, users, readOnlyUsers []string, isPublic bool) (*Repository, error) {
	log.Debugf("Creating repository %q", name)
	r := &Repository{Name: name, Users: users, ReadOnlyUsers: readOnlyUsers, IsPublic: isPublic}
	if v, err := r.isValid(); !v {
		log.Errorf("repository.New: Invalid repository %q: %s", name, err)
		return r, err
	}
	conn, err := db.Conn()
	if err != nil {
		return nil, err
	}
	defer conn.Close()
	err = conn.Repository().Insert(r)
	if err != nil {
		if mgo.IsDup(err) {
			return nil, ErrRepositoryAlreadyExists
		}
		return nil, err
	}
	if err = newBare(name); err != nil {
		log.Errorf("repository.New: Error creating bare repository for %q: %s", name, err)
		conn.Repository().Remove(bson.M{"_id": r.Name})
		return r, err
	}
	barePath := barePath(name)
	if barePath != "" && isPublic {
		if f, createErr := fs.Filesystem().Create(barePath + "/git-daemon-export-ok"); createErr == nil {
			f.Close()
		}
	}
	return r, err
}
Beispiel #9
0
func removeBare(name string) error {
	err := fs.Filesystem().RemoveAll(barePath(name))
	if err != nil {
		return fmt.Errorf("Could not remove git bare repository: %s", err)
	}
	return nil
}
Beispiel #10
0
func (s *S) authKeysContent(c *gocheck.C) string {
	authFile := path.Join(os.Getenv("HOME"), ".ssh", "authorized_keys")
	f, err := fs.Filesystem().OpenFile(authFile, os.O_RDWR, 0755)
	c.Assert(err, gocheck.IsNil)
	defer f.Close()
	b, err := ioutil.ReadAll(f)
	c.Assert(err, gocheck.IsNil)
	return string(b)
}
Beispiel #11
0
// writeKeys serializes the given key in the authorized_keys file (of the
// current user).
func writeKey(k *Key) error {
	file, err := fs.Filesystem().OpenFile(authKey(), os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)
	if err != nil {
		return err
	}
	defer file.Close()
	syscall.Flock(int(file.Fd()), syscall.LOCK_EX)
	defer syscall.Flock(int(file.Fd()), syscall.LOCK_UN)
	return k.dump(file)
}
Beispiel #12
0
func (s *S) TestCanAddNewHook(c *gocheck.C) {
	hook_content := strings.NewReader("some content")
	err := Add("test-can-add-new-hook", []string{}, hook_content)
	c.Assert(err, gocheck.IsNil)
	file, err := fs.Filesystem().OpenFile("/home/git/bare-template/hooks/test-can-add-new-hook", os.O_RDONLY, 0755)
	defer file.Close()
	content, err := ioutil.ReadAll(file)
	c.Assert(err, gocheck.IsNil)
	c.Assert(string(content), gocheck.Equals, "some content")
}
Beispiel #13
0
func (s *S) TestCanCreateHookFile(c *gocheck.C) {
	hook_content := strings.NewReader("some content")
	err := createHookFile("/tmp/repositories/some-repo.git/hooks/test-can-create-hook-file", hook_content)
	c.Assert(err, gocheck.IsNil)
	file, err := fs.Filesystem().OpenFile("/tmp/repositories/some-repo.git/hooks/test-can-create-hook-file", os.O_RDONLY, 0755)
	defer file.Close()
	content, err := ioutil.ReadAll(file)
	c.Assert(err, gocheck.IsNil)
	c.Assert(string(content), gocheck.Equals, "some content")
}
Beispiel #14
0
func (s *S) TestCanAddNewRepository(c *gocheck.C) {
	hook_content := strings.NewReader("some content")
	err := Add("test-can-add-new-repository-hook", []string{"some-repo"}, hook_content)
	c.Assert(err, gocheck.IsNil)
	file, err := fs.Filesystem().OpenFile("/tmp/repositories/some-repo.git/hooks/test-can-add-new-repository-hook", os.O_RDONLY, 0755)
	defer file.Close()
	content, err := ioutil.ReadAll(file)
	c.Assert(err, gocheck.IsNil)
	c.Assert(string(content), gocheck.Equals, "some content")
}
Beispiel #15
0
func createHookFile(path string, content []byte) error {
	file, err := fs.Filesystem().OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
	if err != nil {
		return err
	}
	defer file.Close()
	_, err = file.Write(content)
	if err != nil {
		return err
	}
	return nil
}
Beispiel #16
0
func createHookFile(path string, body io.Reader) error {
	file, err := fs.Filesystem().OpenFile(path, os.O_WRONLY|os.O_CREATE, 0755)
	if err != nil {
		return err
	}
	defer file.Close()
	_, err = io.Copy(file, body)
	if err != nil {
		return err
	}
	return nil
}
func (s *S) TestAddUpdateReceiveHookRepository(c *gocheck.C) {
	b := strings.NewReader(`{"repositories": ["some-repo"], "content": "some content"}`)
	recorder, request := post("repository/hook/update?:name=update", b, c)
	AddHook(recorder, request)
	got := readBody(recorder.Body, c)
	expected := "hook update successfully created for [some-repo]\n"
	c.Assert(got, gocheck.Equals, expected)
	c.Assert(recorder.Code, gocheck.Equals, 200)
	file, err := fs.Filesystem().OpenFile("/tmp/repositories/some-repo.git/hooks/update", os.O_RDONLY, 0755)
	defer file.Close()
	content, err := ioutil.ReadAll(file)
	c.Assert(err, gocheck.IsNil)
	c.Assert(string(content), gocheck.Equals, "some content")
}
func (s *S) TestAddUpdateOldFormatHook(c *gocheck.C) {
	b := strings.NewReader("some content")
	recorder, request := post("/hook/update?:name=update", b, c)
	AddHook(recorder, request)
	got := readBody(recorder.Body, c)
	expected := "hook update successfully created\n"
	c.Assert(got, gocheck.Equals, expected)
	c.Assert(recorder.Code, gocheck.Equals, 200)
	file, err := fs.Filesystem().OpenFile("/home/git/bare-template/hooks/update", os.O_RDONLY, 0755)
	defer file.Close()
	content, err := ioutil.ReadAll(file)
	c.Assert(err, gocheck.IsNil)
	c.Assert(string(content), gocheck.Equals, "some content")
}
Beispiel #19
0
func (s *S) TestCanAddNewHookInOldRepository(c *check.C) {
	s.rfs = &fstest.RecordingFs{}
	fs.Fsystem = s.rfs
	bareTemplate, _ := config.GetString("git:bare:template")
	err := fs.Fsystem.RemoveAll(bareTemplate + "/hooks")
	c.Assert(err, check.IsNil)
	hookContent := []byte("some content")
	err = Add("test-can-add-new-hook", []string{}, hookContent)
	c.Assert(err, check.IsNil)
	file, err := fs.Filesystem().OpenFile("/home/git/bare-template/hooks/test-can-add-new-hook", os.O_RDONLY, 0755)
	defer file.Close()
	content, err := ioutil.ReadAll(file)
	c.Assert(err, check.IsNil)
	c.Assert(string(content), check.Equals, "some content")
}
Beispiel #20
0
// Adds a hook script.
func Add(name string, body io.ReadCloser) error {
	path, err := config.GetString("git:bare:template")
	if err != nil {
		return err
	}
	s := []string{path, "hooks", name}
	scriptPath := strings.Join(s, "/")
	file, err := fs.Filesystem().OpenFile(scriptPath, os.O_WRONLY|os.O_CREATE, 0755)
	if err != nil {
		return err
	}
	defer file.Close()
	_, err = io.Copy(file, body)
	if err != nil {
		return err
	}
	return nil
}
Beispiel #21
0
// Update update a repository data.
func Update(name string, newData Repository) error {
	log.Debugf("Updating repository %q data", name)
	repo, err := Get(name)
	if err != nil {
		log.Errorf("repository.Update(%q): %s", name, err)
		return err
	}
	conn, err := db.Conn()
	if err != nil {
		return err
	}
	defer conn.Close()
	if len(newData.Name) > 0 && newData.Name != repo.Name {
		oldName := repo.Name
		log.Debugf("Renaming repository %q to %q", oldName, newData.Name)
		err = conn.Repository().Insert(newData)
		if err != nil {
			log.Errorf("repository.Rename: Error adding new repository %q: %s", newData.Name, err)
			return err
		}
		err = conn.Repository().RemoveId(oldName)
		if err != nil {
			log.Errorf("repository.Rename: Error removing old repository %q: %s", oldName, err)
			return err
		}
		err = fs.Filesystem().Rename(barePath(oldName), barePath(newData.Name))
		if err != nil {
			log.Errorf("repository.Rename: Error renaming old repository in filesystem %q: %s", oldName, err)
			return err
		}
	} else {
		err = conn.Repository().UpdateId(repo.Name, newData)
		if err != nil {
			log.Errorf("repository.Update: Error updating repository data %q: %s", repo.Name, err)
			return err
		}
	}
	return nil
}
Beispiel #22
0
// moveFile writes the authorized key file atomically.
func moveFile(fromPath string) error {
	return fs.Filesystem().Rename(fromPath, authKey())
}