From 4a6c56d2fdca7f3f7cbc6d03a6809796c0b5a56e Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 20 Mar 2014 09:49:06 -0400 Subject: Bug fix --- gogs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gogs.go') diff --git a/gogs.go b/gogs.go index 385b7421..d32e3908 100644 --- a/gogs.go +++ b/gogs.go @@ -20,7 +20,7 @@ import ( // Test that go1.1 tag above is included in builds. main.go refers to this definition. const go11tag = true -const APP_VER = "0.1.1.0320.1" +const APP_VER = "0.1.2.0320.1" func init() { base.AppVer = APP_VER -- cgit v1.2.3 From 3b387336bfc097090d5b03f5b01e136bca56f8fd Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 20 Mar 2014 11:41:24 -0400 Subject: Add Repository/user name filter --- README.md | 2 +- gogs.go | 2 +- models/repo.go | 31 +++++++++++++++++++++++++++++++ models/user.go | 5 +++++ routers/repo/repo.go | 3 +++ routers/repo/single.go | 5 +++++ routers/user/user.go | 8 +++++--- 7 files changed, 51 insertions(+), 5 deletions(-) (limited to 'gogs.go') diff --git a/README.md b/README.md index 3a1023c6..4219e4ed 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Gogs(Go Git Service) is a GitHub-like clone in the Go Programming Language. Since we choose to use pure Go implementation of Git manipulation, Gogs certainly supports **ALL platforms** that Go supports, including Linux, Max OS X, and Windows with **ZERO** dependency. -##### Current version: 0.1.1 Alpha +##### Current version: 0.1.4 Alpha ## Purpose diff --git a/gogs.go b/gogs.go index d32e3908..a600c53d 100644 --- a/gogs.go +++ b/gogs.go @@ -20,7 +20,7 @@ import ( // Test that go1.1 tag above is included in builds. main.go refers to this definition. const go11tag = true -const APP_VER = "0.1.2.0320.1" +const APP_VER = "0.1.3.0320.1" func init() { base.AppVer = APP_VER diff --git a/models/repo.go b/models/repo.go index 052341ff..bcbc5867 100644 --- a/models/repo.go +++ b/models/repo.go @@ -12,6 +12,7 @@ import ( "os" "path" "path/filepath" + "regexp" "strings" "sync" "time" @@ -82,6 +83,7 @@ var ( ErrRepoAlreadyExist = errors.New("Repository already exist") ErrRepoNotExist = errors.New("Repository does not exist") ErrRepoFileNotExist = errors.New("Target Repo file does not exist") + ErrRepoNameIllegal = errors.New("Repository name contains illegal characters") ) func init() { @@ -104,6 +106,15 @@ func init() { os.Exit(2) } } + + // Initialize illegal patterns. + for i := range illegalPatterns[1:] { + pattern := "" + for j := range illegalPatterns[i+1] { + pattern += "[" + string(illegalPatterns[i+1][j]-32) + string(illegalPatterns[i+1][j]) + "]" + } + illegalPatterns[i+1] = pattern + } } // IsRepositoryExist returns true if the repository with given name under user has already existed. @@ -120,8 +131,28 @@ func IsRepositoryExist(user *User, repoName string) (bool, error) { return s.IsDir(), nil } +var ( + // Define as all lower case!! + illegalPatterns = []string{"[.][Gg][Ii][Tt]", "user", "help", "stars", "issues", "pulls", "commits", "admin", "repo", "template"} +) + +// IsLegalName returns false if name contains illegal characters. +func IsLegalName(repoName string) bool { + for _, pattern := range illegalPatterns { + has, _ := regexp.MatchString(pattern, repoName) + if has { + return false + } + } + return true +} + // CreateRepository creates a repository for given user or orgnaziation. func CreateRepository(user *User, repoName, desc, repoLang, license string, private bool, initReadme bool) (*Repository, error) { + if !IsLegalName(repoName) { + return nil, ErrRepoNameIllegal + } + isExist, err := IsRepositoryExist(user, repoName) if err != nil { return nil, err diff --git a/models/user.go b/models/user.go index fd89af6b..990e1954 100644 --- a/models/user.go +++ b/models/user.go @@ -79,6 +79,7 @@ var ( ErrUserAlreadyExist = errors.New("User already exist") ErrUserNotExist = errors.New("User does not exist") ErrEmailAlreadyUsed = errors.New("E-mail already used") + ErrUserNameIllegal = errors.New("User name contains illegal characters") ) // IsUserExist checks if given user name exist, @@ -108,6 +109,10 @@ func GetUserSalt() string { // RegisterUser creates record of a new user. func RegisterUser(user *User) (*User, error) { + if !IsLegalName(user.Name) { + return nil, ErrUserNameIllegal + } + isExist, err := IsUserExist(user.Name) if err != nil { return nil, err diff --git a/routers/repo/repo.go b/routers/repo/repo.go index 556cc434..c83a6df5 100644 --- a/routers/repo/repo.go +++ b/routers/repo/repo.go @@ -31,6 +31,9 @@ func Create(ctx *middleware.Context, form auth.CreateRepoForm) { } else if err == models.ErrRepoAlreadyExist { ctx.RenderWithErr("Repository name has already been used", "repo/create", &form) return + } else if err == models.ErrRepoNameIllegal { + ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), "repo/create", &form) + return } ctx.Handle(200, "repo.Create", err) } diff --git a/routers/repo/single.go b/routers/repo/single.go index f1b15cce..eab49be9 100644 --- a/routers/repo/single.go +++ b/routers/repo/single.go @@ -217,6 +217,11 @@ func Setting(ctx *middleware.Context, params martini.Params) { title = t } + if len(params["branchname"]) == 0 { + params["branchname"] = "master" + } + + ctx.Data["Branchname"] = params["branchname"] ctx.Data["Title"] = title + " - settings" ctx.HTML(200, "repo/setting") } diff --git a/routers/user/user.go b/routers/user/user.go index be2c4d38..ea692259 100644 --- a/routers/user/user.go +++ b/routers/user/user.go @@ -139,11 +139,13 @@ func SignUp(ctx *middleware.Context, form auth.RegisterForm) { var err error if u, err = models.RegisterUser(u); err != nil { - switch err.Error() { - case models.ErrUserAlreadyExist.Error(): + switch err { + case models.ErrUserAlreadyExist: ctx.RenderWithErr("Username has been already taken", "user/signup", &form) - case models.ErrEmailAlreadyUsed.Error(): + case models.ErrEmailAlreadyUsed: ctx.RenderWithErr("E-mail address has been already used", "user/signup", &form) + case models.ErrUserNameIllegal: + ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), "user/signup", &form) default: ctx.Handle(200, "user.SignUp", err) } -- cgit v1.2.3 From 06631ab91f5d84b48d6f71ac8eaf4df740ba0282 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 20 Mar 2014 16:04:56 -0400 Subject: Basic admin data table, models changes --- README.md | 2 +- gogs.go | 8 +- models/issue.go | 19 ++++ models/models.go | 56 ++++------- models/publickey.go | 10 +- models/repo.go | 216 +++++++++++++++++++++-------------------- models/user.go | 97 +++++++++--------- modules/base/conf.go | 21 ++-- routers/admin/admin.go | 15 +++ serve.go | 4 +- templates/admin/dashboard.tmpl | 2 +- templates/admin/repos.tmpl | 24 +++++ templates/admin/users.tmpl | 26 +++++ 13 files changed, 291 insertions(+), 209 deletions(-) create mode 100644 models/issue.go (limited to 'gogs.go') diff --git a/README.md b/README.md index 4219e4ed..8c971fdb 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ There are some very good products in this category such as [gitlab](http://gitla - Please see [Wiki](https://github.com/gogits/gogs/wiki) for project design, develop specification, change log and road map. - See [Trello Broad](https://trello.com/b/uxAoeLUl/gogs-go-git-service) to follow the develop team. -- Try it before anything? Go down to **Installation -> Install from binary** section!. +- Try it before anything? Do it [online](http://try.gogits.org/Unknown/gogs) or go down to **Installation -> Install from binary** section! - Having troubles? Get help from [Troubleshooting](https://github.com/gogits/gogs/wiki/Troubleshooting). ## Features diff --git a/gogs.go b/gogs.go index a600c53d..a9f7e6b5 100644 --- a/gogs.go +++ b/gogs.go @@ -15,12 +15,12 @@ import ( "github.com/gogits/gogs/modules/base" ) -// +build go1.1 +// +build go1.2 -// Test that go1.1 tag above is included in builds. main.go refers to this definition. -const go11tag = true +// Test that go1.2 tag above is included in builds. main.go refers to this definition. +const go12tag = true -const APP_VER = "0.1.3.0320.1" +const APP_VER = "0.1.4.0321" func init() { base.AppVer = APP_VER diff --git a/models/issue.go b/models/issue.go new file mode 100644 index 00000000..c669d201 --- /dev/null +++ b/models/issue.go @@ -0,0 +1,19 @@ +// 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 + +type Issue struct { + Id int64 + RepoId int64 `xorm:"index"` + PosterId int64 +} + +type PullRequest struct { + Id int64 +} + +type Comment struct { + Id int64 +} diff --git a/models/models.go b/models/models.go index 2e0bb759..214d1c76 100644 --- a/models/models.go +++ b/models/models.go @@ -15,30 +15,7 @@ import ( "github.com/gogits/gogs/modules/base" ) -var ( - orm *xorm.Engine - RepoRootPath string -) - -type Members struct { - Id int64 - OrgId int64 `xorm:"unique(s) index"` - UserId int64 `xorm:"unique(s)"` -} - -type Issue struct { - Id int64 - RepoId int64 `xorm:"index"` - PosterId int64 -} - -type PullRequest struct { - Id int64 -} - -type Comment struct { - Id int64 -} +var orm *xorm.Engine func setEngine() { dbType := base.Cfg.MustValue("database", "DB_TYPE") @@ -65,8 +42,8 @@ func setEngine() { os.Exit(2) } - // TODO: for serv command, MUST remove the output to os.stdout, so - // use log file to instead print to stdout + // WARNNING: for serv command, MUST remove the output to os.stdout, + // so use log file to instead print to stdout. //x.ShowDebug = true //orm.ShowErr = true @@ -77,20 +54,29 @@ func setEngine() { } orm.Logger = f orm.ShowSQL = true - - // Determine and create root git reposiroty path. - RepoRootPath = base.Cfg.MustValue("repository", "ROOT") - if err = os.MkdirAll(RepoRootPath, os.ModePerm); err != nil { - fmt.Printf("models.init(fail to create RepoRootPath(%s)): %v\n", RepoRootPath, err) - os.Exit(2) - } } func init() { setEngine() - if err := orm.Sync(new(User), new(PublicKey), new(Repository), new(Access), - new(Action), new(Watch)); err != nil { + if err := orm.Sync(new(User), new(PublicKey), new(Repository), new(Watch), + new(Action), new(Access)); err != nil { fmt.Printf("sync database struct error: %v\n", err) os.Exit(2) } } + +type Statistic struct { + Counter struct { + User, PublicKey, Repo, Watch, Action, Access int64 + } +} + +func GetStatistic() (stats Statistic) { + stats.Counter.User, _ = orm.Count(new(User)) + stats.Counter.PublicKey, _ = orm.Count(new(PublicKey)) + stats.Counter.Repo, _ = orm.Count(new(Repository)) + stats.Counter.Watch, _ = orm.Count(new(Watch)) + stats.Counter.Action, _ = orm.Count(new(Action)) + stats.Counter.Access, _ = orm.Count(new(Access)) + return stats +} diff --git a/models/publickey.go b/models/publickey.go index 092436d5..c69bca68 100644 --- a/models/publickey.go +++ b/models/publickey.go @@ -27,8 +27,12 @@ const ( ) var ( - sshOpLocker = sync.Mutex{} + ErrKeyAlreadyExist = errors.New("Public key already exist") +) +var sshOpLocker = sync.Mutex{} + +var ( sshPath string appPath string ) @@ -79,10 +83,6 @@ type PublicKey struct { Updated time.Time `xorm:"updated"` } -var ( - ErrKeyAlreadyExist = errors.New("Public key already exist") -) - // GenAuthorizedKey returns formatted public key string. func GenAuthorizedKey(keyId int64, key string) string { return fmt.Sprintf(TPL_PUBLICK_KEY+"\n", appPath, keyId, key) diff --git a/models/repo.go b/models/repo.go index bcbc5867..f7173d76 100644 --- a/models/repo.go +++ b/models/repo.go @@ -27,63 +27,18 @@ import ( "github.com/gogits/gogs/modules/log" ) -// Repository represents a git repository. -type Repository struct { - Id int64 - OwnerId int64 `xorm:"unique(s)"` - ForkId int64 - LowerName string `xorm:"unique(s) index not null"` - Name string `xorm:"index not null"` - Description string - Website string - Private bool - NumWatchs int - NumStars int - NumForks int - Created time.Time `xorm:"created"` - Updated time.Time `xorm:"updated"` -} - -// Watch is connection request for receiving repository notifycation. -type Watch struct { - Id int64 - RepoId int64 `xorm:"UNIQUE(watch)"` - UserId int64 `xorm:"UNIQUE(watch)"` -} - -// Watch or unwatch repository. -func WatchRepo(userId, repoId int64, watch bool) (err error) { - if watch { - _, err = orm.Insert(&Watch{RepoId: repoId, UserId: userId}) - } else { - _, err = orm.Delete(&Watch{0, repoId, userId}) - } - return err -} - -// GetWatches returns all watches of given repository. -func GetWatches(repoId int64) ([]Watch, error) { - watches := make([]Watch, 0, 10) - err := orm.Find(&watches, &Watch{RepoId: repoId}) - return watches, err -} - -// IsWatching checks if user has watched given repository. -func IsWatching(userId, repoId int64) bool { - has, _ := orm.Get(&Watch{0, repoId, userId}) - return has -} - var ( - gitInitLocker = sync.Mutex{} - LanguageIgns, Licenses []string + ErrRepoAlreadyExist = errors.New("Repository already exist") + ErrRepoNotExist = errors.New("Repository does not exist") + ErrRepoFileNotExist = errors.New("Target Repo file does not exist") + ErrRepoNameIllegal = errors.New("Repository name contains illegal characters") + ErrRepoFileNotLoaded = fmt.Errorf("repo file not loaded") ) +var gitInitLocker = sync.Mutex{} + var ( - ErrRepoAlreadyExist = errors.New("Repository already exist") - ErrRepoNotExist = errors.New("Repository does not exist") - ErrRepoFileNotExist = errors.New("Target Repo file does not exist") - ErrRepoNameIllegal = errors.New("Repository name contains illegal characters") + LanguageIgns, Licenses []string ) func init() { @@ -117,6 +72,23 @@ func init() { } } +// Repository represents a git repository. +type Repository struct { + Id int64 + OwnerId int64 `xorm:"unique(s)"` + ForkId int64 + LowerName string `xorm:"unique(s) index not null"` + Name string `xorm:"index not null"` + Description string + Website string + Private bool + NumWatches int + NumStars int + NumForks int + Created time.Time `xorm:"created"` + Updated time.Time `xorm:"updated"` +} + // IsRepositoryExist returns true if the repository with given name under user has already existed. func IsRepositoryExist(user *User, repoName string) (bool, error) { repo := Repository{OwnerId: user.Id} @@ -351,6 +323,60 @@ func initRepository(f string, user *User, repo *Repository, initReadme bool, rep return nil } +// GetRepos returns given number of repository objects with offset. +func GetRepos(num, offset int) ([]Repository, error) { + repos := make([]Repository, 0, num) + err := orm.Limit(num, offset).Asc("id").Find(&repos) + return repos, err +} + +func RepoPath(userName, repoName string) string { + return filepath.Join(UserPath(userName), repoName+".git") +} + +// DeleteRepository deletes a repository for a user or orgnaztion. +func DeleteRepository(userId, repoId int64, userName string) (err error) { + repo := &Repository{Id: repoId, OwnerId: userId} + has, err := orm.Get(repo) + if err != nil { + return err + } else if !has { + return ErrRepoNotExist + } + + session := orm.NewSession() + if err = session.Begin(); err != nil { + return err + } + if _, err = session.Delete(&Repository{Id: repoId}); err != nil { + session.Rollback() + return err + } + if _, err := session.Delete(&Access{UserName: userName, RepoName: repo.Name}); err != nil { + session.Rollback() + return err + } + rawSql := "UPDATE `user` SET num_repos = num_repos - 1 WHERE id = ?" + if _, err = session.Exec(rawSql, userId); err != nil { + session.Rollback() + return err + } + if _, err = session.Delete(&Watch{RepoId: repoId}); err != nil { + session.Rollback() + return err + } + if err = session.Commit(); err != nil { + session.Rollback() + return err + } + if err = os.RemoveAll(RepoPath(userName, repo.Name)); err != nil { + // TODO: log and delete manully + log.Error("delete repo %s/%s failed: %v", userName, repo.Name, err) + return err + } + return nil +} + // GetRepositoryByName returns the repository by given name under user if exists. func GetRepositoryByName(user *User, repoName string) (*Repository, error) { repo := &Repository{ @@ -388,6 +414,36 @@ func GetRepositoryCount(user *User) (int64, error) { return orm.Count(&Repository{OwnerId: user.Id}) } +// Watch is connection request for receiving repository notifycation. +type Watch struct { + Id int64 + RepoId int64 `xorm:"UNIQUE(watch)"` + UserId int64 `xorm:"UNIQUE(watch)"` +} + +// Watch or unwatch repository. +func WatchRepo(userId, repoId int64, watch bool) (err error) { + if watch { + _, err = orm.Insert(&Watch{RepoId: repoId, UserId: userId}) + } else { + _, err = orm.Delete(&Watch{0, repoId, userId}) + } + return err +} + +// GetWatches returns all watches of given repository. +func GetWatches(repoId int64) ([]Watch, error) { + watches := make([]Watch, 0, 10) + err := orm.Find(&watches, &Watch{RepoId: repoId}) + return watches, err +} + +// IsWatching checks if user has watched given repository. +func IsWatching(userId, repoId int64) bool { + has, _ := orm.Get(&Watch{0, repoId, userId}) + return has +} + func StarReposiory(user *User, repoName string) error { return nil } @@ -408,60 +464,6 @@ func ForkRepository(reposName string, userId int64) { } -func RepoPath(userName, repoName string) string { - return filepath.Join(UserPath(userName), repoName+".git") -} - -// DeleteRepository deletes a repository for a user or orgnaztion. -func DeleteRepository(userId, repoId int64, userName string) (err error) { - repo := &Repository{Id: repoId, OwnerId: userId} - has, err := orm.Get(repo) - if err != nil { - return err - } else if !has { - return ErrRepoNotExist - } - - session := orm.NewSession() - if err = session.Begin(); err != nil { - return err - } - if _, err = session.Delete(&Repository{Id: repoId}); err != nil { - session.Rollback() - return err - } - if _, err := session.Delete(&Access{UserName: userName, RepoName: repo.Name}); err != nil { - session.Rollback() - return err - } - rawSql := "UPDATE user SET num_repos = num_repos - 1 WHERE id = ?" - if base.Cfg.MustValue("database", "DB_TYPE") == "postgres" { - rawSql = "UPDATE \"user\" SET num_repos = num_repos - 1 WHERE id = ?" - } - if _, err = session.Exec(rawSql, userId); err != nil { - session.Rollback() - return err - } - if _, err = session.Delete(&Watch{RepoId: repoId}); err != nil { - session.Rollback() - return err - } - if err = session.Commit(); err != nil { - session.Rollback() - return err - } - if err = os.RemoveAll(RepoPath(userName, repo.Name)); err != nil { - // TODO: log and delete manully - log.Error("delete repo %s/%s failed: %v", userName, repo.Name, err) - return err - } - return nil -} - -var ( - ErrRepoFileNotLoaded = fmt.Errorf("repo file not loaded") -) - // RepoFile represents a file object in git repository. type RepoFile struct { *git.TreeEntry diff --git a/models/user.go b/models/user.go index 990e1954..3c110912 100644 --- a/models/user.go +++ b/models/user.go @@ -33,6 +33,14 @@ const ( LT_LDAP ) +var ( + ErrUserOwnRepos = errors.New("User still have ownership of repositories") + ErrUserAlreadyExist = errors.New("User already exist") + ErrUserNotExist = errors.New("User does not exist") + ErrEmailAlreadyUsed = errors.New("E-mail already used") + ErrUserNameIllegal = errors.New("User name contains illegal characters") +) + // User represents the object of individual and member of organization. type User struct { Id int64 @@ -67,20 +75,28 @@ func (user *User) AvatarLink() string { return "http://1.gravatar.com/avatar/" + user.Avatar } -type Follow struct { - Id int64 - UserId int64 `xorm:"unique(s)"` - FollowId int64 `xorm:"unique(s)"` - Created time.Time `xorm:"created"` +// NewGitSig generates and returns the signature of given user. +func (user *User) NewGitSig() *git.Signature { + return &git.Signature{ + Name: user.Name, + Email: user.Email, + When: time.Now(), + } } -var ( - ErrUserOwnRepos = errors.New("User still have ownership of repositories") - ErrUserAlreadyExist = errors.New("User already exist") - ErrUserNotExist = errors.New("User does not exist") - ErrEmailAlreadyUsed = errors.New("E-mail already used") - ErrUserNameIllegal = errors.New("User name contains illegal characters") -) +// EncodePasswd encodes password to safe format. +func (user *User) EncodePasswd() error { + newPasswd, err := scrypt.Key([]byte(user.Passwd), []byte(base.SecretKey), 16384, 8, 1, 64) + user.Passwd = fmt.Sprintf("%x", newPasswd) + return err +} + +// Member represents user is member of organization. +type Member struct { + Id int64 + OrgId int64 `xorm:"unique(member) index"` + UserId int64 `xorm:"unique(member)"` +} // IsUserExist checks if given user name exist, // the user name should be noncased unique. @@ -93,15 +109,6 @@ func IsEmailUsed(email string) (bool, error) { return orm.Get(&User{Email: email}) } -// NewGitSig generates and returns the signature of given user. -func (user *User) NewGitSig() *git.Signature { - return &git.Signature{ - Name: user.Name, - Email: user.Email, - When: time.Now(), - } -} - // return a user salt token func GetUserSalt() string { return base.GetRandomString(10) @@ -151,6 +158,13 @@ func RegisterUser(user *User) (*User, error) { return user, err } +// GetUsers returns given number of user objects with offset. +func GetUsers(num, offset int) ([]User, error) { + users := make([]User, 0, num) + err := orm.Limit(num, offset).Asc("id").Find(&users) + return users, err +} + // get user by erify code func getVerifyUser(code string) (user *User) { if len(code) <= base.TimeLimitCodeLength { @@ -229,24 +243,14 @@ func DeleteUser(user *User) error { return err } -// EncodePasswd encodes password to safe format. -func (user *User) EncodePasswd() error { - newPasswd, err := scrypt.Key([]byte(user.Passwd), []byte(base.SecretKey), 16384, 8, 1, 64) - user.Passwd = fmt.Sprintf("%x", newPasswd) - return err -} - // UserPath returns the path absolute path of user repositories. func UserPath(userName string) string { - return filepath.Join(RepoRootPath, strings.ToLower(userName)) + return filepath.Join(base.RepoRootPath, strings.ToLower(userName)) } func GetUserByKeyId(keyId int64) (*User, error) { user := new(User) - rawSql := "SELECT a.* FROM user AS a, public_key AS b WHERE a.id = b.owner_id AND b.id=?" - if base.Cfg.MustValue("database", "DB_TYPE") == "postgres" { - rawSql = "SELECT a.* FROM \"user\" AS a, public_key AS b WHERE a.id = b.owner_id AND b.id=?" - } + rawSql := "SELECT a.* FROM `user` AS a, public_key AS b WHERE a.id = b.owner_id AND b.id=?" has, err := orm.Sql(rawSql, keyId).Get(user) if err != nil { return nil, err @@ -303,6 +307,13 @@ func LoginUserPlain(name, passwd string) (*User, error) { return &user, err } +// Follow is connection request for receiving user notifycation. +type Follow struct { + Id int64 + UserId int64 `xorm:"unique(follow)"` + FollowId int64 `xorm:"unique(follow)"` +} + // FollowUser marks someone be another's follower. func FollowUser(userId int64, followId int64) (err error) { session := orm.NewSession() @@ -314,19 +325,13 @@ func FollowUser(userId int64, followId int64) (err error) { return err } - rawSql := "UPDATE user SET num_followers = num_followers + 1 WHERE id = ?" - if base.Cfg.MustValue("database", "DB_TYPE") == "postgres" { - rawSql = "UPDATE \"user\" SET num_followers = num_followers + 1 WHERE id = ?" - } + rawSql := "UPDATE `user` SET num_followers = num_followers + 1 WHERE id = ?" if _, err = session.Exec(rawSql, followId); err != nil { session.Rollback() return err } - rawSql = "UPDATE user SET num_followings = num_followings + 1 WHERE id = ?" - if base.Cfg.MustValue("database", "DB_TYPE") == "postgres" { - rawSql = "UPDATE \"user\" SET num_followings = num_followings + 1 WHERE id = ?" - } + rawSql = "UPDATE `user` SET num_followings = num_followings + 1 WHERE id = ?" if _, err = session.Exec(rawSql, userId); err != nil { session.Rollback() return err @@ -345,19 +350,13 @@ func UnFollowUser(userId int64, unFollowId int64) (err error) { return err } - rawSql := "UPDATE user SET num_followers = num_followers - 1 WHERE id = ?" - if base.Cfg.MustValue("database", "DB_TYPE") == "postgres" { - rawSql = "UPDATE \"user\" SET num_followers = num_followers - 1 WHERE id = ?" - } + rawSql := "UPDATE `user` SET num_followers = num_followers - 1 WHERE id = ?" if _, err = session.Exec(rawSql, unFollowId); err != nil { session.Rollback() return err } - rawSql = "UPDATE user SET num_followings = num_followings - 1 WHERE id = ?" - if base.Cfg.MustValue("database", "DB_TYPE") == "postgres" { - rawSql = "UPDATE \"user\" SET num_followings = num_followings - 1 WHERE id = ?" - } + rawSql = "UPDATE `user` SET num_followings = num_followings - 1 WHERE id = ?" if _, err = session.Exec(rawSql, userId); err != nil { session.Rollback() return err diff --git a/modules/base/conf.go b/modules/base/conf.go index fdbf3ad3..81f32bd5 100644 --- a/modules/base/conf.go +++ b/modules/base/conf.go @@ -26,12 +26,14 @@ type Mailer struct { } var ( - AppVer string - AppName string - AppLogo string - AppUrl string - Domain string - SecretKey string + AppVer string + AppName string + AppLogo string + AppUrl string + Domain string + SecretKey string + RepoRootPath string + Cfg *goconfig.ConfigFile MailService *Mailer ) @@ -173,6 +175,13 @@ func init() { AppUrl = Cfg.MustValue("server", "ROOT_URL") Domain = Cfg.MustValue("server", "DOMAIN") SecretKey = Cfg.MustValue("security", "SECRET_KEY") + + // Determine and create root git reposiroty path. + RepoRootPath = Cfg.MustValue("repository", "ROOT") + if err = os.MkdirAll(RepoRootPath, os.ModePerm); err != nil { + fmt.Printf("models.init(fail to create RepoRootPath(%s)): %v\n", RepoRootPath, err) + os.Exit(2) + } } func NewServices() { diff --git a/routers/admin/admin.go b/routers/admin/admin.go index c7523b7f..a37f1207 100644 --- a/routers/admin/admin.go +++ b/routers/admin/admin.go @@ -5,20 +5,35 @@ package admin import ( + "github.com/gogits/gogs/models" "github.com/gogits/gogs/modules/middleware" ) func Dashboard(ctx *middleware.Context) { ctx.Data["Title"] = "Admin Dashboard" + ctx.Data["Stats"] = models.GetStatistic() ctx.HTML(200, "admin/dashboard") } func Users(ctx *middleware.Context) { ctx.Data["Title"] = "User Management" + + var err error + ctx.Data["Users"], err = models.GetUsers(100, 0) + if err != nil { + ctx.Handle(200, "admin.Users", err) + return + } ctx.HTML(200, "admin/users") } func Repositories(ctx *middleware.Context) { ctx.Data["Title"] = "Repository Management" + var err error + ctx.Data["Repos"], err = models.GetRepos(100, 0) + if err != nil { + ctx.Handle(200, "admin.Repositories", err) + return + } ctx.HTML(200, "admin/repos") } diff --git a/serve.go b/serve.go index ddc67023..2a17a334 100644 --- a/serve.go +++ b/serve.go @@ -12,7 +12,9 @@ import ( "strings" "github.com/codegangsta/cli" + "github.com/gogits/gogs/models" + "github.com/gogits/gogs/modules/base" ) var ( @@ -144,7 +146,7 @@ func runServ(*cli.Context) { } gitcmd := exec.Command(verb, rRepo) - gitcmd.Dir = models.RepoRootPath + gitcmd.Dir = base.RepoRootPath gitcmd.Stdout = os.Stdout gitcmd.Stdin = os.Stdin gitcmd.Stderr = os.Stderr diff --git a/templates/admin/dashboard.tmpl b/templates/admin/dashboard.tmpl index 84456c85..6a914b65 100644 --- a/templates/admin/dashboard.tmpl +++ b/templates/admin/dashboard.tmpl @@ -16,7 +16,7 @@
- Gogs database has 4 users, 3 repositories, 4 SSH keys. + Gogs database has {{.Stats.Counter.User}} users, {{.Stats.Counter.PublicKey}} SSH keys, {{.Stats.Counter.Repo}} repositories, {{.Stats.Counter.Watch}} watches, {{.Stats.Counter.Action}} actions, and {{.Stats.Counter.Access}} accesses.
diff --git a/templates/admin/repos.tmpl b/templates/admin/repos.tmpl index ec7f47e0..4522c667 100644 --- a/templates/admin/repos.tmpl +++ b/templates/admin/repos.tmpl @@ -16,6 +16,30 @@
+ + + + + + + + + + + + + {{range .Repos}} + + + + + + + + + {{end}} + +
IdNamePrivateWatchesForksCreated
{{.Id}}{{.Name}}{{.NumWatches}}{{.NumForks}}{{DateFormat .Created "M d, Y"}}
diff --git a/templates/admin/users.tmpl b/templates/admin/users.tmpl index 8acf256d..c087f268 100644 --- a/templates/admin/users.tmpl +++ b/templates/admin/users.tmpl @@ -16,6 +16,32 @@
+ + + + + + + + + + + + + + {{range .Users}} + + + + + + + + + + {{end}} + +
IdNameE-mailActivedAdminReposJoin
{{.Id}}{{.Name}}{{.Email}}{{.NumRepos}}{{DateFormat .Created "M d, Y"}}
-- cgit v1.2.3 From d40499e7fa3d62655431f160b6909d9751dabe11 Mon Sep 17 00:00:00 2001 From: Unknown Date: Fri, 21 Mar 2014 10:09:57 -0400 Subject: Finsih mail resend limit --- README.md | 2 +- conf/app.ini | 8 +++++++- gogs.go | 2 +- models/models.go | 1 - modules/base/conf.go | 35 +++++++++++++++++++++++++---------- routers/admin/admin.go | 3 +++ routers/user/user.go | 12 ++++++++++-- templates/admin/config.tmpl | 11 +++++++++++ templates/user/active.tmpl | 2 ++ 9 files changed, 60 insertions(+), 16 deletions(-) (limited to 'gogs.go') diff --git a/README.md b/README.md index e78ce8fe..cbd1f588 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Gogs(Go Git Service) is a GitHub-like clone in the Go Programming Language. Since we choose to use pure Go implementation of Git manipulation, Gogs certainly supports **ALL platforms** that Go supports, including Linux, Max OS X, and Windows with **ZERO** dependency. -##### Current version: 0.1.4 Alpha +##### Current version: 0.1.5 Alpha ## Purpose diff --git a/conf/app.ini b/conf/app.ini index 71fe81e8..ecb0d251 100644 --- a/conf/app.ini +++ b/conf/app.ini @@ -61,8 +61,14 @@ USER = PASSWD = [cache] +; Either "memory", "redis", or "memcache", default is "memory" ADAPTER = memory -CONFIG = +; For "memory" only, GC interval in seconds, default is 60 +INTERVAL = 60 +; For "redis" and "memcache", connection host address +; redis: ":6039" +; memcache: "127.0.0.1:11211" +HOST = [log] ; Either "console", "file", "conn" or "smtp", default is "console" diff --git a/gogs.go b/gogs.go index a9f7e6b5..41df7928 100644 --- a/gogs.go +++ b/gogs.go @@ -20,7 +20,7 @@ import ( // Test that go1.2 tag above is included in builds. main.go refers to this definition. const go12tag = true -const APP_VER = "0.1.4.0321" +const APP_VER = "0.1.5.0321" func init() { base.AppVer = APP_VER diff --git a/models/models.go b/models/models.go index a4550d72..8713ff28 100644 --- a/models/models.go +++ b/models/models.go @@ -35,7 +35,6 @@ func LoadModelsConfig() { } func setEngine() { - var err error switch DbCfg.Type { case "mysql": diff --git a/modules/base/conf.go b/modules/base/conf.go index 3962972c..2c3ecd72 100644 --- a/modules/base/conf.go +++ b/modules/base/conf.go @@ -133,6 +133,30 @@ func newLogService() { log.Info("Log Mode: %s(%s)", strings.Title(mode), levelName) } +func newCacheService() { + CacheAdapter = Cfg.MustValue("cache", "ADAPTER", "memory") + + switch CacheAdapter { + case "memory": + CacheConfig = fmt.Sprintf(`{"interval":%d}`, Cfg.MustInt("cache", "INTERVAL", 60)) + case "redis", "memcache": + CacheConfig = fmt.Sprintf(`{"conn":"%s"}`, Cfg.MustValue("cache", "HOST")) + default: + fmt.Printf("Unknown cache adapter: %s\n", CacheAdapter) + os.Exit(2) + } + + var err error + Cache, err = cache.NewCache(CacheAdapter, CacheConfig) + if err != nil { + fmt.Printf("Init cache system failed, adapter: %s, config: %s, %v\n", + CacheAdapter, CacheConfig, err) + os.Exit(2) + } + + log.Info("Cache Service Enabled") +} + func newMailService() { // Check mailer setting. if Cfg.MustBool("mailer", "ENABLED") { @@ -188,16 +212,6 @@ func NewConfigContext() { SecretKey = Cfg.MustValue("security", "SECRET_KEY") RunUser = Cfg.MustValue("", "RUN_USER") - CacheAdapter = Cfg.MustValue("cache", "ADAPTER") - CacheConfig = Cfg.MustValue("cache", "CONFIG") - - Cache, err = cache.NewCache(CacheAdapter, CacheConfig) - if err != nil { - fmt.Printf("Init cache system failed, adapter: %s, config: %s, %v\n", - CacheAdapter, CacheConfig, err) - os.Exit(2) - } - // Determine and create root git reposiroty path. RepoRootPath = Cfg.MustValue("repository", "ROOT") if err = os.MkdirAll(RepoRootPath, os.ModePerm); err != nil { @@ -209,6 +223,7 @@ func NewConfigContext() { func NewServices() { newService() newLogService() + newCacheService() newMailService() newRegisterMailService() } diff --git a/routers/admin/admin.go b/routers/admin/admin.go index 6d3831a9..d70af3c5 100644 --- a/routers/admin/admin.go +++ b/routers/admin/admin.go @@ -67,5 +67,8 @@ func Config(ctx *middleware.Context) { ctx.Data["Mailer"] = base.MailService } + ctx.Data["CacheAdapter"] = base.CacheAdapter + ctx.Data["CacheConfig"] = base.CacheConfig + ctx.HTML(200, "admin/config") } diff --git a/routers/user/user.go b/routers/user/user.go index 40b594ab..d38eb1ce 100644 --- a/routers/user/user.go +++ b/routers/user/user.go @@ -167,6 +167,10 @@ func SignUp(ctx *middleware.Context, form auth.RegisterForm) { ctx.Data["Email"] = u.Email ctx.Data["Hours"] = base.Service.ActiveCodeLives / 60 ctx.HTML(200, "user/active") + + if err = ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil { + log.Error("Set cache(MailResendLimit) fail: %v", err) + } return } ctx.Redirect("/user/login") @@ -247,8 +251,12 @@ func Activate(ctx *middleware.Context) { } // Resend confirmation e-mail. if base.Service.RegisterEmailConfirm { - ctx.Data["Hours"] = base.Service.ActiveCodeLives / 60 - mailer.SendActiveMail(ctx.Render, ctx.User) + if ctx.Cache.IsExist("MailResendLimit_" + ctx.User.LowerName) { + ctx.Data["ResendLimited"] = true + } else { + ctx.Data["Hours"] = base.Service.ActiveCodeLives / 60 + mailer.SendActiveMail(ctx.Render, ctx.User) + } } else { ctx.Data["ServiceNotEnabled"] = true } diff --git a/templates/admin/config.tmpl b/templates/admin/config.tmpl index 7013c201..ad32ec3f 100644 --- a/templates/admin/config.tmpl +++ b/templates/admin/config.tmpl @@ -63,6 +63,17 @@
User: {{.Mailer.User}}
+ +
+
+ Cache Configuration +
+ +
+
Cache Adapter: {{.CacheAdapter}}
+
Cache Config: {{.CacheConfig}}
+
+
{{template "base/footer" .}} \ No newline at end of file diff --git a/templates/user/active.tmpl b/templates/user/active.tmpl index fefd7d3a..47c87a59 100644 --- a/templates/user/active.tmpl +++ b/templates/user/active.tmpl @@ -6,6 +6,8 @@ {{if .IsActivatePage}} {{if .ServiceNotEnabled}}

Sorry, Register Mail Confirmation has been disabled.

+ {{else if .ResendLimited}} +

Sorry, you are sending activation e-mail too frequently, please wait 3 minutes.

{{else}}

New confirmation e-mail has been sent to {{.SignedUser.Email}}, please check your inbox within {{.Hours}} hours to complete your registeration.


-- cgit v1.2.3