summaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
Diffstat (limited to 'models')
-rw-r--r--models/access.go17
-rw-r--r--models/action.go11
-rw-r--r--models/issue.go4
-rw-r--r--models/login.go4
-rw-r--r--models/models.go2
-rw-r--r--models/org.go192
-rw-r--r--models/repo.go129
-rw-r--r--models/update.go27
-rw-r--r--models/user.go161
9 files changed, 413 insertions, 134 deletions
diff --git a/models/access.go b/models/access.go
index cf31fc137b..5238daba32 100644
--- a/models/access.go
+++ b/models/access.go
@@ -11,19 +11,20 @@ import (
"github.com/go-xorm/xorm"
)
-// Access types.
+type AccessType int
+
const (
- AU_READABLE = iota + 1
- AU_WRITABLE
+ READABLE AccessType = iota + 1
+ WRITABLE
)
// Access represents the accessibility of user to repository.
type Access struct {
Id int64
- UserName string `xorm:"unique(s)"`
- RepoName string `xorm:"unique(s)"` // <user name>/<repo name>
- Mode int `xorm:"unique(s)"`
- Created time.Time `xorm:"created"`
+ UserName string `xorm:"unique(s)"`
+ RepoName string `xorm:"unique(s)"` // <user name>/<repo name>
+ Mode AccessType `xorm:"unique(s)"`
+ Created time.Time `xorm:"created"`
}
// AddAccess adds new access record.
@@ -59,7 +60,7 @@ func UpdateAccessWithSession(sess *xorm.Session, access *Access) error {
// HasAccess returns true if someone can read or write to given repository.
// The repoName should be in format <username>/<reponame>.
-func HasAccess(uname, repoName string, mode int) (bool, error) {
+func HasAccess(uname, repoName string, mode AccessType) (bool, error) {
if len(repoName) == 0 {
return false, nil
}
diff --git a/models/action.go b/models/action.go
index 8ecdf1de16..55557da2ff 100644
--- a/models/action.go
+++ b/models/action.go
@@ -182,14 +182,15 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
}
// NewRepoAction adds new action for creating repository.
-func NewRepoAction(user *User, repo *Repository) (err error) {
- if err = NotifyWatchers(&Action{ActUserId: user.Id, ActUserName: user.Name, ActEmail: user.Email,
- OpType: OP_CREATE_REPO, RepoId: repo.Id, RepoName: repo.Name, IsPrivate: repo.IsPrivate}); err != nil {
- log.Error("action.NewRepoAction(notify watchers): %d/%s", user.Id, repo.Name)
+func NewRepoAction(u *User, repo *Repository) (err error) {
+ if err = NotifyWatchers(&Action{ActUserId: u.Id, ActUserName: u.Name, ActEmail: u.Email,
+ OpType: OP_CREATE_REPO, RepoId: repo.Id, RepoUserName: repo.Owner.Name, RepoName: repo.Name,
+ IsPrivate: repo.IsPrivate}); err != nil {
+ log.Error("action.NewRepoAction(notify watchers): %d/%s", u.Id, repo.Name)
return err
}
- log.Trace("action.NewRepoAction: %s/%s", user.LowerName, repo.LowerName)
+ log.Trace("action.NewRepoAction: %s/%s", u.LowerName, repo.LowerName)
return err
}
diff --git a/models/issue.go b/models/issue.go
index 11f6dd4ef9..6d67a72bc4 100644
--- a/models/issue.go
+++ b/models/issue.go
@@ -213,9 +213,9 @@ func GetIssueCountByPoster(uid, rid int64, isClosed bool) int64 {
// IssueUser represents an issue-user relation.
type IssueUser struct {
Id int64
- Uid int64 // User ID.
+ Uid int64 `xorm:"INDEX"` // User ID.
IssueId int64
- RepoId int64
+ RepoId int64 `xorm:"INDEX"`
MilestoneId int64
IsRead bool
IsAssigned bool
diff --git a/models/login.go b/models/login.go
index 98c5c64e40..e99b61e779 100644
--- a/models/login.go
+++ b/models/login.go
@@ -255,7 +255,7 @@ func LoginUserLdapSource(user *User, name, passwd string, sourceId int64, cfg *L
Email: mail,
}
- return RegisterUser(user)
+ return CreateUser(user)
}
type loginAuth struct {
@@ -359,5 +359,5 @@ func LoginUserSMTPSource(user *User, name, passwd string, sourceId int64, cfg *S
Passwd: passwd,
Email: name,
}
- return RegisterUser(user)
+ return CreateUser(user)
}
diff --git a/models/models.go b/models/models.go
index d6273d7f98..4e65c00bcb 100644
--- a/models/models.go
+++ b/models/models.go
@@ -35,7 +35,7 @@ func init() {
tables = append(tables, new(User), new(PublicKey), new(Repository), new(Watch),
new(Action), new(Access), new(Issue), new(Comment), new(Oauth2), new(Follow),
new(Mirror), new(Release), new(LoginSource), new(Webhook), new(IssueUser),
- new(Milestone), new(Label), new(HookTask))
+ new(Milestone), new(Label), new(HookTask), new(Team), new(OrgUser), new(TeamUser))
}
func LoadModelsConfig() {
diff --git a/models/org.go b/models/org.go
new file mode 100644
index 0000000000..553a46aa0b
--- /dev/null
+++ b/models/org.go
@@ -0,0 +1,192 @@
+// Copyright 2014 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package models
+
+import (
+ "strings"
+
+ "github.com/gogits/gogs/modules/base"
+)
+
+// CreateOrganization creates record of a new organization.
+func CreateOrganization(org, owner *User) (*User, error) {
+ if !IsLegalName(org.Name) {
+ return nil, ErrUserNameIllegal
+ }
+
+ isExist, err := IsUserExist(org.Name)
+ if err != nil {
+ return nil, err
+ } else if isExist {
+ return nil, ErrUserAlreadyExist
+ }
+
+ isExist, err = IsEmailUsed(org.Email)
+ if err != nil {
+ return nil, err
+ } else if isExist {
+ return nil, ErrEmailAlreadyUsed
+ }
+
+ org.LowerName = strings.ToLower(org.Name)
+ org.FullName = org.Name
+ org.Avatar = base.EncodeMd5(org.Email)
+ org.AvatarEmail = org.Email
+ // No password for organization.
+ org.NumTeams = 1
+ org.NumMembers = 1
+
+ sess := x.NewSession()
+ defer sess.Close()
+ if err = sess.Begin(); err != nil {
+ return nil, err
+ }
+
+ if _, err = sess.Insert(org); err != nil {
+ sess.Rollback()
+ return nil, err
+ }
+
+ // Create default owner team.
+ t := &Team{
+ OrgId: org.Id,
+ Name: OWNER_TEAM,
+ Authorize: ORG_ADMIN,
+ NumMembers: 1,
+ }
+ if _, err = sess.Insert(t); err != nil {
+ sess.Rollback()
+ return nil, err
+ }
+
+ // Add initial creator to organization and owner team.
+ ou := &OrgUser{
+ Uid: owner.Id,
+ OrgId: org.Id,
+ IsOwner: true,
+ NumTeam: 1,
+ }
+ if _, err = sess.Insert(ou); err != nil {
+ sess.Rollback()
+ return nil, err
+ }
+
+ tu := &TeamUser{
+ Uid: owner.Id,
+ OrgId: org.Id,
+ TeamId: t.Id,
+ }
+ if _, err = sess.Insert(tu); err != nil {
+ sess.Rollback()
+ return nil, err
+ }
+
+ return org, sess.Commit()
+}
+
+type AuthorizeType int
+
+const (
+ ORG_READABLE AuthorizeType = iota + 1
+ ORG_WRITABLE
+ ORG_ADMIN
+)
+
+const OWNER_TEAM = "Owner"
+
+// Team represents a organization team.
+type Team struct {
+ Id int64
+ OrgId int64 `xorm:"INDEX"`
+ Name string
+ Description string
+ Authorize AuthorizeType
+ RepoIds string `xorm:"TEXT"`
+ NumMembers int
+ NumRepos int
+}
+
+// NewTeam creates a record of new team.
+func NewTeam(t *Team) error {
+ _, err := x.Insert(t)
+ return err
+}
+
+func UpdateTeam(t *Team) error {
+ if len(t.Description) > 255 {
+ t.Description = t.Description[:255]
+ }
+
+ _, err := x.Id(t.Id).AllCols().Update(t)
+ return err
+}
+
+// ________ ____ ___
+// \_____ \_______ ____ | | \______ ___________
+// / | \_ __ \/ ___\| | / ___// __ \_ __ \
+// / | \ | \/ /_/ > | /\___ \\ ___/| | \/
+// \_______ /__| \___ /|______//____ >\___ >__|
+// \/ /_____/ \/ \/
+
+// OrgUser represents an organization-user relation.
+type OrgUser struct {
+ Id int64
+ Uid int64 `xorm:"INDEX"`
+ OrgId int64 `xorm:"INDEX"`
+ IsPublic bool
+ IsOwner bool
+ NumTeam int
+}
+
+// GetOrgUsersByUserId returns all organization-user relations by user ID.
+func GetOrgUsersByUserId(uid int64) ([]*OrgUser, error) {
+ ous := make([]*OrgUser, 0, 10)
+ err := x.Where("uid=?", uid).Find(&ous)
+ return ous, err
+}
+
+// GetOrgUsersByOrgId returns all organization-user relations by organization ID.
+func GetOrgUsersByOrgId(orgId int64) ([]*OrgUser, error) {
+ ous := make([]*OrgUser, 0, 10)
+ err := x.Where("org_id=?", orgId).Find(&ous)
+ return ous, err
+}
+
+func GetOrganizationCount(u *User) (int64, error) {
+ return x.Where("uid=?", u.Id).Count(new(OrgUser))
+}
+
+// ___________ ____ ___
+// \__ ___/___ _____ _____ | | \______ ___________
+// | |_/ __ \\__ \ / \| | / ___// __ \_ __ \
+// | |\ ___/ / __ \| Y Y \ | /\___ \\ ___/| | \/
+// |____| \___ >____ /__|_| /______//____ >\___ >__|
+// \/ \/ \/ \/ \/
+
+// TeamUser represents an team-user relation.
+type TeamUser struct {
+ Id int64
+ Uid int64
+ OrgId int64 `xorm:"INDEX"`
+ TeamId int64
+}
+
+// GetTeamMembers returns all members in given team of organization.
+func GetTeamMembers(orgId, teamId int64) ([]*User, error) {
+ tus := make([]*TeamUser, 0, 10)
+ err := x.Where("org_id=?", orgId).And("team_id=?", teamId).Find(&tus)
+ if err != nil {
+ return nil, err
+ }
+
+ us := make([]*User, len(tus))
+ for i, tu := range tus {
+ us[i], err = GetUserById(tu.Uid)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return us, nil
+}
diff --git a/models/repo.go b/models/repo.go
index 4ccaccbf81..85f2a913d3 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -158,7 +158,7 @@ func IsRepositoryExist(u *User, repoName string) (bool, error) {
}
var (
- illegalEquals = []string{"raw", "install", "api", "avatar", "user", "help", "stars", "issues", "pulls", "commits", "repo", "template", "admin"}
+ illegalEquals = []string{"raw", "install", "api", "avatar", "user", "org", "help", "stars", "issues", "pulls", "commits", "repo", "template", "admin"}
illegalSuffixs = []string{".git"}
)
@@ -240,7 +240,7 @@ func MirrorUpdate() {
"git", "remote", "update"); err != nil {
return errors.New("git remote update: " + stderr)
} else if err = git.UnpackRefs(repoPath); err != nil {
- return err
+ return errors.New("UnpackRefs: " + err.Error())
}
m.NextUpdate = time.Now().Add(time.Duration(m.Interval) * time.Hour)
@@ -251,8 +251,8 @@ func MirrorUpdate() {
}
// MigrateRepository migrates a existing repository from other project hosting.
-func MigrateRepository(user *User, name, desc string, private, mirror bool, url string) (*Repository, error) {
- repo, err := CreateRepository(user, name, desc, "", "", private, mirror, false)
+func MigrateRepository(u *User, name, desc string, private, mirror bool, url string) (*Repository, error) {
+ repo, err := CreateRepository(u, name, desc, "", "", private, mirror, false)
if err != nil {
return nil, err
}
@@ -261,11 +261,11 @@ func MigrateRepository(user *User, name, desc string, private, mirror bool, url
tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().Nanosecond()))
os.MkdirAll(tmpDir, os.ModePerm)
- repoPath := RepoPath(user.Name, name)
+ repoPath := RepoPath(u.Name, name)
repo.IsBare = false
if mirror {
- if err = MirrorRepository(repo.Id, user.Name, repo.Name, repoPath, url); err != nil {
+ if err = MirrorRepository(repo.Id, u.Name, repo.Name, repoPath, url); err != nil {
return repo, err
}
repo.IsMirror = true
@@ -454,21 +454,28 @@ func initRepository(f string, user *User, repo *Repository, initReadme bool, rep
return initRepoCommit(tmpDir, user.NewGitSig())
}
-// CreateRepository creates a repository for given user or orgnaziation.
-func CreateRepository(user *User, name, desc, lang, license string, private, mirror, initReadme bool) (*Repository, error) {
+// CreateRepository creates a repository for given user or organization.
+func CreateRepository(u *User, name, desc, lang, license string, private, mirror, initReadme bool) (*Repository, error) {
if !IsLegalName(name) {
return nil, ErrRepoNameIllegal
}
- isExist, err := IsRepositoryExist(user, name)
+ isExist, err := IsRepositoryExist(u, name)
if err != nil {
return nil, err
} else if isExist {
return nil, ErrRepoAlreadyExist
}
+ sess := x.NewSession()
+ defer sess.Close()
+ if err = sess.Begin(); err != nil {
+ return nil, err
+ }
+
repo := &Repository{
- OwnerId: user.Id,
+ OwnerId: u.Id,
+ Owner: u,
Name: name,
LowerName: strings.ToLower(name),
Description: desc,
@@ -479,67 +486,85 @@ func CreateRepository(user *User, name, desc, lang, license string, private, mir
repo.DefaultBranch = "master"
}
- repoPath := RepoPath(user.Name, repo.Name)
-
- sess := x.NewSession()
- defer sess.Close()
- sess.Begin()
-
if _, err = sess.Insert(repo); err != nil {
- if err2 := os.RemoveAll(repoPath); err2 != nil {
- log.Error("repo.CreateRepository(repo): %v", err)
- return nil, errors.New(fmt.Sprintf(
- "delete repo directory %s/%s failed(1): %v", user.Name, repo.Name, err2))
- }
sess.Rollback()
return nil, err
}
- mode := AU_WRITABLE
+ var t *Team // Owner team.
+
+ mode := WRITABLE
if mirror {
- mode = AU_READABLE
+ mode = READABLE
}
- access := Access{
- UserName: user.LowerName,
- RepoName: strings.ToLower(path.Join(user.Name, repo.Name)),
+ access := &Access{
+ UserName: u.LowerName,
+ RepoName: strings.ToLower(path.Join(u.Name, repo.Name)),
Mode: mode,
}
- if _, err = sess.Insert(&access); err != nil {
- sess.Rollback()
- if err2 := os.RemoveAll(repoPath); err2 != nil {
- log.Error("repo.CreateRepository(access): %v", err)
- return nil, errors.New(fmt.Sprintf(
- "delete repo directory %s/%s failed(2): %v", user.Name, repo.Name, err2))
+ // Give access to all members in owner team.
+ if u.IsOrganization() {
+ t, err = u.GetOwnerTeam()
+ if err != nil {
+ sess.Rollback()
+ return nil, err
+ }
+ us, err := GetTeamMembers(u.Id, t.Id)
+ if err != nil {
+ sess.Rollback()
+ return nil, err
+ }
+ for _, u := range us {
+ access.UserName = u.LowerName
+ if _, err = sess.Insert(access); err != nil {
+ sess.Rollback()
+ return nil, err
+ }
+ }
+ } else {
+ if _, err = sess.Insert(access); err != nil {
+ sess.Rollback()
+ return nil, err
}
- return nil, err
}
rawSql := "UPDATE `user` SET num_repos = num_repos + 1 WHERE id = ?"
- if _, err = sess.Exec(rawSql, user.Id); err != nil {
+ if _, err = sess.Exec(rawSql, u.Id); err != nil {
sess.Rollback()
- if err2 := os.RemoveAll(repoPath); err2 != nil {
- log.Error("repo.CreateRepository(repo count): %v", err)
- return nil, errors.New(fmt.Sprintf(
- "delete repo directory %s/%s failed(3): %v", user.Name, repo.Name, err2))
- }
return nil, err
}
- if err = sess.Commit(); err != nil {
- sess.Rollback()
- if err2 := os.RemoveAll(repoPath); err2 != nil {
- log.Error("repo.CreateRepository(commit): %v", err)
- return nil, errors.New(fmt.Sprintf(
- "delete repo directory %s/%s failed(3): %v", user.Name, repo.Name, err2))
+ // Update owner team info and count.
+ if u.IsOrganization() {
+ t.RepoIds += "$" + base.ToStr(repo.Id) + "|"
+ t.NumRepos++
+ if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil {
+ sess.Rollback()
+ return nil, err
}
+ }
+
+ if err = sess.Commit(); err != nil {
return nil, err
}
- if err = WatchRepo(user.Id, repo.Id, true); err != nil {
- log.Error("repo.CreateRepository(WatchRepo): %v", err)
+ if u.IsOrganization() {
+ ous, err := GetOrgUsersByOrgId(u.Id)
+ if err != nil {
+ log.Error("repo.CreateRepository(GetOrgUsersByOrgId): %v", err)
+ } else {
+ for _, ou := range ous {
+ if err = WatchRepo(ou.Uid, repo.Id, true); err != nil {
+ log.Error("repo.CreateRepository(WatchRepo): %v", err)
+ }
+ }
+ }
+ }
+ if err = WatchRepo(u.Id, repo.Id, true); err != nil {
+ log.Error("repo.CreateRepository(WatchRepo2): %v", err)
}
- if err = NewRepoAction(user, repo); err != nil {
+ if err = NewRepoAction(u, repo); err != nil {
log.Error("repo.CreateRepository(NewRepoAction): %v", err)
}
@@ -548,7 +573,13 @@ func CreateRepository(user *User, name, desc, lang, license string, private, mir
return repo, nil
}
- if err = initRepository(repoPath, user, repo, initReadme, lang, license); err != nil {
+ repoPath := RepoPath(u.Name, repo.Name)
+ if err = initRepository(repoPath, u, repo, initReadme, lang, license); err != nil {
+ if err2 := os.RemoveAll(repoPath); err2 != nil {
+ log.Error("repo.CreateRepository(initRepository): %v", err)
+ return nil, errors.New(fmt.Sprintf(
+ "delete repo directory %s/%s failed(2): %v", u.Name, repo.Name, err2))
+ }
return nil, err
}
diff --git a/models/update.go b/models/update.go
index 188e6cb9c7..0231b6af38 100644
--- a/models/update.go
+++ b/models/update.go
@@ -6,6 +6,7 @@ package models
import (
"container/list"
+ "fmt"
"os/exec"
"strings"
@@ -15,13 +16,13 @@ import (
"github.com/gogits/gogs/modules/log"
)
-func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName string, userId int64) {
+func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName string, userId int64) error {
//fmt.Println(refName, oldCommitId, newCommitId)
//fmt.Println(userName, repoUserName, repoName)
isNew := strings.HasPrefix(oldCommitId, "0000000")
if isNew &&
strings.HasPrefix(newCommitId, "0000000") {
- log.GitLogger.Fatal("old rev and new rev both 000000")
+ return fmt.Errorf("old rev and new rev both 000000")
}
f := RepoPath(repoUserName, repoName)
@@ -33,18 +34,17 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName
isDel := strings.HasPrefix(newCommitId, "0000000")
if isDel {
log.GitLogger.Info("del rev", refName, "from", userName+"/"+repoName+".git", "by", userId)
- return
+ return nil
}
repo, err := git.OpenRepository(f)
if err != nil {
- log.GitLogger.Fatal("runUpdate.Open repoId: %v", err)
+ return fmt.Errorf("runUpdate.Open repoId: %v", err)
}
newCommit, err := repo.GetCommit(newCommitId)
if err != nil {
- log.GitLogger.Fatal("runUpdate GetCommit of newCommitId: %v", err)
- return
+ return fmt.Errorf("runUpdate GetCommit of newCommitId: %v", err)
}
var l *list.List
@@ -52,28 +52,27 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName
if isNew {
l, err = newCommit.CommitsBefore()
if err != nil {
- log.GitLogger.Fatal("Find CommitsBefore erro: %v", err)
+ return fmt.Errorf("Find CommitsBefore erro: %v", err)
}
} else {
l, err = newCommit.CommitsBeforeUntil(oldCommitId)
if err != nil {
- log.GitLogger.Fatal("Find CommitsBeforeUntil erro: %v", err)
- return
+ return fmt.Errorf("Find CommitsBeforeUntil erro: %v", err)
}
}
if err != nil {
- log.GitLogger.Fatal("runUpdate.Commit repoId: %v", err)
+ return fmt.Errorf("runUpdate.Commit repoId: %v", err)
}
ru, err := GetUserByName(repoUserName)
if err != nil {
- log.GitLogger.Fatal("runUpdate.GetUserByName: %v", err)
+ return fmt.Errorf("runUpdate.GetUserByName: %v", err)
}
repos, err := GetRepositoryByName(ru.Id, repoName)
if err != nil {
- log.GitLogger.Fatal("runUpdate.GetRepositoryByName userId: %v", err)
+ return fmt.Errorf("runUpdate.GetRepositoryByName userId: %v", err)
}
// if tags push
@@ -104,6 +103,7 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName
return
}
+ // if commits push
commits := make([]*base.PushCommit, 0)
var maxCommits = 3
var actEmail string
@@ -126,6 +126,7 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName
//commits = append(commits, []string{lastCommit.Id().String(), lastCommit.Message()})
if err = CommitRepoAction(userId, ru.Id, userName, actEmail,
repos.Id, repoUserName, repoName, refName, &base.PushCommits{l.Len(), commits}); err != nil {
- log.GitLogger.Fatal("runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err)
+ return fmt.Errorf("runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err)
}
+ return nil
}
diff --git a/models/user.go b/models/user.go
index 50d81c942d..8ffad26632 100644
--- a/models/user.go
+++ b/models/user.go
@@ -21,14 +21,16 @@ import (
"github.com/gogits/gogs/modules/setting"
)
-// User types.
+type UserType int
+
const (
- UT_INDIVIDUAL = iota + 1
- UT_ORGANIZATION
+ INDIVIDUAL UserType = iota // Historic reason to make it starts at 0.
+ ORGANIZATION
)
var (
ErrUserOwnRepos = errors.New("User still have ownership of repositories")
+ ErrUserHasOrgs = errors.New("User still have membership of organization")
ErrUserAlreadyExist = errors.New("User already exist")
ErrUserNotExist = errors.New("User does not exist")
ErrUserNotKeyOwner = errors.New("User does not the owner of public key")
@@ -50,7 +52,8 @@ type User struct {
LoginType LoginType
LoginSource int64 `xorm:"not null default 0"`
LoginName string
- Type int
+ Type UserType
+ Orgs []*User `xorm:"-"`
NumFollowers int
NumFollowings int
NumStars int
@@ -65,43 +68,71 @@ type User struct {
Salt string `xorm:"VARCHAR(10)"`
Created time.Time `xorm:"created"`
Updated time.Time `xorm:"updated"`
+
+ // For organization.
+ Description string
+ NumTeams int
+ NumMembers int
}
// HomeLink returns the user home page link.
-func (user *User) HomeLink() string {
- return "/user/" + user.Name
+func (u *User) HomeLink() string {
+ return "/user/" + u.Name
}
// AvatarLink returns user gravatar link.
-func (user *User) AvatarLink() string {
+func (u *User) AvatarLink() string {
if setting.DisableGravatar {
return "/img/avatar_default.jpg"
} else if setting.Service.EnableCacheAvatar {
- return "/avatar/" + user.Avatar
+ return "/avatar/" + u.Avatar
}
- return "//1.gravatar.com/avatar/" + user.Avatar
+ return "//1.gravatar.com/avatar/" + u.Avatar
}
// NewGitSig generates and returns the signature of given user.
-func (user *User) NewGitSig() *git.Signature {
+func (u *User) NewGitSig() *git.Signature {
return &git.Signature{
- Name: user.Name,
- Email: user.Email,
+ Name: u.Name,
+ Email: u.Email,
When: time.Now(),
}
}
// EncodePasswd encodes password to safe format.
-func (user *User) EncodePasswd() {
- newPasswd := base.PBKDF2([]byte(user.Passwd), []byte(user.Salt), 10000, 50, sha256.New)
- user.Passwd = fmt.Sprintf("%x", newPasswd)
+func (u *User) EncodePasswd() {
+ newPasswd := base.PBKDF2([]byte(u.Passwd), []byte(u.Salt), 10000, 50, sha256.New)
+ u.Passwd = fmt.Sprintf("%x", newPasswd)
}
-// Member represents user is member of organization.
-type Member struct {
- Id int64
- OrgId int64 `xorm:"unique(member) index"`
- UserId int64 `xorm:"unique(member)"`
+func (u *User) IsOrganization() bool {
+ return u.Type == ORGANIZATION
+}
+
+func (u *User) GetOrganizations() error {
+ ous, err := GetOrgUsersByUserId(u.Id)
+ if err != nil {
+ return err
+ }
+
+ u.Orgs = make([]*User, len(ous))
+ for i, ou := range ous {
+ u.Orgs[i], err = GetUserById(ou.OrgId)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// GetOwnerTeam returns owner team of organization.
+func (org *User) GetOwnerTeam() (*Team, error) {
+ t := &Team{
+ OrgId: org.Id,
+ Name: OWNER_TEAM,
+ }
+ _, err := x.Get(t)
+ return t, err
}
// IsUserExist checks if given user name exist,
@@ -126,49 +157,60 @@ func GetUserSalt() string {
return base.GetRandomString(10)
}
-// RegisterUser creates record of a new user.
-func RegisterUser(user *User) (*User, error) {
-
- if !IsLegalName(user.Name) {
+// CreateUser creates record of a new user.
+func CreateUser(u *User) (*User, error) {
+ if !IsLegalName(u.Name) {
return nil, ErrUserNameIllegal
}
- isExist, err := IsUserExist(user.Name)
+ isExist, err := IsUserExist(u.Name)
if err != nil {
return nil, err
} else if isExist {
return nil, ErrUserAlreadyExist
}
- isExist, err = IsEmailUsed(user.Email)
+ isExist, err = IsEmailUsed(u.Email)
if err != nil {
return nil, err
} else if isExist {
return nil, ErrEmailAlreadyUsed
}
- user.LowerName = strings.ToLower(user.Name)
- user.Avatar = base.EncodeMd5(user.Email)
- user.AvatarEmail = user.Email
- user.Rands = GetUserSalt()
- user.Salt = GetUserSalt()
- user.EncodePasswd()
- if _, err = x.Insert(user); err != nil {
+ u.LowerName = strings.ToLower(u.Name)
+ u.Avatar = base.EncodeMd5(u.Email)
+ u.AvatarEmail = u.Email
+ u.Rands = GetUserSalt()
+ u.Salt = GetUserSalt()
+ u.EncodePasswd()
+
+ sess := x.NewSession()
+ defer sess.Close()
+ if err = sess.Begin(); err != nil {
+ return nil, err
+ }
+
+ if _, err = sess.Insert(u); err != nil {
+ sess.Rollback()
return nil, err
- } else if err = os.MkdirAll(UserPath(user.Name), os.ModePerm); err != nil {
- if _, err := x.Id(user.Id).Delete(&User{}); err != nil {
- return nil, errors.New(fmt.Sprintf(
- "both create userpath %s and delete table record faild: %v", user.Name, err))
- }
+ }
+
+ if err = os.MkdirAll(UserPath(u.Name), os.ModePerm); err != nil {
+ sess.Rollback()
return nil, err
}
- if user.Id == 1 {
- user.IsAdmin = true
- user.IsActive = true
- _, err = x.Id(user.Id).UseBool().Update(user)
+ if err = sess.Commit(); err != nil {
+ return nil, err
}
- return user, err
+
+ // Auto-set admin for user whose ID is 1.
+ if u.Id == 1 {
+ u.IsAdmin = true
+ u.IsActive = true
+ _, err = x.Id(u.Id).UseBool().Update(u)
+ }
+ return u, err
}
// GetUsers returns given number of user objects with offset.
@@ -277,51 +319,62 @@ func UpdateUser(u *User) (err error) {
if len(u.Website) > 255 {
u.Website = u.Website[:255]
}
+ if len(u.Description) > 255 {
+ u.Description = u.Description[:255]
+ }
_, err = x.Id(u.Id).AllCols().Update(u)
return err
}
// DeleteUser completely deletes everything of the user.
-func DeleteUser(user *User) error {
+func DeleteUser(u *User) error {
// Check ownership of repository.
- count, err := GetRepositoryCount(user)
+ count, err := GetRepositoryCount(u)
if err != nil {
- return errors.New("modesl.GetRepositories: " + err.Error())
+ return errors.New("modesl.GetRepositories(GetRepositoryCount): " + err.Error())
} else if count > 0 {
return ErrUserOwnRepos
}
+ // Check membership of organization.
+ count, err = GetOrganizationCount(u)
+ if err != nil {
+ return errors.New("modesl.GetRepositories(GetOrganizationCount): " + err.Error())
+ } else if count > 0 {
+ return ErrUserHasOrgs
+ }
+
// TODO: check issues, other repos' commits
// Delete all followers.
- if _, err = x.Delete(&Follow{FollowId: user.Id}); err != nil {
+ if _, err = x.Delete(&Follow{FollowId: u.Id}); err != nil {
return err
}
// Delete oauth2.
- if _, err = x.Delete(&Oauth2{Uid: user.Id}); err != nil {
+ if _, err = x.Delete(&Oauth2{Uid: u.Id}); err != nil {
return err
}
// Delete all feeds.
- if _, err = x.Delete(&Action{UserId: user.Id}); err != nil {
+ if _, err = x.Delete(&Action{UserId: u.Id}); err != nil {
return err
}
// Delete all watches.
- if _, err = x.Delete(&Watch{UserId: user.Id}); err != nil {
+ if _, err = x.Delete(&Watch{UserId: u.Id}); err != nil {
return err
}
// Delete all accesses.
- if _, err = x.Delete(&Access{UserName: user.LowerName}); err != nil {
+ if _, err = x.Delete(&Access{UserName: u.LowerName}); err != nil {
return err
}
// Delete all SSH keys.
keys := make([]*PublicKey, 0, 10)
- if err = x.Find(&keys, &PublicKey{OwnerId: user.Id}); err != nil {
+ if err = x.Find(&keys, &PublicKey{OwnerId: u.Id}); err != nil {
return err
}
for _, key := range keys {
@@ -331,11 +384,11 @@ func DeleteUser(user *User) error {
}
// Delete user directory.
- if err = os.RemoveAll(UserPath(user.Name)); err != nil {
+ if err = os.RemoveAll(UserPath(u.Name)); err != nil {
return err
}
- _, err = x.Delete(user)
+ _, err = x.Delete(u)
return err
}