diff options
author | Unknown <joe2010xtmf@163.com> | 2014-04-13 21:00:12 -0400 |
---|---|---|
committer | Unknown <joe2010xtmf@163.com> | 2014-04-13 21:00:12 -0400 |
commit | d2b53dd43b3bc9719985033bc92b76abb9515b4d (patch) | |
tree | f6c038f0b8c11e8a01d7cd26d6bbdb14144696b3 | |
parent | 4b9b8024ba59b5b84d92dca650761b35ebf6408a (diff) | |
download | gitea-d2b53dd43b3bc9719985033bc92b76abb9515b4d.tar.gz gitea-d2b53dd43b3bc9719985033bc92b76abb9515b4d.zip |
Add weibo oauth
-rw-r--r-- | README.md | 3 | ||||
-rw-r--r-- | README_ZH.md | 3 | ||||
-rw-r--r-- | conf/app.ini | 8 | ||||
-rw-r--r-- | gogs.go | 2 | ||||
-rw-r--r-- | models/action.go | 14 | ||||
-rw-r--r-- | models/oauth2.go | 6 | ||||
-rw-r--r-- | models/repo.go | 2 | ||||
-rw-r--r-- | modules/base/conf.go | 2 | ||||
-rw-r--r-- | modules/base/template.go | 22 | ||||
-rw-r--r-- | modules/middleware/repo.go | 7 | ||||
-rw-r--r-- | modules/social/social.go | 62 | ||||
-rw-r--r-- | routers/admin/admin.go | 6 | ||||
-rw-r--r-- | routers/user/setting.go | 24 | ||||
-rw-r--r-- | templates/admin/config.tmpl | 26 | ||||
-rw-r--r-- | templates/repo/toolbar.tmpl | 2 | ||||
-rw-r--r-- | templates/user/publickey.tmpl | 4 | ||||
-rw-r--r-- | templates/user/setting_nav.tmpl | 1 | ||||
-rw-r--r-- | templates/user/signin.tmpl | 5 | ||||
-rw-r--r-- | templates/user/social.tmpl | 17 | ||||
-rw-r--r-- | web.go | 3 |
20 files changed, 198 insertions, 21 deletions
@@ -5,7 +5,7 @@ Gogs(Go Git Service) is a Self Hosted Git Service in the Go Programming Language ![Demo](http://gowalker.org/public/gogs_demo.gif) -##### Current version: 0.2.8 Alpha +##### Current version: 0.2.9 Alpha ### NOTICES @@ -40,6 +40,7 @@ More importantly, Gogs only needs one binary to setup your own project hosting o - Mail service(register, issue). - Administration panel. - Supports MySQL, PostgreSQL and SQLite3. +- Social account login(GitHub, Google, QQ, Weibo) ## Installation diff --git a/README_ZH.md b/README_ZH.md index beb5a1050b..97ab07ff23 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -5,7 +5,7 @@ Gogs(Go Git Service) 是一个由 Go 语言编写的自助 Git 托管服务。 ![Demo](http://gowalker.org/public/gogs_demo.gif) -##### 当前版本:0.2.8 Alpha +##### 当前版本:0.2.9 Alpha ## 开发目的 @@ -31,6 +31,7 @@ Gogs 完全使用 Go 语言来实现对 Git 数据的操作,实现 **零** 依 - 邮件服务(注册、Issue) - 管理员面板 - 支持 MySQL、PostgreSQL 以及 SQLite3 +- 社交帐号登录(GitHub、Google、QQ、微博) ## 安装部署 diff --git a/conf/app.ini b/conf/app.ini index 4eaf0a33c2..c70919961c 100644 --- a/conf/app.ini +++ b/conf/app.ini @@ -109,6 +109,14 @@ SCOPES = all AUTH_URL = https://api.twitter.com/oauth/authorize TOKEN_URL = https://api.twitter.com/oauth/access_token +[oauth.weibo] +ENABLED = false +CLIENT_ID = +CLIENT_SECRET = +SCOPES = all +AUTH_URL = https://api.weibo.com/oauth2/authorize +TOKEN_URL = https://api.weibo.com/oauth2/access_token + [cache] ; Either "memory", "redis", or "memcache", default is "memory" ADAPTER = memory @@ -19,7 +19,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.2.8.0413 Alpha" +const APP_VER = "0.2.9.0413 Alpha" func init() { base.AppVer = APP_VER diff --git a/models/action.go b/models/action.go index a642a82c98..3edb884e27 100644 --- a/models/action.go +++ b/models/action.go @@ -8,6 +8,8 @@ import ( "encoding/json" "time" + // "github.com/gogits/git" + "github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/log" ) @@ -22,6 +24,7 @@ const ( OP_CREATE_ISSUE OP_PULL_REQUEST OP_TRANSFER_REPO + OP_PUSH_TAG ) // Action represents user operation type and other information to repository., @@ -67,7 +70,14 @@ func (a Action) GetContent() string { // CommitRepoAction adds new action for committing repository. func CommitRepoAction(userId int64, userName, actEmail string, repoId int64, repoName string, refName string, commit *base.PushCommits) error { - log.Trace("action.CommitRepoAction(start): %d/%s", userId, repoName) + // log.Trace("action.CommitRepoAction(start): %d/%s", userId, repoName) + + opType := OP_COMMIT_REPO + // Check it's tag push or branch. + // if git.IsTagExist(RepoPath(userName, repoName), refName) { + // opType = OP_PUSH_TAG + // commit = &base.PushCommits{} + // } bs, err := json.Marshal(commit) if err != nil { @@ -76,7 +86,7 @@ func CommitRepoAction(userId int64, userName, actEmail string, } if err = NotifyWatchers(&Action{ActUserId: userId, ActUserName: userName, ActEmail: actEmail, - OpType: OP_COMMIT_REPO, Content: string(bs), RepoId: repoId, RepoName: repoName, RefName: refName}); err != nil { + OpType: opType, Content: string(bs), RepoId: repoId, RepoName: repoName, RefName: refName}); err != nil { log.Error("action.CommitRepoAction(notify watchers): %d/%s", userId, repoName) return err } diff --git a/models/oauth2.go b/models/oauth2.go index 38d21fda1c..d1ae4611b8 100644 --- a/models/oauth2.go +++ b/models/oauth2.go @@ -68,3 +68,9 @@ func GetOauth2ById(id int64) (oa *Oauth2, err error) { } return oa, nil } + +// GetOauthByUserId returns list of oauthes that are releated to given user. +func GetOauthByUserId(uid int64) (oas []*Oauth2, err error) { + err = orm.Find(&oas, Oauth2{Uid: uid}) + return oas, err +} diff --git a/models/repo.go b/models/repo.go index 1a5a95f047..bb0c164e24 100644 --- a/models/repo.go +++ b/models/repo.go @@ -75,9 +75,9 @@ type Repository struct { NumStars int NumForks int NumIssues int - NumReleases int `xorm:"NOT NULL"` NumClosedIssues int NumOpenIssues int `xorm:"-"` + NumTags int `xorm:"-"` IsPrivate bool IsMirror bool IsBare bool diff --git a/modules/base/conf.go b/modules/base/conf.go index 0eca5f4fcb..957ec57b4d 100644 --- a/modules/base/conf.go +++ b/modules/base/conf.go @@ -38,7 +38,7 @@ type OauthInfo struct { // Oauther represents oauth service. type Oauther struct { GitHub, Google, Tencent bool - Twitter bool + Twitter, Weibo bool OauthInfos map[string]*OauthInfo } diff --git a/modules/base/template.go b/modules/base/template.go index 6241497969..79aeeb9d77 100644 --- a/modules/base/template.go +++ b/modules/base/template.go @@ -92,6 +92,7 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{ "DiffTypeToStr": DiffTypeToStr, "DiffLineTypeToStr": DiffLineTypeToStr, "ShortSha": ShortSha, + "Oauth2Icon": Oauth2Icon, } type Actioner interface { @@ -109,7 +110,7 @@ func ActionIcon(opType int) string { switch opType { case 1: // Create repository. return "plus-circle" - case 5: // Commit repository. + case 5, 9: // Commit repository. return "arrow-circle-o-right" case 6: // Create issue. return "exclamation-circle" @@ -127,6 +128,7 @@ const ( TPL_CREATE_ISSUE = `<a href="/user/%s">%s</a> opened issue <a href="/%s/issues/%s">%s#%s</a> <div><img src="%s?s=16" alt="user-avatar"/> %s</div>` TPL_TRANSFER_REPO = `<a href="/user/%s">%s</a> transfered repository <code>%s</code> to <a href="/%s">%s</a>` + TPL_PUSH_TAG = `<a href="/user/%s">%s</a> pushed tag <a href="/%s/src/%s">%s</a> at <a href="/%s">%s</a>` ) type PushCommit struct { @@ -174,6 +176,8 @@ func ActionDesc(act Actioner) string { case 8: // Transfer repository. newRepoLink := content + "/" + repoName return fmt.Sprintf(TPL_TRANSFER_REPO, actUserName, actUserName, repoLink, newRepoLink, newRepoLink) + case 9: // Push tag. + return fmt.Sprintf(TPL_PUSH_TAG, actUserName, actUserName, repoLink, branch, branch, repoLink, repoLink) default: return "invalid type" } @@ -197,3 +201,19 @@ func DiffLineTypeToStr(diffType int) string { } return "same" } + +func Oauth2Icon(t int) string { + switch t { + case 1: + return "fa-github-square" + case 2: + return "fa-google-plus-square" + case 3: + return "fa-twitter-square" + case 4: + return "fa-linux" + case 5: + return "fa-weibo" + } + return "" +} diff --git a/modules/middleware/repo.go b/modules/middleware/repo.go index 1e79ce9870..82c1c2dbf6 100644 --- a/modules/middleware/repo.go +++ b/modules/middleware/repo.go @@ -123,6 +123,13 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler { ctx.Repo.GitRepo = gitRepo ctx.Repo.RepoLink = "/" + user.Name + "/" + repo.Name + tags, err := ctx.Repo.GitRepo.GetTags() + if err != nil { + ctx.Handle(500, "RepoAssignment(GetTags))", err) + return + } + ctx.Repo.Repository.NumTags = len(tags) + ctx.Data["Title"] = user.Name + "/" + repo.Name ctx.Data["Repository"] = repo ctx.Data["Owner"] = user diff --git a/modules/social/social.go b/modules/social/social.go index 230f478fe4..c2ee541776 100644 --- a/modules/social/social.go +++ b/modules/social/social.go @@ -48,7 +48,7 @@ func NewOauthService() { base.OauthService.OauthInfos = make(map[string]*base.OauthInfo) socialConfigs := make(map[string]*oauth.Config) - allOauthes := []string{"github", "google", "qq", "twitter"} + allOauthes := []string{"github", "google", "qq", "twitter", "weibo"} // Load all OAuth config data. for _, name := range allOauthes { base.OauthService.OauthInfos[name] = &base.OauthInfo{ @@ -98,6 +98,13 @@ func NewOauthService() { enabledOauths = append(enabledOauths, "Twitter") } + // Weibo. + if base.Cfg.MustBool("oauth.weibo", "ENABLED") { + base.OauthService.Weibo = true + newWeiboOauth(socialConfigs["weibo"]) + enabledOauths = append(enabledOauths, "Weibo") + } + log.Info("Oauth Service Enabled %s", enabledOauths) } @@ -331,3 +338,56 @@ func (s *SocialTwitter) UserInfo(token *oauth.Token, _ *url.URL) (*BasicUserInfo // }, nil return nil, nil } + +// __ __ ._____. +// / \ / \ ____ |__\_ |__ ____ +// \ \/\/ // __ \| || __ \ / _ \ +// \ /\ ___/| || \_\ ( <_> ) +// \__/\ / \___ >__||___ /\____/ +// \/ \/ \/ + +type SocialWeibo struct { + Token *oauth.Token + *oauth.Transport +} + +func (s *SocialWeibo) Type() int { + return models.OT_WEIBO +} + +func newWeiboOauth(config *oauth.Config) { + SocialMap["weibo"] = &SocialWeibo{ + Transport: &oauth.Transport{ + Config: config, + Transport: http.DefaultTransport, + }, + } +} + +func (s *SocialWeibo) SetRedirectUrl(url string) { + s.Transport.Config.RedirectURL = url +} + +func (s *SocialWeibo) UserInfo(token *oauth.Token, _ *url.URL) (*BasicUserInfo, error) { + transport := &oauth.Transport{Token: token} + var data struct { + Id string `json:"id"` + Name string `json:"name"` + } + var err error + + reqUrl := "https://api.weibo.com/2/users/show.json" + r, err := transport.Client().Get(reqUrl) + if err != nil { + return nil, err + } + defer r.Body.Close() + if err = json.NewDecoder(r.Body).Decode(&data); err != nil { + return nil, err + } + return &BasicUserInfo{ + Identity: data.Id, + Name: data.Name, + }, nil + return nil, nil +} diff --git a/routers/admin/admin.go b/routers/admin/admin.go index 18a43ff817..d0f737e645 100644 --- a/routers/admin/admin.go +++ b/routers/admin/admin.go @@ -153,6 +153,12 @@ func Config(ctx *middleware.Context) { ctx.Data["Mailer"] = base.MailService } + ctx.Data["OauthEnabled"] = false + if base.OauthService != nil { + ctx.Data["OauthEnabled"] = true + ctx.Data["Oauther"] = base.OauthService + } + ctx.Data["CacheAdapter"] = base.CacheAdapter ctx.Data["CacheConfig"] = base.CacheConfig diff --git a/routers/user/setting.go b/routers/user/setting.go index 7e66ad3599..a8fdc116c6 100644 --- a/routers/user/setting.go +++ b/routers/user/setting.go @@ -69,6 +69,20 @@ func SettingPost(ctx *middleware.Context, form auth.UpdateProfileForm) { ctx.Redirect("/user/setting") } +func SettingSocial(ctx *middleware.Context) { + ctx.Data["Title"] = "Social Account" + ctx.Data["PageIsUserSetting"] = true + ctx.Data["IsUserPageSettingSocial"] = true + socials, err := models.GetOauthByUserId(ctx.User.Id) + if err != nil { + ctx.Handle(500, "user.SettingSocial", err) + return + } + + ctx.Data["Socials"] = socials + ctx.HTML(200, "user/social") +} + func SettingPassword(ctx *middleware.Context) { ctx.Data["Title"] = "Password" ctx.Data["PageIsUserSetting"] = true @@ -147,7 +161,7 @@ func SettingSSHKeys(ctx *middleware.Context, form auth.AddSSHKeyForm) { // Add new SSH key. if ctx.Req.Method == "POST" { - if hasErr, ok := ctx.Data["HasError"]; ok && hasErr.(bool) { + if ctx.HasError() { ctx.HTML(200, "user/publickey") return } @@ -162,11 +176,13 @@ func SettingSSHKeys(ctx *middleware.Context, form auth.AddSSHKeyForm) { ctx.RenderWithErr("Public key name has been used", "user/publickey", &form) return } - ctx.Handle(200, "ssh.AddPublicKey", err) - log.Trace("%s User SSH key added: %s", ctx.Req.RequestURI, ctx.User.LowerName) + ctx.Handle(500, "ssh.AddPublicKey", err) return } else { - ctx.Data["AddSSHKeySuccess"] = true + log.Trace("%s User SSH key added: %s", ctx.Req.RequestURI, ctx.User.LowerName) + ctx.Flash.Success("New SSH Key has been added!") + ctx.Redirect("/user/setting/ssh") + return } } diff --git a/templates/admin/config.tmpl b/templates/admin/config.tmpl index 31cfb77bad..757a800c20 100644 --- a/templates/admin/config.tmpl +++ b/templates/admin/config.tmpl @@ -88,12 +88,34 @@ <dl class="dl-horizontal admin-dl-horizontal"> <dt>Enabled</dt> <dd><i class="fa fa{{if .MailerEnabled}}-check{{end}}-square-o"></i></dd> - <dt>Name</dt> + {{if .MailerEnabled}}<dt>Name</dt> <dd>{{.Mailer.Name}}</dd> <dt>Host</dt> <dd>{{.Mailer.Host}}</dd> <dt>User</dt> - <dd>{{.Mailer.User}}</dd> + <dd>{{.Mailer.User}}</dd>{{end}} + </dl> + </div> + </div> + + <div class="panel panel-default"> + <div class="panel-heading"> + OAuth Configuration + </div> + + <div class="panel-body"> + <dl class="dl-horizontal admin-dl-horizontal"> + <dt>Enabled</dt> + <dd><i class="fa fa{{if .OauthEnabled}}-check{{end}}-square-o"></i></dd> + {{if .OauthEnabled}}<dt>GitHub</dt> + <dd><i class="fa fa{{if .Oauther.GitHub}}-check{{end}}-square-o"></i></dd> + <dt>Google</dt> + <dd><i class="fa fa{{if .Oauther.Google}}-check{{end}}-square-o"></i></dd> + <dt>Tencent QQ</dt> + <dd><i class="fa fa{{if .Oauther.Tencent}}-check{{end}}-square-o"></i></dd> + <dt>Weibo</dt> + <dd><i class="fa fa{{if .Oauther.Weibo}}-check{{end}}-square-o"></i></dd> + <dd>{{.Mailer.User}}</dd>{{end}} </dl> </div> </div> diff --git a/templates/repo/toolbar.tmpl b/templates/repo/toolbar.tmpl index 9c137e5179..bde5bc29e1 100644 --- a/templates/repo/toolbar.tmpl +++ b/templates/repo/toolbar.tmpl @@ -13,7 +13,7 @@ <li class="tmp">{{if .IsRepoToolbarIssuesList}}<a href="{{.RepoLink}}/issues/new"><button class="btn btn-primary btn-sm">New Issue</button> </a>{{end}}</li> {{end}} - <li class="{{if .IsRepoToolbarReleases}}active{{end}}"><a href="{{.RepoLink}}/releases">{{if .Repository.NumReleases}}<span class="badge">{{.Repository.NumReleases}}</span> {{end}}Releases</a></li> + <li class="{{if .IsRepoToolbarReleases}}active{{end}}"><a href="{{.RepoLink}}/releases">{{if .Repository.NumTags}}<span class="badge">{{.Repository.NumTags}}</span> {{end}}Releases</a></li> {{if .IsRepoToolbarReleases}} <li class="tmp">{{if not .IsRepoReleaseNew}}<a href="{{.RepoLink}}/releases/new"><button class="btn btn-primary btn-sm">New Release</button></a>{{end}}</li> {{end}} diff --git a/templates/user/publickey.tmpl b/templates/user/publickey.tmpl index ecdeb035d2..29cfd8f0eb 100644 --- a/templates/user/publickey.tmpl +++ b/templates/user/publickey.tmpl @@ -4,8 +4,8 @@ {{template "user/setting_nav" .}} <div id="user-setting-container" class="col-md-9"> <div id="ssh-keys"> - <h4>SSH Keys</h4>{{if .AddSSHKeySuccess}} - <p class="alert alert-success">New SSH Key has been added !</p>{{else if .HasError}}<p class="alert alert-danger">{{.ErrorMsg}}</p>{{end}} + <h4>SSH Keys</h4> + {{template "base/alert" .}} <ul id="ssh-keys-list" class="list-group"> <li class="list-group-item"><span class="name">SSH Key's name</span></li> {{range .Keys}} diff --git a/templates/user/setting_nav.tmpl b/templates/user/setting_nav.tmpl index c0f2ae03dd..9c7ae5208f 100644 --- a/templates/user/setting_nav.tmpl +++ b/templates/user/setting_nav.tmpl @@ -2,6 +2,7 @@ <h4>Account Setting</h4> <ul class="list-group"> <li class="list-group-item{{if .IsUserPageSetting}} list-group-item-success{{end}}"><a href="/user/setting">Account Profile</a></li> + <li class="list-group-item{{if .IsUserPageSettingSocial}} list-group-item-success{{end}}"><a href="/user/setting/social">Social Account</a></li> <li class="list-group-item{{if .IsUserPageSettingPasswd}} list-group-item-success{{end}}"><a href="/user/setting/password">Password</a></li> <!-- <li class="list-group-item{{if .IsUserPageSettingNotify}} list-group-item-success{{end}}"><a href="/user/setting/notification">Notifications</a></li> --> <li class="list-group-item{{if .IsUserPageSettingSSH}} list-group-item-success{{end}}"><a href="/user/setting/ssh/">SSH Keys</a></li> diff --git a/templates/user/signin.tmpl b/templates/user/signin.tmpl index d402c29238..955c82f430 100644 --- a/templates/user/signin.tmpl +++ b/templates/user/signin.tmpl @@ -61,8 +61,9 @@ </a>--> {{if .OauthService.GitHub}}<a href="/user/login/github?next=/user/sign_up" class="btn btn-default"><i class="fa fa-github-square fa-2x"></i><span>GitHub</span></a>{{end}} {{if .OauthService.Google}}<a href="/user/login/google?next=/user/sign_up" class="btn btn-default"><i class="fa fa-google-plus-square fa-2x"></i><span>Google</span></a>{{end}} - {{if .OauthService.Tencent}}<a href="/user/login/twitter?next=/user/sign_up" class="btn btn-default"><i class="fa fa-twitter-square fa-2x"></i><span>Twitter</span></a>{{end}} - {{if .OauthService.Tencent}}<a href="/user/login/qq?next=/user/sign_up" class="btn btn-default"><i class="fa fa-linux fa-2x"></i><span>QQ</span></a>{{end}} + {{if .OauthService.Twitter}}<a href="/user/login/twitter?next=/user/sign_up" class="btn btn-default"><i class="fa fa-twitter-square fa-2x"></i><span>Twitter</span></a>{{end}} + {{if .OauthService.Tencent}}<a href="/user/login/qq?next=/user/sign_up" class="btn btn-default"><i class="fa fa-linux fa-2x"></i><span>Tencent QQ</span></a>{{end}} + {{if .OauthService.Weibo}}<a href="/user/login/weibo?next=/user/sign_up" class="btn btn-default"><i class="fa fa-weibo fa-2x"></i><span>Weibo</span></a>{{end}} </div> {{end}}{{end}} </form> diff --git a/templates/user/social.tmpl b/templates/user/social.tmpl new file mode 100644 index 0000000000..f0b1132385 --- /dev/null +++ b/templates/user/social.tmpl @@ -0,0 +1,17 @@ +{{template "base/head" .}} +{{template "base/navbar" .}} +<div id="body" class="container" data-page="user"> + {{template "user/setting_nav" .}} + <div id="user-setting-container" class="col-md-9"> + <div id="ssh-keys"> + <h4>Social Account</h4> + {{template "base/alert" .}} + <ul id="ssh-keys-list" class="list-group"> + {{range .Socials}} + <i class="fa {{Oauth2Icon .Type}} fa-3x"></i> + {{end}} + </ul> + </div> + </div> +</div> +{{template "base/footer" .}}
\ No newline at end of file @@ -63,7 +63,7 @@ func runWeb(*cli.Context) { SignInRequire: base.Service.RequireSignInView, DisableCsrf: true, }) - + reqSignOut := middleware.Toggle(&middleware.ToggleOptions{SignOutRequire: true}) bindIgnErr := middleware.BindIgnErr @@ -108,6 +108,7 @@ func runWeb(*cli.Context) { r.Post("/forget_password", user.ForgotPasswdPost) }) m.Group("/user/setting", func(r martini.Router) { + r.Get("/social", user.SettingSocial) r.Get("/password", user.SettingPassword) r.Post("/password", bindIgnErr(auth.UpdatePasswdForm{}), user.SettingPasswordPost) r.Any("/ssh", bindIgnErr(auth.AddSSHKeyForm{}), user.SettingSSHKeys) |