commit
						94c7278194
					
				@ -0,0 +1,13 @@ | 
				
			||||
{ | 
				
			||||
    "paths": ["."], | 
				
			||||
    "depth": 2, | 
				
			||||
    "exclude": [], | 
				
			||||
    "include": ["\\.go$"], | 
				
			||||
    "command": [ | 
				
			||||
        "bash", "-c", "go build && ./gogs web" | 
				
			||||
    ], | 
				
			||||
    "env": { | 
				
			||||
        "POWERED_BY": "github.com/shxsun/fswatch" | 
				
			||||
    }, | 
				
			||||
    "enable-restart": true | 
				
			||||
} | 
				
			||||
@ -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) | 
				
			||||
} | 
				
			||||
 | 
				
			||||
	// Make the request.
 | 
				
			||||
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) | 
				
			||||
} | 
				
			||||
 | 
				
			||||
// 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(), | 
				
			||||
		}, | 
				
			||||
	} | 
				
			||||
	if len(tokens.Access()) == 0 { | 
				
			||||
		log.Error("empty access") | 
				
			||||
		return | 
				
			||||
	} | 
				
			||||
	log.Info("login: %s", user.Name) | 
				
			||||
	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("/") | 
				
			||||
} | 
				
			||||
 | 
				
			||||
@ -1,6 +1,15 @@ | 
				
			||||
#!/bin/bash - | 
				
			||||
#!/bin/sh - | 
				
			||||
# 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. | 
				
			||||
# | 
				
			||||
# start gogs web | 
				
			||||
# | 
				
			||||
cd "$(dirname $0)" | 
				
			||||
./gogs web | 
				
			||||
IFS='  | 
				
			||||
	' | 
				
			||||
PATH=/bin:/usr/bin:/usr/local/bin | 
				
			||||
HOME=${HOME:?"need \$HOME variable"} | 
				
			||||
USER=$(whoami) | 
				
			||||
export USER HOME PATH | 
				
			||||
 | 
				
			||||
cd "$(dirname $0)" && exec ./gogs web | 
				
			||||
 | 
				
			||||
@ -0,0 +1,33 @@ | 
				
			||||
<!DOCTYPE html> | 
				
			||||
<html> | 
				
			||||
<head> | 
				
			||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | 
				
			||||
<title>{{.User.Name}}, please reset your password</title> | 
				
			||||
</head> | 
				
			||||
<body style="background:#eee;"> | 
				
			||||
<div style="color:#333; font:12px/1.5 Tahoma,Arial,sans-serif;; text-shadow:1px 1px #fff; padding:0; margin:0;"> | 
				
			||||
    <div style="width:600px;margin:0 auto; padding:40px 0 20px;"> | 
				
			||||
        <div style="border:1px solid #d9d9d9;border-radius:3px; background:#fff; box-shadow: 0px 2px 5px rgba(0, 0, 0,.05); -webkit-box-shadow: 0px 2px 5px rgba(0, 0, 0,.05);"> | 
				
			||||
            <div style="padding: 20px 15px;"> | 
				
			||||
                <h1 style="font-size:20px; padding:10px 0 20px; margin:0; border-bottom:1px solid #ddd;"><img src="{{.AppUrl}}/{{.AppLogo}}" style="height: 32px; margin-bottom: -10px;"> <a style="color:#333;text-decoration:none;" target="_blank" href="{{.AppUrl}}">{{.AppName}}</a></h1> | 
				
			||||
                <div style="padding:40px 15px;"> | 
				
			||||
                    <div style="font-size:16px; padding-bottom:30px; font-weight:bold;"> | 
				
			||||
                        Hi <span style="color: #00BFFF;">{{.User.Name}}</span>, | 
				
			||||
                    </div> | 
				
			||||
                    <div style="font-size:14px; padding:0 15px;"> | 
				
			||||
						<p style="margin:0;padding:0 0 9px 0;">Please click following link to reset your password within <b>{{.ActiveCodeLives}} hours</b>.</p> | 
				
			||||
						<p style="margin:0;padding:0 0 9px 0;"> | 
				
			||||
							<a href="{{.AppUrl}}user/reset_password?code={{.Code}}">{{.AppUrl}}user/reset_password?code={{.Code}}</a> | 
				
			||||
						</p> | 
				
			||||
						<p style="margin:0;padding:0 0 9px 0;">Copy and paste it to your browser if the link is not working.</p> | 
				
			||||
                    </div> | 
				
			||||
                </div> | 
				
			||||
            </div> | 
				
			||||
        </div> | 
				
			||||
        <div style="color:#aaa;padding:10px;text-align:center;"> | 
				
			||||
            © 2014 <a style="color:#888;text-decoration:none;" target="_blank" href="http://gogits.org">Gogs: Go Git Service</a> | 
				
			||||
        </div> | 
				
			||||
    </div> | 
				
			||||
</div> | 
				
			||||
</body> | 
				
			||||
</html> | 
				
			||||
