Пример #1
0
func (s *S) TearDownSuite(c *gocheck.C) {
	commandmocker.Remove(s.tmpdir)
	conn, err := db.Conn()
	c.Assert(err, gocheck.IsNil)
	defer conn.Close()
	conn.User().Database.DropDatabase()
}
Пример #2
0
func (u *User) handleAssociatedRepositories() error {
	var repos []repository.Repository
	conn, err := db.Conn()
	if err != nil {
		return err
	}
	defer conn.Close()
	if err := conn.Repository().Find(bson.M{"users": u.Name}).All(&repos); err != nil {
		return err
	}
	for _, r := range repos {
		if len(r.Users) == 1 {
			return errors.New("Could not remove user: user is the only one with access to at least one of it's repositories")
		}
	}
	for _, r := range repos {
		for i, v := range r.Users {
			if v == u.Name {
				r.Users[i], r.Users = r.Users[len(r.Users)-1], r.Users[:len(r.Users)-1]
				if err := conn.Repository().Update(bson.M{"_id": r.Name}, r); err != nil {
					return err
				}
				break
			}
		}
	}
	return nil
}
Пример #3
0
func updateKey(name, body, username string) error {
	newK, err := newKey(name, username, body)
	if err != nil {
		return err
	}
	var oldK Key
	conn, err := db.Conn()
	if err != nil {
		return err
	}
	defer conn.Close()
	err = conn.Key().Find(bson.M{"name": name, "username": username}).One(&oldK)
	if err != nil {
		return ErrKeyNotFound
	}
	err = remove(&oldK)
	if err != nil {
		return err
	}
	err = writeKey(newK)
	if err != nil {
		writeKey(&oldK)
		return err
	}
	return conn.Key().Update(bson.M{"name": name, "username": username}, newK)
}
Пример #4
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))
}
Пример #5
0
func (s *S) TestGrantAccessShouldAddUserToListOfRepositories(c *gocheck.C) {
	tmpdir, err := commandmocker.Add("git", "$*")
	c.Assert(err, gocheck.IsNil)
	defer commandmocker.Remove(tmpdir)
	r, err := New("proj1", []string{"someuser"}, true)
	c.Assert(err, gocheck.IsNil)
	conn, err := db.Conn()
	c.Assert(err, gocheck.IsNil)
	defer conn.Close()
	defer conn.Repository().RemoveId(r.Name)
	r2, err := New("proj2", []string{"otheruser"}, true)
	c.Assert(err, gocheck.IsNil)
	defer conn.Repository().RemoveId(r2.Name)
	u := struct {
		Name string `bson:"_id"`
	}{Name: "lolcat"}
	err = conn.User().Insert(&u)
	c.Assert(err, gocheck.IsNil)
	defer conn.User().RemoveId(u.Name)
	err = GrantAccess([]string{r.Name, r2.Name}, []string{u.Name})
	c.Assert(err, gocheck.IsNil)
	err = conn.Repository().FindId(r.Name).One(&r)
	c.Assert(err, gocheck.IsNil)
	err = conn.Repository().FindId(r2.Name).One(&r2)
	c.Assert(err, gocheck.IsNil)
	c.Assert(r.Users, gocheck.DeepEquals, []string{"someuser", u.Name})
	c.Assert(r2.Users, gocheck.DeepEquals, []string{"otheruser", u.Name})
}
Пример #6
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
}
Пример #7
0
func (s *S) TestGrantAccessUpdatesReposDocument(c *gocheck.C) {
	u, err := user.New("pippin", map[string]string{})
	conn, err := db.Conn()
	c.Assert(err, gocheck.IsNil)
	defer conn.Close()
	defer conn.User().Remove(bson.M{"_id": "pippin"})
	c.Assert(err, gocheck.IsNil)
	r := repository.Repository{Name: "onerepo"}
	err = conn.Repository().Insert(&r)
	c.Assert(err, gocheck.IsNil)
	defer conn.Repository().Remove(bson.M{"_id": r.Name})
	r2 := repository.Repository{Name: "otherepo"}
	err = conn.Repository().Insert(&r2)
	c.Assert(err, gocheck.IsNil)
	defer conn.Repository().Remove(bson.M{"_id": r2.Name})
	b := bytes.NewBufferString(fmt.Sprintf(`{"repositories": ["%s", "%s"], "users": ["%s"]}`, r.Name, r2.Name, u.Name))
	rec, req := del("/repository/grant", b, c)
	GrantAccess(rec, req)
	var repos []repository.Repository
	err = conn.Repository().Find(bson.M{"_id": bson.M{"$in": []string{r.Name, r2.Name}}}).All(&repos)
	c.Assert(err, gocheck.IsNil)
	c.Assert(rec.Code, gocheck.Equals, 200)
	for _, repo := range repos {
		c.Assert(repo.Users, gocheck.DeepEquals, []string{u.Name})
	}
}
Пример #8
0
func (s *S) TearDownSuite(c *gocheck.C) {
	fs.Fsystem = nil
	conn, err := db.Conn()
	c.Assert(err, gocheck.IsNil)
	defer conn.Close()
	conn.User().Database.DropDatabase()
}
Пример #9
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
}
Пример #10
0
func (s *S) retrieveRepos(r, r2 *repository.Repository, c *gocheck.C) {
	conn, err := db.Conn()
	c.Assert(err, gocheck.IsNil)
	err = conn.Repository().FindId(r.Name).One(&r)
	c.Assert(err, gocheck.IsNil)
	err = conn.Repository().FindId(r2.Name).One(&r2)
	c.Assert(err, gocheck.IsNil)
}
Пример #11
0
func (s *S) createRepo(name string, users []string, c *gocheck.C) repository.Repository {
	r := repository.Repository{Name: name, Users: users}
	conn, err := db.Conn()
	c.Assert(err, gocheck.IsNil)
	err = conn.Repository().Insert(&r)
	c.Assert(err, gocheck.IsNil)
	return r
}
Пример #12
0
func (s *S) TestUserUpdateKeyNotFound(c *check.C) {
	newKey := Key{Name: "somekey", Body: otherKey}
	u, err := New("umi", map[string]string{})
	conn, err := db.Conn()
	c.Assert(err, check.IsNil)
	defer conn.User().RemoveId(u.Name)
	err = UpdateKey("umi", newKey)
	c.Assert(err, check.Equals, ErrKeyNotFound)
}
Пример #13
0
// GrantAccess gives write permission for users in all specified repositories.
// If any of the repositories/users do not exists, GrantAccess just skips it.
func GrantAccess(rNames, uNames []string) error {
	conn, err := db.Conn()
	if err != nil {
		return err
	}
	defer conn.Close()
	_, err = conn.Repository().UpdateAll(bson.M{"_id": bson.M{"$in": rNames}}, bson.M{"$addToSet": bson.M{"users": bson.M{"$each": uNames}}})
	return err
}
Пример #14
0
// RevokeAccess revokes write permission from users in all specified
// repositories.
func RevokeAccess(rNames, uNames []string) error {
	conn, err := db.Conn()
	if err != nil {
		return err
	}
	defer conn.Close()
	_, err = conn.Repository().UpdateAll(bson.M{"_id": bson.M{"$in": rNames}}, bson.M{"$pullAll": bson.M{"users": uNames}})
	return err
}
Пример #15
0
func (s *S) TestNewUserWihoutKeys(c *gocheck.C) {
	b := strings.NewReader(`{"name": "brain"}`)
	recorder, request := post("/user", b, c)
	NewUser(recorder, request)
	conn, err := db.Conn()
	c.Assert(err, gocheck.IsNil)
	defer conn.Close()
	defer conn.User().Remove(bson.M{"_id": "brain"})
	c.Assert(recorder.Code, gocheck.Equals, 200)
}
Пример #16
0
func (s *S) TestHasReadPermissionShouldReturnFalseWhenUserDoesNotHavePermissionToReadWriteAndRepoIsNotPublic(c *gocheck.C) {
	r := &repository.Repository{Name: "myotherapp", IsPublic: false}
	conn, err := db.Conn()
	c.Assert(err, gocheck.IsNil)
	defer conn.Close()
	conn.Repository().Insert(&r)
	defer conn.Repository().Remove(bson.M{"_id": r.Name})
	allowed := hasReadPermission(s.user, r)
	c.Assert(allowed, gocheck.Equals, false)
}
Пример #17
0
func (s *S) TestHasWritePermissionShouldReturnFalseWhenUserCannotWriteinRepo(c *gocheck.C) {
	r := &repository.Repository{Name: "myotherapp"}
	conn, err := db.Conn()
	c.Assert(err, gocheck.IsNil)
	defer conn.Close()
	conn.Repository().Insert(&r)
	defer conn.Repository().Remove(bson.M{"_id": r.Name})
	allowed := hasWritePermission(s.user, r)
	c.Assert(allowed, gocheck.Equals, false)
}
Пример #18
0
func (s *S) TestNewDuplicateUserDifferentKey(c *check.C) {
	u, err := New("someuser", map[string]string{"somekey": rawKey})
	c.Assert(err, check.IsNil)
	conn, err := db.Conn()
	c.Assert(err, check.IsNil)
	defer conn.User().Remove(bson.M{"_id": u.Name})
	defer conn.Key().Remove(bson.M{"name": "somekey"})
	_, err = New("someuser", map[string]string{"somedifferentkey": rawKey + "fakeKey"})
	c.Assert(err, check.Equals, ErrUserAlreadyExists)
}
Пример #19
0
// Get find a repository by name.
func Get(name string) (Repository, error) {
	var r Repository
	conn, err := db.Conn()
	if err != nil {
		return r, err
	}
	defer conn.Close()
	err = conn.Repository().FindId(name).One(&r)
	return r, err
}
Пример #20
0
func (s *S) TestAddKeyDuplicate(c *check.C) {
	err := addKey("key1", rawKey, "gopher")
	c.Assert(err, check.IsNil)
	conn, err := db.Conn()
	c.Assert(err, check.IsNil)
	defer conn.Close()
	defer conn.Key().Remove(bson.M{"name": "key1"})
	err = addKey("key2", rawKey, "gopher")
	c.Assert(err, check.Equals, ErrDuplicateKey)
}
Пример #21
0
func (s *S) TestHasReadPermissionShouldReturnTrueWhenRepositoryIsPublic(c *gocheck.C) {
	r := &repository.Repository{Name: "myotherapp", IsPublic: true}
	conn, err := db.Conn()
	c.Assert(err, gocheck.IsNil)
	defer conn.Close()
	conn.Repository().Insert(&r)
	defer conn.Repository().Remove(bson.M{"_id": r.Name})
	allowed := hasReadPermission(s.user, r)
	c.Assert(allowed, gocheck.Equals, true)
}
Пример #22
0
func (s *S) TestRemoveUnknownKeyFromUser(c *gocheck.C) {
	u, err := New("luke", map[string]string{})
	c.Assert(err, gocheck.IsNil)
	conn, err := db.Conn()
	c.Assert(err, gocheck.IsNil)
	defer conn.Close()
	defer conn.User().RemoveId(u.Name)
	err = RemoveKey("luke", "homekey")
	c.Assert(err, gocheck.Equals, ErrKeyNotFound)
}
Пример #23
0
func (s *S) TestNewDuplicateUserDifferentKey(c *gocheck.C) {
	u, err := New("someuser", map[string]string{"somekey": rawKey})
	c.Assert(err, gocheck.IsNil)
	conn, err := db.Conn()
	c.Assert(err, gocheck.IsNil)
	defer conn.User().Remove(bson.M{"_id": u.Name})
	defer conn.Key().Remove(bson.M{"name": "somekey"})
	u, err = New("someuser", map[string]string{"somedifferentkey": rawKey + "fakeKey"})
	c.Assert(err, gocheck.ErrorMatches, "Could not create user: user already exists")
}
Пример #24
0
func (s *S) TestGet(c *gocheck.C) {
	repo := Repository{Name: "somerepo", Users: []string{}}
	conn, err := db.Conn()
	c.Assert(err, gocheck.IsNil)
	defer conn.Close()
	err = conn.Repository().Insert(repo)
	c.Assert(err, gocheck.IsNil)
	r, err := Get("somerepo")
	c.Assert(err, gocheck.IsNil)
	c.Assert(r, gocheck.DeepEquals, repo)
}
Пример #25
0
func (s *S) TestRemoveKeyDeletesFromDB(c *check.C) {
	err := addKey("key1", rawKey, "gopher")
	c.Assert(err, check.IsNil)
	err = removeKey("key1", "gopher")
	c.Assert(err, check.IsNil)
	conn, err := db.Conn()
	c.Assert(err, check.IsNil)
	count, err := conn.Key().Find(bson.M{"name": "key1"}).Count()
	c.Assert(err, check.IsNil)
	c.Assert(count, check.Equals, 0)
}
Пример #26
0
func (s *S) TestListKeysEmpty(c *check.C) {
	user := map[string]string{"_id": "gopher"}
	conn, err := db.Conn()
	c.Assert(err, check.IsNil)
	err = conn.User().Insert(user)
	c.Assert(err, check.IsNil)
	defer conn.User().Remove(user)
	got, err := ListKeys("gopher")
	c.Assert(err, check.IsNil)
	c.Assert(got, check.HasLen, 0)
}
Пример #27
0
func (s *S) TestRemove(c *gocheck.C) {
	u, err := New("someuser", map[string]string{})
	c.Assert(err, gocheck.IsNil)
	err = Remove(u.Name)
	c.Assert(err, gocheck.IsNil)
	conn, err := db.Conn()
	c.Assert(err, gocheck.IsNil)
	lenght, err := conn.User().FindId(u.Name).Count()
	c.Assert(err, gocheck.IsNil)
	c.Assert(lenght, gocheck.Equals, 0)
}
Пример #28
0
func (s *S) TestRemoveDoesNotRemovesUserWhenUserIsTheOnlyOneAssciatedWithOneRepository(c *gocheck.C) {
	u, err := New("silver", map[string]string{})
	c.Assert(err, gocheck.IsNil)
	r := s.createRepo("run", []string{u.Name}, c)
	conn, err := db.Conn()
	c.Assert(err, gocheck.IsNil)
	defer conn.Repository().Remove(bson.M{"_id": r.Name})
	defer conn.User().Remove(bson.M{"_id": u.Name})
	err = Remove(u.Name)
	c.Assert(err, gocheck.ErrorMatches, "^Could not remove user: user is the only one with access to at least one of it's repositories$")
}
Пример #29
0
func (s *S) TestRemoveRemovesKeyFromAuthorizedKeysFile(c *gocheck.C) {
	u, err := New("gandalf", map[string]string{"somekey": rawKey})
	c.Assert(err, gocheck.IsNil)
	conn, err := db.Conn()
	c.Assert(err, gocheck.IsNil)
	defer conn.Key().Remove(bson.M{"name": "somekey"})
	err = Remove(u.Name)
	c.Assert(err, gocheck.IsNil)
	got := s.authKeysContent(c)
	c.Assert(got, gocheck.Equals, "")
}
Пример #30
0
// RemoveKey removes the key from the database and from authorized_keys file.
//
// If the user or the key is not found, returns an error.
func RemoveKey(uName, kName string) error {
	var u User
	conn, err := db.Conn()
	if err != nil {
		return err
	}
	defer conn.Close()
	if err := conn.User().FindId(uName).One(&u); err != nil {
		return ErrUserNotFound
	}
	return removeKey(kName, uName)
}