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() }
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 }
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) }
// 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)) }
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}) }
// 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 }
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}) } }
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() }
// 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 }
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) }
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 }
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) }
// 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 }
// 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 }
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) }
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) }
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) }
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) }
// 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 }
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) }
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) }
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) }
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") }
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) }
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) }
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) }
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) }
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$") }
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, "") }
// 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) }