@ -1,25 +0,0 @@ | 
				
			||||
{{template "mail/base.html" .}} | 
				
			||||
{{define "title"}} | 
				
			||||
	{{if eq .Lang "zh-CN"}} | 
				
			||||
		 {{.User.NickName}},重置账户密码 | 
				
			||||
	{{end}} | 
				
			||||
	{{if eq .Lang "en-US"}} | 
				
			||||
		{{.User.NickName}}, reset your password | 
				
			||||
	{{end}} | 
				
			||||
{{end}} | 
				
			||||
{{define "body"}} | 
				
			||||
	{{if eq .Lang "zh-CN"}} | 
				
			||||
		<p style="margin:0;padding:0 0 9px 0;">点击链接重置密码,{{.ResetPwdCodeLives}} 分钟内有效</p> | 
				
			||||
		<p style="margin:0;padding:0 0 9px 0;"> | 
				
			||||
			<a href="{{.AppUrl}}reset/{{.Code}}">{{.AppUrl}}reset/{{.Code}}</a> | 
				
			||||
		</p> | 
				
			||||
		<p style="margin:0;padding:0 0 9px 0;">如果链接点击无反应,请复制到浏览器打开。</p> | 
				
			||||
	{{end}} | 
				
			||||
	{{if eq .Lang "en-US"}} | 
				
			||||
		<p style="margin:0;padding:0 0 9px 0;">Please click following link to reset your password in {{.ResetPwdCodeLives}} hours</p> | 
				
			||||
		<p style="margin:0;padding:0 0 9px 0;"> | 
				
			||||
			<a href="{{.AppUrl}}reset/{{.Code}}">{{.AppUrl}}reset/{{.Code}}</a> | 
				
			||||
		</p> | 
				
			||||
		<p style="margin:0;padding:0 0 9px 0;">Copy and paste it to your browser if it's not working.</p> | 
				
			||||
	{{end}} | 
				
			||||
{{end}} | 
				
			||||
@ -0,0 +1,66 @@ | 
				
			||||
{{template "base/head" .}} | 
				
			||||
{{template "base/navbar" .}} | 
				
			||||
{{template "repo/nav" .}} | 
				
			||||
{{template "repo/toolbar" .}} | 
				
			||||
<div id="body" class="container"> | 
				
			||||
    <div id="release"> | 
				
			||||
        <h4 id="release-head">New Release</h4> | 
				
			||||
        <form id="release-new-form" action="" class="form form-inline"> | 
				
			||||
            <div class="form-group"> | 
				
			||||
                <input id="release-tag-name" type="text" class="form-control" placeholder="tag name"/> | 
				
			||||
                <span class="target-at">@</span> | 
				
			||||
                <div class="btn-group" id="release-new-target-select"> | 
				
			||||
                    <button type="button" class="btn btn-default"><i class="fa fa-code-fork fa-lg fa-m"></i> | 
				
			||||
                        <span class="target-text">Target : </span> | 
				
			||||
                        <strong id="release-new-target-name"> master</strong> | 
				
			||||
                    </button> | 
				
			||||
                    <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"> | 
				
			||||
                        <span class="caret"></span> | 
				
			||||
                    </button> | 
				
			||||
                    <div class="dropdown-menu clone-group-btn" id="release-new-target-branch-list"> | 
				
			||||
                        <ul class="list-group"> | 
				
			||||
                            <li class="list-group-item"> | 
				
			||||
                                <a href="#" rel="master"><i class="fa fa-code-fork"></i>master</a> | 
				
			||||
                            </li> | 
				
			||||
                        </ul> | 
				
			||||
                    </div> | 
				
			||||
                </div> | 
				
			||||
                <p class="help-block">Choose an existing tag without release notes</p> | 
				
			||||
            </div> | 
				
			||||
            <div class="form-group" style="display: block"> | 
				
			||||
                <input class="form-control input-lg" id="release-new-title" name="title" type="text" placeholder="release title"/> | 
				
			||||
            </div> | 
				
			||||
            <div class="form-group col-md-8" style="display: block" id="release-new-content-div"> | 
				
			||||
                <div class="md-help pull-right"> | 
				
			||||
                    Content with <a href="https://help.github.com/articles/markdown-basics">Markdown</a> | 
				
			||||
                </div> | 
				
			||||
                <ul class="nav nav-tabs" data-init="tabs"> | 
				
			||||
                    <li class="release-write active"><a href="#release-textarea" data-toggle="tab">Write</a></li> | 
				
			||||
                    <li class="release-preview"><a href="#release-preview" data-toggle="tab" data-ajax="/api/v1/markdown?repo=repo_id&release=new" data-ajax-name="release-preview" data-ajax-method="post" data-preview="#release-preview">Preview</a></li> | 
				
			||||
                </ul> | 
				
			||||
                <div class="tab-content"> | 
				
			||||
                    <div class="tab-pane active" id="release-textarea"> | 
				
			||||
                        <div class="form-group"> | 
				
			||||
                            <textarea class="form-control" name="content" id="release-new-content" rows="10" placeholder="Write some content" data-ajax-rel="release-preview" data-ajax-val="val" data-ajax-field="content"></textarea> | 
				
			||||
                        </div> | 
				
			||||
                    </div> | 
				
			||||
                    <div class="tab-pane release-preview-content" id="release-preview">loading...</div> | 
				
			||||
                </div> | 
				
			||||
            </div> | 
				
			||||
            <div class="text-right form-group col-md-8" style="display: block"> | 
				
			||||
                <hr/> | 
				
			||||
                <label for="release-new-pre-release"> | 
				
			||||
                    <input id="release-new-pre-release" type="checkbox" name="is-pre-release" value="true"/> | 
				
			||||
                    <strong>This is a pre-release</strong> | 
				
			||||
                </label> | 
				
			||||
                <p class="help-block">We’ll point out that this release is identified as non-production ready.</p> | 
				
			||||
            </div> | 
				
			||||
            <div class="text-right form-group col-md-8" style="display: block"> | 
				
			||||
                <input type="hidden" value="id" name="repo-id"> | 
				
			||||
                <button class="btn-success btn">Publish release</button> | 
				
			||||
                <input class="btn btn-default" type="submit" name="is-draft" value="Save Draft"/> | 
				
			||||
            </div> | 
				
			||||
        </form> | 
				
			||||
    </div> | 
				
			||||
