aboutsummaryrefslogtreecommitdiff
path: root/routers
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2014-04-10 22:21:12 +0800
committerLunny Xiao <xiaolunwen@gmail.com>2014-04-10 22:21:12 +0800
commit94c7278194694fec728b518d4390b03ba6c237a4 (patch)
tree2aebf5fe63423b7b2eb14d58697bab1c95ffb3bb /routers
parent16b6e5d50b665c5376b61ca7d02e3716a1c05ead (diff)
parent2577940c30f6a6d15390974ab36f8c3d1e00f9f4 (diff)
Merge branch 'master' of github.com:gogits/gogs into dev
Conflicts: web.go
Diffstat (limited to 'routers')
-rw-r--r--routers/api/v1/miscellaneous.go2
-rw-r--r--routers/install.go6
-rw-r--r--routers/repo/http.go14
-rw-r--r--routers/repo/issue.go36
-rw-r--r--routers/repo/release.go8
-rw-r--r--routers/user/setting.go7
-rw-r--r--routers/user/social.go115
-rw-r--r--routers/user/user.go86
8 files changed, 229 insertions, 45 deletions
diff --git a/routers/api/v1/miscellaneous.go b/routers/api/v1/miscellaneous.go
index 0ff1eb04..babdfce9 100644
--- a/routers/api/v1/miscellaneous.go
+++ b/routers/api/v1/miscellaneous.go
@@ -13,6 +13,6 @@ func Markdown(ctx *middleware.Context) {
content := ctx.Query("content")
ctx.Render.JSON(200, map[string]interface{}{
"ok": true,
- "content": string(base.RenderMarkdown([]byte(content), "")),
+ "content": string(base.RenderMarkdown([]byte(content), ctx.Query("repoLink"))),
})
}
diff --git a/routers/install.go b/routers/install.go
index 032af480..1c4e6181 100644
--- a/routers/install.go
+++ b/routers/install.go
@@ -6,13 +6,13 @@ package routers
import (
"errors"
- "fmt"
"os"
"strings"
"github.com/Unknwon/goconfig"
"github.com/go-martini/martini"
"github.com/lunny/xorm"
+ qlog "github.com/qiniu/log"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/auth"
@@ -43,8 +43,7 @@ func GlobalInit() {
if base.InstallLock {
if err := models.NewEngine(); err != nil {
- fmt.Println(err)
- os.Exit(2)
+ qlog.Fatal(err)
}
models.HasEngine = true
@@ -183,6 +182,7 @@ func Install(ctx *middleware.Context, form auth.InstallForm) {
if _, err := models.RegisterUser(&models.User{Name: form.AdminName, Email: form.AdminEmail, Passwd: form.AdminPasswd,
IsAdmin: true, IsActive: true}); err != nil {
if err != models.ErrUserAlreadyExist {
+ base.InstallLock = false
ctx.RenderWithErr("Admin account setting is invalid: "+err.Error(), "install", &form)
return
}
diff --git a/routers/repo/http.go b/routers/repo/http.go
index d3699f3a..993de51f 100644
--- a/routers/repo/http.go
+++ b/routers/repo/http.go
@@ -135,10 +135,11 @@ type route struct {
}
type Config struct {
- ReposRoot string
- GitBinPath string
- UploadPack bool
- ReceivePack bool
+ ReposRoot string
+ GitBinPath string
+ UploadPack bool
+ ReceivePack bool
+ OnPushSucceed func()
}
type handler struct {
@@ -223,21 +224,26 @@ func serviceRpc(rpc string, hr handler) {
in, err := cmd.StdinPipe()
if err != nil {
log.Print(err)
+ return
}
stdout, err := cmd.StdoutPipe()
if err != nil {
log.Print(err)
+ return
}
err = cmd.Start()
if err != nil {
log.Print(err)
+ return
}
in.Write(input)
io.Copy(w, stdout)
cmd.Wait()
+
+ hr.Config.OnPushSucceed()
}
func getInfoRefs(hr handler) {
diff --git a/routers/repo/issue.go b/routers/repo/issue.go
index be925426..9688fd4d 100644
--- a/routers/repo/issue.go
+++ b/routers/repo/issue.go
@@ -9,6 +9,7 @@ import (
"net/url"
"strings"
+ "github.com/Unknwon/com"
"github.com/go-martini/martini"
"github.com/gogits/gogs/models"
@@ -99,7 +100,7 @@ func CreateIssue(ctx *middleware.Context, params martini.Params, form auth.Creat
issue, err := models.CreateIssue(ctx.User.Id, ctx.Repo.Repository.Id, form.MilestoneId, form.AssigneeId,
ctx.Repo.Repository.NumIssues, form.IssueName, form.Labels, form.Content, false)
if err != nil {
- ctx.Handle(200, "issue.CreateIssue", err)
+ ctx.Handle(200, "issue.CreateIssue(CreateIssue)", err)
return
}
@@ -107,14 +108,31 @@ func CreateIssue(ctx *middleware.Context, params martini.Params, form auth.Creat
if err = models.NotifyWatchers(&models.Action{ActUserId: ctx.User.Id, ActUserName: ctx.User.Name, ActEmail: ctx.User.Email,
OpType: models.OP_CREATE_ISSUE, Content: fmt.Sprintf("%d|%s", issue.Index, issue.Name),
RepoId: ctx.Repo.Repository.Id, RepoName: ctx.Repo.Repository.Name, RefName: ""}); err != nil {
- ctx.Handle(200, "issue.CreateIssue", err)
+ ctx.Handle(200, "issue.CreateIssue(NotifyWatchers)", err)
return
}
- // Mail watchers.
+ // Mail watchers and mentions.
if base.Service.NotifyMail {
- if err = mailer.SendNotifyMail(ctx.User, ctx.Repo.Owner, ctx.Repo.Repository, issue); err != nil {
- ctx.Handle(200, "issue.CreateIssue", err)
+ tos, err := mailer.SendIssueNotifyMail(ctx.User, ctx.Repo.Owner, ctx.Repo.Repository, issue)
+ if err != nil {
+ ctx.Handle(200, "issue.CreateIssue(SendIssueNotifyMail)", err)
+ return
+ }
+
+ tos = append(tos, ctx.User.LowerName)
+ ms := base.MentionPattern.FindAllString(issue.Content, -1)
+ newTos := make([]string, 0, len(ms))
+ for _, m := range ms {
+ if com.IsSliceContainsStr(tos, m[1:]) {
+ continue
+ }
+
+ newTos = append(newTos, m[1:])
+ }
+ if err = mailer.SendIssueMentionMail(ctx.User, ctx.Repo.Owner, ctx.Repo.Repository,
+ issue, models.GetUserEmailsByNames(newTos)); err != nil {
+ ctx.Handle(200, "issue.CreateIssue(SendIssueMentionMail)", err)
return
}
}
@@ -147,7 +165,7 @@ func ViewIssue(ctx *middleware.Context, params martini.Params) {
return
}
issue.Poster = u
- issue.RenderedContent = string(base.RenderMarkdown([]byte(issue.Content), ""))
+ issue.RenderedContent = string(base.RenderMarkdown([]byte(issue.Content), ctx.Repo.RepoLink))
// Get comments.
comments, err := models.GetIssueComments(issue.Id)
@@ -164,7 +182,7 @@ func ViewIssue(ctx *middleware.Context, params martini.Params) {
return
}
comments[i].Poster = u
- comments[i].Content = string(base.RenderMarkdown([]byte(comments[i].Content), ""))
+ comments[i].Content = string(base.RenderMarkdown([]byte(comments[i].Content), ctx.Repo.RepoLink))
}
ctx.Data["Title"] = issue.Name
@@ -193,7 +211,7 @@ func UpdateIssue(ctx *middleware.Context, params martini.Params, form auth.Creat
return
}
- if ctx.User.Id != issue.PosterId {
+ if ctx.User.Id != issue.PosterId && !ctx.Repo.IsOwner {
ctx.Handle(404, "issue.UpdateIssue", nil)
return
}
@@ -211,7 +229,7 @@ func UpdateIssue(ctx *middleware.Context, params martini.Params, form auth.Creat
ctx.JSON(200, map[string]interface{}{
"ok": true,
"title": issue.Name,
- "content": string(base.RenderMarkdown([]byte(issue.Content), "")),
+ "content": string(base.RenderMarkdown([]byte(issue.Content), ctx.Repo.RepoLink)),
})
}
diff --git a/routers/repo/release.go b/routers/repo/release.go
index 8e8b93c9..279fc169 100644
--- a/routers/repo/release.go
+++ b/routers/repo/release.go
@@ -12,6 +12,7 @@ import (
func Releases(ctx *middleware.Context) {
ctx.Data["Title"] = "Releases"
ctx.Data["IsRepoToolbarReleases"] = true
+ ctx.Data["IsRepoReleaseNew"] = false
tags, err := models.GetTags(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
if err != nil {
ctx.Handle(404, "repo.Releases(GetTags)", err)
@@ -20,3 +21,10 @@ func Releases(ctx *middleware.Context) {
ctx.Data["Releases"] = tags
ctx.HTML(200, "release/list")
}
+
+func ReleasesNew(ctx *middleware.Context) {
+ ctx.Data["Title"] = "New Release"
+ ctx.Data["IsRepoToolbarReleases"] = true
+ ctx.Data["IsRepoReleaseNew"] = true
+ ctx.HTML(200, "release/new")
+}
diff --git a/routers/user/setting.go b/routers/user/setting.go
index 4b6d88a3..ea779e85 100644
--- a/routers/user/setting.go
+++ b/routers/user/setting.go
@@ -73,11 +73,7 @@ func SettingPassword(ctx *middleware.Context, form auth.UpdatePasswdForm) {
user := ctx.User
newUser := &models.User{Passwd: form.NewPasswd}
- if err := newUser.EncodePasswd(); err != nil {
- ctx.Handle(200, "setting.SettingPassword", err)
- return
- }
-
+ newUser.EncodePasswd()
if user.Passwd != newUser.Passwd {
ctx.Data["HasError"] = true
ctx.Data["ErrorMsg"] = "Old password is not correct"
@@ -85,6 +81,7 @@ func SettingPassword(ctx *middleware.Context, form auth.UpdatePasswdForm) {
ctx.Data["HasError"] = true
ctx.Data["ErrorMsg"] = "New password and re-type password are not same"
} else {
+ newUser.Salt = models.GetUserSalt()
user.Passwd = newUser.Passwd
if err := models.UpdateUser(user); err != nil {
ctx.Handle(200, "setting.SettingPassword", err)
diff --git a/routers/user/social.go b/routers/user/social.go
index b59f4963..08cfcd83 100644
--- a/routers/user/social.go
+++ b/routers/user/social.go
@@ -1,49 +1,122 @@
// 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 user
import (
"encoding/json"
+ "strconv"
"code.google.com/p/goauth2/oauth"
+
+ "github.com/gogits/gogs/models"
+ "github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
+ "github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/oauth2"
)
-// github && google && ...
-func SocialSignIn(tokens oauth2.Tokens) {
- transport := &oauth.Transport{}
- transport.Token = &oauth.Token{
- AccessToken: tokens.Access(),
- RefreshToken: tokens.Refresh(),
- Expiry: tokens.ExpiryTime(),
- Extra: tokens.ExtraData(),
- }
+type SocialConnector interface {
+ Identity() string
+ Type() int
+ Name() string
+ Email() string
+ Token() string
+}
- // Github API refer: https://developer.github.com/v3/users/
- // FIXME: need to judge url
- type GithubUser struct {
+type SocialGithub struct {
+ data struct {
Id int `json:"id"`
Name string `json:"login"`
Email string `json:"email"`
}
+ WebToken *oauth.Token
+}
+
+func (s *SocialGithub) Identity() string {
+ return strconv.Itoa(s.data.Id)
+}
+
+func (s *SocialGithub) Type() int {
+ return models.OT_GITHUB
+}
+
+func (s *SocialGithub) Name() string {
+ return s.data.Name
+}
+
+func (s *SocialGithub) Email() string {
+ return s.data.Email
+}
+
+func (s *SocialGithub) Token() string {
+ data, _ := json.Marshal(s.WebToken)
+ return string(data)
+}
- // Make the request.
+// Github API refer: https://developer.github.com/v3/users/
+func (s *SocialGithub) Update() error {
scope := "https://api.github.com/user"
+ transport := &oauth.Transport{
+ Token: s.WebToken,
+ }
+ log.Debug("update github info")
r, err := transport.Client().Get(scope)
if err != nil {
- log.Error("connect with github error: %s", err)
- // FIXME: handle error page
- return
+ return err
}
defer r.Body.Close()
+ return json.NewDecoder(r.Body).Decode(&s.data)
+}
- user := &GithubUser{}
- err = json.NewDecoder(r.Body).Decode(user)
- if err != nil {
- log.Error("Get: %s", err)
+// github && google && ...
+func SocialSignIn(ctx *middleware.Context, tokens oauth2.Tokens) {
+ gh := &SocialGithub{
+ WebToken: &oauth.Token{
+ AccessToken: tokens.Access(),
+ RefreshToken: tokens.Refresh(),
+ Expiry: tokens.ExpiryTime(),
+ Extra: tokens.ExtraData(),
+ },
}
- log.Info("login: %s", user.Name)
+ if len(tokens.Access()) == 0 {
+ log.Error("empty access")
+ return
+ }
+ var err error
+ var u *models.User
+ if err = gh.Update(); err != nil {
+ // FIXME: handle error page
+ log.Error("connect with github error: %s", err)
+ return
+ }
+ var soc SocialConnector = gh
+ log.Info("login: %s", soc.Name())
// FIXME: login here, user email to check auth, if not registe, then generate a uniq username
+ if u, err = models.GetOauth2User(soc.Identity()); err != nil {
+ u = &models.User{
+ Name: soc.Name(),
+ Email: soc.Email(),
+ Passwd: "123456",
+ IsActive: !base.Service.RegisterEmailConfirm,
+ }
+ if u, err = models.RegisterUser(u); err != nil {
+ log.Error("register user: %v", err)
+ return
+ }
+ oa := &models.Oauth2{}
+ oa.Uid = u.Id
+ oa.Type = soc.Type()
+ oa.Token = soc.Token()
+ oa.Identity = soc.Identity()
+ log.Info("oa: %v", oa)
+ if err = models.AddOauth2(oa); err != nil {
+ log.Error("add oauth2 %v", err)
+ return
+ }
+ }
+ ctx.Session.Set("userId", u.Id)
+ ctx.Session.Set("userName", u.Name)
+ ctx.Redirect("/")
}
diff --git a/routers/user/user.go b/routers/user/user.go
index 08930e22..f6a39b86 100644
--- a/routers/user/user.go
+++ b/routers/user/user.go
@@ -78,6 +78,11 @@ func SignIn(ctx *middleware.Context, form auth.LogInForm) {
ctx.Data["Title"] = "Log In"
if ctx.Req.Method == "GET" {
+ if base.OauthService != nil {
+ ctx.Data["OauthEnabled"] = true
+ ctx.Data["OauthGitHubEnabled"] = base.OauthService.GitHub.Enabled
+ }
+
// Check auto-login.
userName := ctx.GetCookie(base.CookieUserName)
if len(userName) == 0 {
@@ -403,9 +408,12 @@ func Activate(ctx *middleware.Context) {
if user := models.VerifyUserActiveCode(code); user != nil {
user.IsActive = true
user.Rands = models.GetUserSalt()
- models.UpdateUser(user)
+ if err := models.UpdateUser(user); err != nil {
+ ctx.Handle(404, "user.Activate", err)
+ return
+ }
- log.Trace("%s User activated: %s", ctx.Req.RequestURI, user.LowerName)
+ log.Trace("%s User activated: %s", ctx.Req.RequestURI, user.Name)
ctx.Session.Set("userId", user.Id)
ctx.Session.Set("userName", user.Name)
@@ -416,3 +424,77 @@ func Activate(ctx *middleware.Context) {
ctx.Data["IsActivateFailed"] = true
ctx.HTML(200, "user/active")
}
+
+func ForgotPasswd(ctx *middleware.Context) {
+ ctx.Data["Title"] = "Forgot Password"
+
+ if base.MailService == nil {
+ ctx.Data["IsResetDisable"] = true
+ ctx.HTML(200, "user/forgot_passwd")
+ return
+ }
+
+ ctx.Data["IsResetRequest"] = true
+ if ctx.Req.Method == "GET" {
+ ctx.HTML(200, "user/forgot_passwd")
+ return
+ }
+
+ email := ctx.Query("email")
+ u, err := models.GetUserByEmail(email)
+ if err != nil {
+ if err == models.ErrUserNotExist {
+ ctx.RenderWithErr("This e-mail address does not associate to any account.", "user/forgot_passwd", nil)
+ } else {
+ ctx.Handle(404, "user.ResetPasswd(check existence)", err)
+ }
+ return
+ }
+
+ mailer.SendResetPasswdMail(ctx.Render, u)
+ ctx.Data["Email"] = email
+ ctx.Data["Hours"] = base.Service.ActiveCodeLives / 60
+ ctx.Data["IsResetSent"] = true
+ ctx.HTML(200, "user/forgot_passwd")
+}
+
+func ResetPasswd(ctx *middleware.Context) {
+ code := ctx.Query("code")
+ if len(code) == 0 {
+ ctx.Error(404)
+ return
+ }
+ ctx.Data["Code"] = code
+
+ if ctx.Req.Method == "GET" {
+ ctx.Data["IsResetForm"] = true
+ ctx.HTML(200, "user/reset_passwd")
+ return
+ }
+
+ if u := models.VerifyUserActiveCode(code); u != nil {
+ // Validate password length.
+ passwd := ctx.Query("passwd")
+ if len(passwd) < 6 || len(passwd) > 30 {
+ ctx.Data["IsResetForm"] = true
+ ctx.RenderWithErr("Password length should be in 6 and 30.", "user/reset_passwd", nil)
+ return
+ }
+
+ u.Passwd = passwd
+ u.Rands = models.GetUserSalt()
+ u.Salt = models.GetUserSalt()
+ u.EncodePasswd()
+ if err := models.UpdateUser(u); err != nil {
+ ctx.Handle(404, "user.ResetPasswd(UpdateUser)", err)
+ return
+ }
+
+ log.Trace("%s User password reset: %s", ctx.Req.RequestURI, u.Name)
+ ctx.Redirect("/user/login")
+ return
+ }
+
+ ctx.Data["IsResetFailed"] = true
+ ctx.HTML(200, "user/reset_passwd")
+}