mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:28:11 +09:00 
			
		
		
		
	Fix issue with log in with GitHub but need more error handle after
This commit is contained in:
		| @@ -72,6 +72,14 @@ FROM = | |||||||
| USER =  | USER =  | ||||||
| PASSWD =  | PASSWD =  | ||||||
|  |  | ||||||
|  | [oauth] | ||||||
|  | ENABLED = false | ||||||
|  |  | ||||||
|  | [oauth.github] | ||||||
|  | ENABLED = | ||||||
|  | CLIENT_ID =  | ||||||
|  | CLIENT_SECRET =  | ||||||
|  |  | ||||||
| [cache] | [cache] | ||||||
| ; Either "memory", "redis", or "memcache", default is "memory" | ; Either "memory", "redis", or "memcache", default is "memory" | ||||||
| ADAPTER = memory | ADAPTER = memory | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							| @@ -19,7 +19,7 @@ import ( | |||||||
| // Test that go1.2 tag above is included in builds. main.go refers to this definition. | // Test that go1.2 tag above is included in builds. main.go refers to this definition. | ||||||
| const go12tag = true | const go12tag = true | ||||||
|  |  | ||||||
| const APP_VER = "0.2.2.0406 Alpha" | const APP_VER = "0.2.2.0407 Alpha" | ||||||
|  |  | ||||||
| func init() { | func init() { | ||||||
| 	base.AppVer = APP_VER | 	base.AppVer = APP_VER | ||||||
|   | |||||||
| @@ -366,6 +366,19 @@ func GetUserByName(name string) (*User, error) { | |||||||
| 	return user, nil | 	return user, nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // GetUserEmailsByNames returns a slice of e-mails corresponds to names. | ||||||
|  | func GetUserEmailsByNames(names []string) []string { | ||||||
|  | 	mails := make([]string, 0, len(names)) | ||||||
|  | 	for _, name := range names { | ||||||
|  | 		u, err := GetUserByName(name) | ||||||
|  | 		if err != nil { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		mails = append(mails, u.Email) | ||||||
|  | 	} | ||||||
|  | 	return mails | ||||||
|  | } | ||||||
|  |  | ||||||
| // GetUserByEmail returns the user object by given e-mail if exists. | // GetUserByEmail returns the user object by given e-mail if exists. | ||||||
| func GetUserByEmail(email string) (*User, error) { | func GetUserByEmail(email string) (*User, error) { | ||||||
| 	if len(email) == 0 { | 	if len(email) == 0 { | ||||||
|   | |||||||
| @@ -22,13 +22,21 @@ import ( | |||||||
| 	"github.com/gogits/gogs/modules/log" | 	"github.com/gogits/gogs/modules/log" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // Mailer represents a mail service. | // Mailer represents mail service. | ||||||
| type Mailer struct { | type Mailer struct { | ||||||
| 	Name         string | 	Name         string | ||||||
| 	Host         string | 	Host         string | ||||||
| 	User, Passwd string | 	User, Passwd string | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // Oauther represents oauth service. | ||||||
|  | type Oauther struct { | ||||||
|  | 	GitHub struct { | ||||||
|  | 		Enabled                bool | ||||||
|  | 		ClientId, ClientSecret string | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| var ( | var ( | ||||||
| 	AppVer       string | 	AppVer       string | ||||||
| 	AppName      string | 	AppName      string | ||||||
| @@ -45,8 +53,9 @@ var ( | |||||||
| 	CookieUserName     string | 	CookieUserName     string | ||||||
| 	CookieRememberName string | 	CookieRememberName string | ||||||
|  |  | ||||||
| 	Cfg         *goconfig.ConfigFile | 	Cfg          *goconfig.ConfigFile | ||||||
| 	MailService *Mailer | 	MailService  *Mailer | ||||||
|  | 	OauthService *Oauther | ||||||
|  |  | ||||||
| 	LogMode   string | 	LogMode   string | ||||||
| 	LogConfig string | 	LogConfig string | ||||||
| @@ -206,15 +215,17 @@ func newSessionService() { | |||||||
|  |  | ||||||
| func newMailService() { | func newMailService() { | ||||||
| 	// Check mailer setting. | 	// Check mailer setting. | ||||||
| 	if Cfg.MustBool("mailer", "ENABLED") { | 	if !Cfg.MustBool("mailer", "ENABLED") { | ||||||
| 		MailService = &Mailer{ | 		return | ||||||
| 			Name:   Cfg.MustValue("mailer", "NAME", AppName), |  | ||||||
| 			Host:   Cfg.MustValue("mailer", "HOST"), |  | ||||||
| 			User:   Cfg.MustValue("mailer", "USER"), |  | ||||||
| 			Passwd: Cfg.MustValue("mailer", "PASSWD"), |  | ||||||
| 		} |  | ||||||
| 		log.Info("Mail Service Enabled") |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	MailService = &Mailer{ | ||||||
|  | 		Name:   Cfg.MustValue("mailer", "NAME", AppName), | ||||||
|  | 		Host:   Cfg.MustValue("mailer", "HOST"), | ||||||
|  | 		User:   Cfg.MustValue("mailer", "USER"), | ||||||
|  | 		Passwd: Cfg.MustValue("mailer", "PASSWD"), | ||||||
|  | 	} | ||||||
|  | 	log.Info("Mail Service Enabled") | ||||||
| } | } | ||||||
|  |  | ||||||
| func newRegisterMailService() { | func newRegisterMailService() { | ||||||
| @@ -239,6 +250,25 @@ func newNotifyMailService() { | |||||||
| 	log.Info("Notify Mail Service Enabled") | 	log.Info("Notify Mail Service Enabled") | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func newOauthService() { | ||||||
|  | 	if !Cfg.MustBool("oauth", "ENABLED") { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	OauthService = &Oauther{} | ||||||
|  | 	oauths := make([]string, 0, 10) | ||||||
|  |  | ||||||
|  | 	// GitHub. | ||||||
|  | 	if Cfg.MustBool("oauth.github", "ENABLED") { | ||||||
|  | 		OauthService.GitHub.Enabled = true | ||||||
|  | 		OauthService.GitHub.ClientId = Cfg.MustValue("oauth.github", "CLIENT_ID") | ||||||
|  | 		OauthService.GitHub.ClientSecret = Cfg.MustValue("oauth.github", "CLIENT_SECRET") | ||||||
|  | 		oauths = append(oauths, "GitHub") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	log.Info("Oauth Service Enabled %s", oauths) | ||||||
|  | } | ||||||
|  |  | ||||||
| func NewConfigContext() { | func NewConfigContext() { | ||||||
| 	//var err error | 	//var err error | ||||||
| 	workDir, err := ExecDir() | 	workDir, err := ExecDir() | ||||||
| @@ -303,4 +333,5 @@ func NewServices() { | |||||||
| 	newMailService() | 	newMailService() | ||||||
| 	newRegisterMailService() | 	newRegisterMailService() | ||||||
| 	newNotifyMailService() | 	newNotifyMailService() | ||||||
|  | 	newOauthService() | ||||||
| } | } | ||||||
|   | |||||||
| @@ -90,21 +90,21 @@ func (options *CustomRender) Link(out *bytes.Buffer, link []byte, title []byte, | |||||||
| } | } | ||||||
|  |  | ||||||
| var ( | var ( | ||||||
| 	mentionPattern    = regexp.MustCompile(`@[0-9a-zA-Z_]{1,}`) | 	MentionPattern    = regexp.MustCompile(`@[0-9a-zA-Z_]{1,}`) | ||||||
| 	commitPattern     = regexp.MustCompile(`(\s|^)https?.*commit/[0-9a-zA-Z]+(#+[0-9a-zA-Z-]*)?`) | 	commitPattern     = regexp.MustCompile(`(\s|^)https?.*commit/[0-9a-zA-Z]+(#+[0-9a-zA-Z-]*)?`) | ||||||
| 	issueFullPattern  = regexp.MustCompile(`(\s|^)https?.*issues/[0-9]+(#+[0-9a-zA-Z-]*)?`) | 	issueFullPattern  = regexp.MustCompile(`(\s|^)https?.*issues/[0-9]+(#+[0-9a-zA-Z-]*)?`) | ||||||
| 	issueIndexPattern = regexp.MustCompile(`(\s|^)#[0-9]+`) | 	issueIndexPattern = regexp.MustCompile(`#[0-9]+`) | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func RenderSpecialLink(rawBytes []byte, urlPrefix string) []byte { | func RenderSpecialLink(rawBytes []byte, urlPrefix string) []byte { | ||||||
| 	ms := mentionPattern.FindAll(rawBytes, -1) | 	ms := MentionPattern.FindAll(rawBytes, -1) | ||||||
| 	for _, m := range ms { | 	for _, m := range ms { | ||||||
| 		rawBytes = bytes.Replace(rawBytes, m, | 		rawBytes = bytes.Replace(rawBytes, m, | ||||||
| 			[]byte(fmt.Sprintf(`<a href="/user/%s">%s</a>`, m[1:], m)), -1) | 			[]byte(fmt.Sprintf(`<a href="/user/%s">%s</a>`, m[1:], m)), -1) | ||||||
| 	} | 	} | ||||||
| 	ms = commitPattern.FindAll(rawBytes, -1) | 	ms = commitPattern.FindAll(rawBytes, -1) | ||||||
| 	for _, m := range ms { | 	for _, m := range ms { | ||||||
| 		m = bytes.TrimPrefix(m, []byte(" ")) | 		m = bytes.TrimSpace(m) | ||||||
| 		i := strings.Index(string(m), "commit/") | 		i := strings.Index(string(m), "commit/") | ||||||
| 		j := strings.Index(string(m), "#") | 		j := strings.Index(string(m), "#") | ||||||
| 		if j == -1 { | 		if j == -1 { | ||||||
| @@ -115,7 +115,7 @@ func RenderSpecialLink(rawBytes []byte, urlPrefix string) []byte { | |||||||
| 	} | 	} | ||||||
| 	ms = issueFullPattern.FindAll(rawBytes, -1) | 	ms = issueFullPattern.FindAll(rawBytes, -1) | ||||||
| 	for _, m := range ms { | 	for _, m := range ms { | ||||||
| 		m = bytes.TrimPrefix(m, []byte(" ")) | 		m = bytes.TrimSpace(m) | ||||||
| 		i := strings.Index(string(m), "issues/") | 		i := strings.Index(string(m), "issues/") | ||||||
| 		j := strings.Index(string(m), "#") | 		j := strings.Index(string(m), "#") | ||||||
| 		if j == -1 { | 		if j == -1 { | ||||||
| @@ -126,9 +126,8 @@ func RenderSpecialLink(rawBytes []byte, urlPrefix string) []byte { | |||||||
| 	} | 	} | ||||||
| 	ms = issueIndexPattern.FindAll(rawBytes, -1) | 	ms = issueIndexPattern.FindAll(rawBytes, -1) | ||||||
| 	for _, m := range ms { | 	for _, m := range ms { | ||||||
| 		m = bytes.TrimPrefix(m, []byte(" ")) |  | ||||||
| 		rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf( | 		rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf( | ||||||
| 			` <a href="%s/issues/%s">%s</a>`, urlPrefix, m[1:], m)), -1) | 			`<a href="%s/issues/%s">%s</a>`, urlPrefix, m[1:], m)), -1) | ||||||
| 	} | 	} | ||||||
| 	return rawBytes | 	return rawBytes | ||||||
| } | } | ||||||
|   | |||||||
| @@ -111,11 +111,11 @@ func SendResetPasswdMail(r *middleware.Render, user *models.User) { | |||||||
| 	SendAsync(&msg) | 	SendAsync(&msg) | ||||||
| } | } | ||||||
|  |  | ||||||
| // SendNotifyMail sends mail notification of all watchers. | // SendIssueNotifyMail sends mail notification of all watchers of repository. | ||||||
| func SendNotifyMail(user, owner *models.User, repo *models.Repository, issue *models.Issue) error { | func SendIssueNotifyMail(user, owner *models.User, repo *models.Repository, issue *models.Issue) ([]string, error) { | ||||||
| 	watches, err := models.GetWatches(repo.Id) | 	watches, err := models.GetWatches(repo.Id) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return errors.New("mail.NotifyWatchers(get watches): " + err.Error()) | 		return nil, errors.New("mail.NotifyWatchers(get watches): " + err.Error()) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	tos := make([]string, 0, len(watches)) | 	tos := make([]string, 0, len(watches)) | ||||||
| @@ -126,20 +126,37 @@ func SendNotifyMail(user, owner *models.User, repo *models.Repository, issue *mo | |||||||
| 		} | 		} | ||||||
| 		u, err := models.GetUserById(uid) | 		u, err := models.GetUserById(uid) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return errors.New("mail.NotifyWatchers(get user): " + err.Error()) | 			return nil, errors.New("mail.NotifyWatchers(get user): " + err.Error()) | ||||||
| 		} | 		} | ||||||
| 		tos = append(tos, u.Email) | 		tos = append(tos, u.Email) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(tos) == 0 { | 	if len(tos) == 0 { | ||||||
| 		return nil | 		return tos, nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	subject := fmt.Sprintf("[%s] %s", repo.Name, issue.Name) | 	subject := fmt.Sprintf("[%s] %s", repo.Name, issue.Name) | ||||||
| 	content := fmt.Sprintf("%s<br>-<br> <a href=\"%s%s/%s/issues/%d\">View it on Gogs</a>.", | 	content := fmt.Sprintf("%s<br>-<br> <a href=\"%s%s/%s/issues/%d\">View it on Gogs</a>.", | ||||||
| 		issue.Content, base.AppUrl, owner.Name, repo.Name, issue.Index) | 		base.RenderSpecialLink([]byte(issue.Content), owner.Name+"/"+repo.Name), | ||||||
|  | 		base.AppUrl, owner.Name, repo.Name, issue.Index) | ||||||
| 	msg := NewMailMessageFrom(tos, user.Name, subject, content) | 	msg := NewMailMessageFrom(tos, user.Name, subject, content) | ||||||
| 	msg.Info = fmt.Sprintf("Subject: %s, send notify emails", subject) | 	msg.Info = fmt.Sprintf("Subject: %s, send issue notify emails", subject) | ||||||
|  | 	SendAsync(&msg) | ||||||
|  | 	return tos, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SendIssueMentionMail sends mail notification for who are mentioned in issue. | ||||||
|  | func SendIssueMentionMail(user, owner *models.User, repo *models.Repository, issue *models.Issue, tos []string) error { | ||||||
|  | 	if len(tos) == 0 { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	issueLink := fmt.Sprintf("%s%s/%s/issues/%d", base.AppUrl, owner.Name, repo.Name, issue.Index) | ||||||
|  | 	body := fmt.Sprintf(`%s mentioned you.`) | ||||||
|  | 	subject := fmt.Sprintf("[%s] %s", repo.Name, issue.Name) | ||||||
|  | 	content := fmt.Sprintf("%s<br>-<br> <a href=\"%s\">View it on Gogs</a>.", body, issueLink) | ||||||
|  | 	msg := NewMailMessageFrom(tos, user.Name, subject, content) | ||||||
|  | 	msg.Info = fmt.Sprintf("Subject: %s, send issue mention emails", subject) | ||||||
| 	SendAsync(&msg) | 	SendAsync(&msg) | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|   | |||||||
| @@ -29,13 +29,13 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/gogits/session" | 	"github.com/gogits/session" | ||||||
|  |  | ||||||
|  | 	"github.com/gogits/gogs/modules/log" | ||||||
| 	"github.com/gogits/gogs/modules/middleware" | 	"github.com/gogits/gogs/modules/middleware" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
| 	codeRedirect = 302 | 	keyToken    = "oauth2_token" | ||||||
| 	keyToken     = "oauth2_token" | 	keyNextPage = "next" | ||||||
| 	keyNextPage  = "next" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var ( | var ( | ||||||
| @@ -179,42 +179,49 @@ var LoginRequired martini.Handler = func() martini.Handler { | |||||||
| 		token := unmarshallToken(ctx.Session) | 		token := unmarshallToken(ctx.Session) | ||||||
| 		if token == nil || token.IsExpired() { | 		if token == nil || token.IsExpired() { | ||||||
| 			next := url.QueryEscape(ctx.Req.URL.RequestURI()) | 			next := url.QueryEscape(ctx.Req.URL.RequestURI()) | ||||||
| 			ctx.Redirect(PathLogin+"?next="+next, codeRedirect) | 			ctx.Redirect(PathLogin + "?next=" + next) | ||||||
|  | 			return | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| }() | }() | ||||||
|  |  | ||||||
| func login(t *oauth.Transport, ctx *middleware.Context) { | func login(t *oauth.Transport, ctx *middleware.Context) { | ||||||
| 	next := extractPath(ctx.Req.URL.Query().Get(keyNextPage)) | 	next := extractPath(ctx.Query(keyNextPage)) | ||||||
| 	if ctx.Session.Get(keyToken) == nil { | 	if ctx.Session.Get(keyToken) == nil { | ||||||
| 		// User is not logged in. | 		// User is not logged in. | ||||||
| 		ctx.Redirect(t.Config.AuthCodeURL(next), codeRedirect) | 		ctx.Redirect(t.Config.AuthCodeURL(next)) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	// No need to login, redirect to the next page. | 	// No need to login, redirect to the next page. | ||||||
| 	ctx.Redirect(next, codeRedirect) | 	ctx.Redirect(next) | ||||||
| } | } | ||||||
|  |  | ||||||
| func logout(t *oauth.Transport, ctx *middleware.Context) { | func logout(t *oauth.Transport, ctx *middleware.Context) { | ||||||
| 	next := extractPath(ctx.Req.URL.Query().Get(keyNextPage)) | 	next := extractPath(ctx.Query(keyNextPage)) | ||||||
| 	ctx.Session.Delete(keyToken) | 	ctx.Session.Delete(keyToken) | ||||||
| 	ctx.Redirect(next, codeRedirect) | 	ctx.Redirect(next) | ||||||
| } | } | ||||||
|  |  | ||||||
| func handleOAuth2Callback(t *oauth.Transport, ctx *middleware.Context) { | func handleOAuth2Callback(t *oauth.Transport, ctx *middleware.Context) { | ||||||
| 	next := extractPath(ctx.Req.URL.Query().Get("state")) | 	if errMsg := ctx.Query("error_description"); len(errMsg) > 0 { | ||||||
| 	code := ctx.Req.URL.Query().Get("code") | 		log.Error("oauth2.handleOAuth2Callback: %s", errMsg) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	next := extractPath(ctx.Query("state")) | ||||||
|  | 	code := ctx.Query("code") | ||||||
| 	tk, err := t.Exchange(code) | 	tk, err := t.Exchange(code) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		// Pass the error message, or allow dev to provide its own | 		// Pass the error message, or allow dev to provide its own | ||||||
| 		// error handler. | 		// error handler. | ||||||
| 		ctx.Redirect(PathError, codeRedirect) | 		log.Error("oauth2.handleOAuth2Callback(token.Exchange): %v", err) | ||||||
|  | 		// ctx.Redirect(PathError) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	// Store the credentials in the session. | 	// Store the credentials in the session. | ||||||
| 	val, _ := json.Marshal(tk) | 	val, _ := json.Marshal(tk) | ||||||
| 	ctx.Session.Set(keyToken, val) | 	ctx.Session.Set(keyToken, val) | ||||||
| 	ctx.Redirect(next, codeRedirect) | 	ctx.Redirect(next) | ||||||
| } | } | ||||||
|  |  | ||||||
| func unmarshallToken(s session.SessionStore) (t *token) { | func unmarshallToken(s session.SessionStore) (t *token) { | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ import ( | |||||||
| 	"net/url" | 	"net/url" | ||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
|  | 	"github.com/Unknwon/com" | ||||||
| 	"github.com/go-martini/martini" | 	"github.com/go-martini/martini" | ||||||
|  |  | ||||||
| 	"github.com/gogits/gogs/models" | 	"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, | 	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) | 		ctx.Repo.Repository.NumIssues, form.IssueName, form.Labels, form.Content, false) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Handle(200, "issue.CreateIssue", err) | 		ctx.Handle(200, "issue.CreateIssue(CreateIssue)", err) | ||||||
| 		return | 		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, | 	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), | 		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 { | 		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 | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Mail watchers. | 	// Mail watchers and mentions. | ||||||
| 	if base.Service.NotifyMail { | 	if base.Service.NotifyMail { | ||||||
| 		if err = mailer.SendNotifyMail(ctx.User, ctx.Repo.Owner, ctx.Repo.Repository, issue); err != nil { | 		tos, err := mailer.SendIssueNotifyMail(ctx.User, ctx.Repo.Owner, ctx.Repo.Repository, issue) | ||||||
| 			ctx.Handle(200, "issue.CreateIssue", err) | 		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 | 			return | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -1,20 +1,20 @@ | |||||||
| // Copyright 2014 The Gogs Authors. All rights reserved. | // Copyright 2014 The Gogs Authors. All rights reserved. | ||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
| package user | package user | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"strconv" | 	"strconv" | ||||||
|  |  | ||||||
|  | 	"code.google.com/p/goauth2/oauth" | ||||||
|  |  | ||||||
| 	"github.com/gogits/gogs/models" | 	"github.com/gogits/gogs/models" | ||||||
| 	"github.com/gogits/gogs/modules/base" | 	"github.com/gogits/gogs/modules/base" | ||||||
| 	"github.com/gogits/gogs/modules/log" | 	"github.com/gogits/gogs/modules/log" | ||||||
| 	"github.com/gogits/gogs/modules/middleware" | 	"github.com/gogits/gogs/modules/middleware" | ||||||
| 	//"github.com/gogits/gogs/modules/oauth2" | 	"github.com/gogits/gogs/modules/oauth2" | ||||||
|  |  | ||||||
| 	"code.google.com/p/goauth2/oauth" |  | ||||||
| 	"github.com/martini-contrib/oauth2" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type SocialConnector interface { | type SocialConnector interface { | ||||||
| @@ -80,6 +80,10 @@ func SocialSignIn(ctx *middleware.Context, tokens oauth2.Tokens) { | |||||||
| 			Extra:        tokens.ExtraData(), | 			Extra:        tokens.ExtraData(), | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
|  | 	if len(tokens.Access()) == 0 { | ||||||
|  | 		log.Error("empty access") | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
| 	var err error | 	var err error | ||||||
| 	var u *models.User | 	var u *models.User | ||||||
| 	if err = gh.Update(); err != nil { | 	if err = gh.Update(); err != nil { | ||||||
|   | |||||||
| @@ -78,6 +78,11 @@ func SignIn(ctx *middleware.Context, form auth.LogInForm) { | |||||||
| 	ctx.Data["Title"] = "Log In" | 	ctx.Data["Title"] = "Log In" | ||||||
|  |  | ||||||
| 	if ctx.Req.Method == "GET" { | 	if ctx.Req.Method == "GET" { | ||||||
|  | 		if base.OauthService != nil { | ||||||
|  | 			ctx.Data["OauthEnabled"] = true | ||||||
|  | 			ctx.Data["OauthGitHubEnabled"] = base.OauthService.GitHub.Enabled | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		// Check auto-login. | 		// Check auto-login. | ||||||
| 		userName := ctx.GetCookie(base.CookieUserName) | 		userName := ctx.GetCookie(base.CookieUserName) | ||||||
| 		if len(userName) == 0 { | 		if len(userName) == 0 { | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ | |||||||
|                     </div> |                     </div> | ||||||
|                     <ul class="nav nav-tabs" data-init="tabs"> |                     <ul class="nav nav-tabs" data-init="tabs"> | ||||||
|                         <li class="active issue-write"><a href="#issue-textarea" data-toggle="tab">Write</a></li> |                         <li class="active issue-write"><a href="#issue-textarea" data-toggle="tab">Write</a></li> | ||||||
|                         <li class="issue-preview"><a href="#issue-preview" data-toggle="tab" data-ajax="/api/v1/markdown?repo=repo_id&issue=new" data-ajax-name="issue-preview" data-ajax-method="post" data-preview="#issue-preview">Preview</a></li> |                         <li class="issue-preview"><a href="#issue-preview" data-toggle="tab" data-ajax="/api/v1/markdown?repoLink={{.RepoLink}}" data-ajax-name="issue-preview" data-ajax-method="post" data-preview="#issue-preview">Preview</a></li> | ||||||
|                     </ul> |                     </ul> | ||||||
|                     <div class="tab-content"> |                     <div class="tab-content"> | ||||||
|                         <div class="tab-pane" id="issue-textarea"> |                         <div class="tab-pane" id="issue-textarea"> | ||||||
|   | |||||||
| @@ -43,9 +43,12 @@ | |||||||
|             </div> |             </div> | ||||||
|         </div> |         </div> | ||||||
|  |  | ||||||
|  |         {{if .OauthEnabled}} | ||||||
|         <div class="form-group text-center" id="social-login"> |         <div class="form-group text-center" id="social-login"> | ||||||
|             <a class="btn btn-danger btn-lg" href="/user/sign_up">Register new account</a> |             <h4>Log In with Social Accounts</h4> | ||||||
|  |             {{if .OauthGitHubEnabled}}<a href="/user/login/github"><i class="fa fa-github-square fa-3x"></i></a>{{end}} | ||||||
|         </div> |         </div> | ||||||
|  |         {{end}} | ||||||
|     </form> |     </form> | ||||||
| </div> | </div> | ||||||
| {{template "base/footer" .}} | {{template "base/footer" .}} | ||||||
							
								
								
									
										22
									
								
								web.go
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								web.go
									
									
									
									
									
								
							| @@ -20,16 +20,13 @@ import ( | |||||||
| 	"github.com/gogits/gogs/modules/base" | 	"github.com/gogits/gogs/modules/base" | ||||||
| 	"github.com/gogits/gogs/modules/log" | 	"github.com/gogits/gogs/modules/log" | ||||||
| 	"github.com/gogits/gogs/modules/middleware" | 	"github.com/gogits/gogs/modules/middleware" | ||||||
| 	//"github.com/gogits/gogs/modules/oauth2" | 	"github.com/gogits/gogs/modules/oauth2" | ||||||
| 	"github.com/gogits/gogs/routers" | 	"github.com/gogits/gogs/routers" | ||||||
| 	"github.com/gogits/gogs/routers/admin" | 	"github.com/gogits/gogs/routers/admin" | ||||||
| 	"github.com/gogits/gogs/routers/api/v1" | 	"github.com/gogits/gogs/routers/api/v1" | ||||||
| 	"github.com/gogits/gogs/routers/dev" | 	"github.com/gogits/gogs/routers/dev" | ||||||
| 	"github.com/gogits/gogs/routers/repo" | 	"github.com/gogits/gogs/routers/repo" | ||||||
| 	"github.com/gogits/gogs/routers/user" | 	"github.com/gogits/gogs/routers/user" | ||||||
|  |  | ||||||
| 	"github.com/martini-contrib/oauth2" |  | ||||||
| 	"github.com/martini-contrib/sessions" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var CmdWeb = cli.Command{ | var CmdWeb = cli.Command{ | ||||||
| @@ -63,12 +60,17 @@ func runWeb(*cli.Context) { | |||||||
| 	m.Use(middleware.InitContext()) | 	m.Use(middleware.InitContext()) | ||||||
|  |  | ||||||
| 	scope := "https://api.github.com/user" | 	scope := "https://api.github.com/user" | ||||||
| 	oauth2.PathCallback = "/oauth2callback" | 	// m.Use(sessions.Sessions("my_session", sessions.NewCookieStore([]byte("secret123")))) | ||||||
| 	m.Use(sessions.Sessions("my_session", sessions.NewCookieStore([]byte("secret123")))) | 	// m.Use(oauth2.Github(&oauth2.Options{ | ||||||
|  | 	// 	ClientId:     "09383403ff2dc16daaa1", | ||||||
|  | 	// 	ClientSecret: "5f6e7101d30b77952aab22b75eadae17551ea6b5", | ||||||
|  | 	// 	RedirectURL:  base.AppUrl + oauth2.PathCallback, | ||||||
|  | 	// 	Scopes:       []string{scope}, | ||||||
|  | 	// })) | ||||||
| 	m.Use(oauth2.Github(&oauth2.Options{ | 	m.Use(oauth2.Github(&oauth2.Options{ | ||||||
| 		ClientId:     "09383403ff2dc16daaa1", | 		ClientId:     "ba323b44192e65c7c320", | ||||||
| 		ClientSecret: "5f6e7101d30b77952aab22b75eadae17551ea6b5", | 		ClientSecret: "6818ffed53bea5815bf1a6412d1933f25fa10619", | ||||||
| 		RedirectURL:  base.AppUrl + oauth2.PathCallback, | 		RedirectURL:  base.AppUrl + oauth2.PathCallback[1:], | ||||||
| 		Scopes:       []string{scope}, | 		Scopes:       []string{scope}, | ||||||
| 	})) | 	})) | ||||||
|  |  | ||||||
| @@ -92,8 +94,8 @@ func runWeb(*cli.Context) { | |||||||
| 	m.Get("/avatar/:hash", avt.ServeHTTP) | 	m.Get("/avatar/:hash", avt.ServeHTTP) | ||||||
|  |  | ||||||
| 	m.Group("/user", func(r martini.Router) { | 	m.Group("/user", func(r martini.Router) { | ||||||
| 		r.Any("/login/github", reqSignOut, oauth2.LoginRequired, user.SocialSignIn) |  | ||||||
| 		r.Any("/login", binding.BindIgnErr(auth.LogInForm{}), user.SignIn) | 		r.Any("/login", binding.BindIgnErr(auth.LogInForm{}), user.SignIn) | ||||||
|  | 		r.Any("/login/github", oauth2.LoginRequired, user.SocialSignIn) | ||||||
| 		r.Any("/sign_up", binding.BindIgnErr(auth.RegisterForm{}), user.SignUp) | 		r.Any("/sign_up", binding.BindIgnErr(auth.RegisterForm{}), user.SignUp) | ||||||
| 		r.Any("/forget_password", user.ForgotPasswd) | 		r.Any("/forget_password", user.ForgotPasswd) | ||||||
| 		r.Any("/reset_password", user.ResetPasswd) | 		r.Any("/reset_password", user.ResetPasswd) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user