</div> | 
				
			||||
{{template "base/footer" .}} | 
				
			||||
@ -0,0 +1,30 @@ | 
				
			||||
{{template "base/head" .}} | 
				
			||||
{{template "base/navbar" .}} | 
				
			||||
<div id="body" class="container"> | 
				
			||||
    <form action="/user/forget_password" method="post" class="form-horizontal card" id="login-card"> | 
				
			||||
        {{.CsrfTokenHtml}} | 
				
			||||
        <h3>Reset Your Password</h3> | 
				
			||||
        <div class="alert alert-danger form-error{{if .HasError}}{{else}} hidden{{end}}">{{.ErrorMsg}}</div> | 
				
			||||
        {{if .IsResetSent}} | 
				
			||||
        <p>A confirmation e-mail has been sent to <b>{{.Email}}</b>, please check your inbox within {{.Hours}} hours.</p> | 
				
			||||
        <hr/> | 
				
			||||
        <a href="http://{{Mail2Domain .Email}}" class="btn btn-lg btn-success">Sign in to your e-mail</a> | 
				
			||||
        {{else if .IsResetRequest}} | 
				
			||||
        <div class="form-group {{if .Err_Email}}has-error has-feedback{{end}}"> | 
				
			||||
            <label class="col-md-3 control-label">Email: </label> | 
				
			||||
            <div class="col-md-7"> | 
				
			||||
                <input name="email" class="form-control" placeholder="Type your e-mail address" required="required"> | 
				
			||||
            </div> | 
				
			||||
        </div> | 
				
			||||
        <hr/> | 
				
			||||
        <div class="form-group"> | 
				
			||||
            <div class="col-md-offset-4 col-md-6"> | 
				
			||||
                <button type="submit" class="btn btn-lg btn-primary">Click here to send reset confirmation e-mail</button> | 
				
			||||
            </div> | 
				
			||||
        </div> | 
				
			||||
        {{else if .IsResetDisable}} | 
				
			||||
        <p>Sorry, mail service is not enabled.</p> | 
				
			||||
        {{end}} | 
				
			||||
    </form> | 
				
			||||
</div> | 
				
			||||
{{template "base/footer" .}} | 
				
			||||
@ -0,0 +1,26 @@ | 
				
			||||
{{template "base/head" .}} | 
				
			||||
{{template "base/navbar" .}} | 
				
			||||
<div id="body" class="container"> | 
				
			||||
    <form action="/user/reset_password?code={{.Code}}" method="post" class="form-horizontal card" id="login-card"> | 
				
			||||
        {{.CsrfTokenHtml}} | 
				
			||||
        <h3>Reset Your Pasword</h3> | 
				
			||||
        <div class="alert alert-danger form-error{{if .HasError}}{{else}} hidden{{end}}">{{.ErrorMsg}}</div> | 
				
			||||
        {{if .IsResetForm}} | 
				
			||||
        <div class="form-group"> | 
				
			||||
            <label class="col-md-4 control-label">Password: </label> | 
				
			||||
            <div class="col-md-6"> | 
				
			||||
                <input name="passwd" type="password" class="form-control" placeholder="Type your password" required="required"> | 
				
			||||
            </div> | 
				
			||||
        </div> | 
				
			||||
        <hr/> | 
				
			||||
        <div class="form-group"> | 
				
			||||
            <div class="col-md-offset-4 col-md-6"> | 
				
			||||
                <button type="submit" class="btn btn-lg btn-primary">Click here to reset your password</button> | 
				
			||||
            </div> | 
				
			||||
        </div> | 
				
			||||
        {{else}} | 
				
			||||
        <p>Sorry, your confirmation code has been exipired or not valid.</p> | 
				
			||||
        {{end}} | 
				
			||||
    </form> | 
				
			||||
</div> | 
				
			||||
{{template "base/footer" .}} | 
				
			||||
					Loading…
					
					
				
		Reference in new issue