merge with branch master
This commit is contained in:
commit
4bac361605
58 changed files with 1870 additions and 546 deletions
|
@ -61,6 +61,7 @@ func (f *RegisterForm) Validate(errors *binding.Errors, req *http.Request, conte
|
|||
type LogInForm struct {
|
||||
UserName string `form:"username" binding:"Required;AlphaDash;MaxSize(30)"`
|
||||
Password string `form:"passwd" binding:"Required;MinSize(6);MaxSize(30)"`
|
||||
Remember string `form:"remember"`
|
||||
}
|
||||
|
||||
func (f *LogInForm) Name(field string) string {
|
||||
|
|
54
modules/auth/issue.go
Normal file
54
modules/auth/issue.go
Normal file
|
@ -0,0 +1,54 @@
|
|||
// 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 auth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
"github.com/codegangsta/martini"
|
||||
|
||||
"github.com/gogits/binding"
|
||||
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
)
|
||||
|
||||
type CreateIssueForm struct {
|
||||
IssueName string `form:"name" binding:"Required;MaxSize(50)"`
|
||||
RepoId int64 `form:"repoid" binding:"Required"`
|
||||
MilestoneId int64 `form:"milestoneid" binding:"Required"`
|
||||
AssigneeId int64 `form:"assigneeid"`
|
||||
Labels string `form:"labels"`
|
||||
Content string `form:"content"`
|
||||
}
|
||||
|
||||
func (f *CreateIssueForm) Name(field string) string {
|
||||
names := map[string]string{
|
||||
"IssueName": "Issue name",
|
||||
"RepoId": "Repository ID",
|
||||
"MilestoneId": "Milestone ID",
|
||||
}
|
||||
return names[field]
|
||||
}
|
||||
|
||||
func (f *CreateIssueForm) Validate(errors *binding.Errors, req *http.Request, context martini.Context) {
|
||||
if req.Method == "GET" || errors.Count() == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
|
||||
data["HasError"] = true
|
||||
AssignForm(f, data)
|
||||
|
||||
if len(errors.Overall) > 0 {
|
||||
for _, err := range errors.Overall {
|
||||
log.Error("CreateIssueForm.Validate: %v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
validate(errors, data, f)
|
||||
}
|
|
@ -9,7 +9,8 @@ import (
|
|||
"reflect"
|
||||
|
||||
"github.com/codegangsta/martini"
|
||||
"github.com/martini-contrib/sessions"
|
||||
|
||||
"github.com/gogits/session"
|
||||
|
||||
"github.com/gogits/binding"
|
||||
|
||||
|
@ -19,7 +20,7 @@ import (
|
|||
)
|
||||
|
||||
// SignedInId returns the id of signed in user.
|
||||
func SignedInId(session sessions.Session) int64 {
|
||||
func SignedInId(session session.SessionStore) int64 {
|
||||
userId := session.Get("userId")
|
||||
if userId == nil {
|
||||
return 0
|
||||
|
@ -34,7 +35,7 @@ func SignedInId(session sessions.Session) int64 {
|
|||
}
|
||||
|
||||
// SignedInName returns the name of signed in user.
|
||||
func SignedInName(session sessions.Session) string {
|
||||
func SignedInName(session session.SessionStore) string {
|
||||
userName := session.Get("userName")
|
||||
if userName == nil {
|
||||
return ""
|
||||
|
@ -46,7 +47,7 @@ func SignedInName(session sessions.Session) string {
|
|||
}
|
||||
|
||||
// SignedInUser returns the user object of signed user.
|
||||
func SignedInUser(session sessions.Session) *models.User {
|
||||
func SignedInUser(session session.SessionStore) *models.User {
|
||||
id := SignedInId(session)
|
||||
if id <= 0 {
|
||||
return nil
|
||||
|
@ -61,7 +62,7 @@ func SignedInUser(session sessions.Session) *models.User {
|
|||
}
|
||||
|
||||
// IsSignedIn check if any user has signed in.
|
||||
func IsSignedIn(session sessions.Session) bool {
|
||||
func IsSignedIn(session session.SessionStore) bool {
|
||||
return SignedInId(session) > 0
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/Unknwon/goconfig"
|
||||
|
||||
"github.com/gogits/cache"
|
||||
"github.com/gogits/session"
|
||||
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
)
|
||||
|
@ -37,21 +38,35 @@ var (
|
|||
RunUser string
|
||||
RepoRootPath string
|
||||
|
||||
EnableHttpsClone bool
|
||||
|
||||
LogInRememberDays int
|
||||
CookieUserName string
|
||||
CookieRememberName string
|
||||
|
||||
Cfg *goconfig.ConfigFile
|
||||
MailService *Mailer
|
||||
|
||||
LogMode string
|
||||
LogConfig string
|
||||
|
||||
Cache cache.Cache
|
||||
CacheAdapter string
|
||||
CacheConfig string
|
||||
|
||||
LogMode string
|
||||
LogConfig string
|
||||
SessionProvider string
|
||||
SessionConfig *session.Config
|
||||
SessionManager *session.Manager
|
||||
|
||||
PictureService string
|
||||
PictureRootPath string
|
||||
)
|
||||
|
||||
var Service struct {
|
||||
RegisterEmailConfirm bool
|
||||
DisenableRegisteration bool
|
||||
RequireSignInView bool
|
||||
EnableCacheAvatar bool
|
||||
ActiveCodeLives int
|
||||
ResetPwdCodeLives int
|
||||
}
|
||||
|
@ -82,6 +97,7 @@ func newService() {
|
|||
Service.ResetPwdCodeLives = Cfg.MustInt("service", "RESET_PASSWD_CODE_LIVE_MINUTES", 180)
|
||||
Service.DisenableRegisteration = Cfg.MustBool("service", "DISENABLE_REGISTERATION", false)
|
||||
Service.RequireSignInView = Cfg.MustBool("service", "REQUIRE_SIGNIN_VIEW", false)
|
||||
Service.EnableCacheAvatar = Cfg.MustBool("service", "ENABLE_CACHE_AVATAR", false)
|
||||
}
|
||||
|
||||
func newLogService() {
|
||||
|
@ -129,6 +145,10 @@ func newLogService() {
|
|||
Cfg.MustValue(modeSec, "HOST", "127.0.0.1:25"),
|
||||
Cfg.MustValue(modeSec, "RECEIVERS", "[]"),
|
||||
Cfg.MustValue(modeSec, "SUBJECT", "Diagnostic message from serve"))
|
||||
case "database":
|
||||
LogConfig = fmt.Sprintf(`{"level":%s,"driver":%s,"conn":%s}`, level,
|
||||
Cfg.MustValue(modeSec, "Driver"),
|
||||
Cfg.MustValue(modeSec, "CONN"))
|
||||
}
|
||||
|
||||
log.NewLogger(Cfg.MustInt64("log", "BUFFER_LEN", 10000), LogMode, LogConfig)
|
||||
|
@ -159,6 +179,34 @@ func newCacheService() {
|
|||
log.Info("Cache Service Enabled")
|
||||
}
|
||||
|
||||
func newSessionService() {
|
||||
SessionProvider = Cfg.MustValue("session", "PROVIDER", "memory")
|
||||
|
||||
SessionConfig = new(session.Config)
|
||||
SessionConfig.ProviderConfig = Cfg.MustValue("session", "PROVIDER_CONFIG")
|
||||
SessionConfig.CookieName = Cfg.MustValue("session", "COOKIE_NAME", "i_like_gogits")
|
||||
SessionConfig.CookieSecure = Cfg.MustBool("session", "COOKIE_SECURE")
|
||||
SessionConfig.EnableSetCookie = Cfg.MustBool("session", "ENABLE_SET_COOKIE", true)
|
||||
SessionConfig.GcIntervalTime = Cfg.MustInt64("session", "GC_INTERVAL_TIME", 86400)
|
||||
SessionConfig.SessionLifeTime = Cfg.MustInt64("session", "SESSION_LIFE_TIME", 86400)
|
||||
SessionConfig.SessionIDHashFunc = Cfg.MustValue("session", "SESSION_ID_HASHFUNC", "sha1")
|
||||
SessionConfig.SessionIDHashKey = Cfg.MustValue("session", "SESSION_ID_HASHKEY")
|
||||
|
||||
if SessionProvider == "file" {
|
||||
os.MkdirAll(path.Dir(SessionConfig.ProviderConfig), os.ModePerm)
|
||||
}
|
||||
|
||||
var err error
|
||||
SessionManager, err = session.NewManager(SessionProvider, *SessionConfig)
|
||||
if err != nil {
|
||||
fmt.Printf("Init session system failed, provider: %s, %v\n",
|
||||
SessionProvider, err)
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
log.Info("Session Service Enabled")
|
||||
}
|
||||
|
||||
func newMailService() {
|
||||
// Check mailer setting.
|
||||
if Cfg.MustBool("mailer", "ENABLED") {
|
||||
|
@ -214,6 +262,15 @@ func NewConfigContext() {
|
|||
SecretKey = Cfg.MustValue("security", "SECRET_KEY")
|
||||
RunUser = Cfg.MustValue("", "RUN_USER")
|
||||
|
||||
EnableHttpsClone = Cfg.MustBool("security", "ENABLE_HTTPS_CLONE", false)
|
||||
|
||||
LogInRememberDays = Cfg.MustInt("security", "LOGIN_REMEMBER_DAYS")
|
||||
CookieUserName = Cfg.MustValue("security", "COOKIE_USERNAME")
|
||||
CookieRememberName = Cfg.MustValue("security", "COOKIE_REMEMBER_NAME")
|
||||
|
||||
PictureService = Cfg.MustValue("picture", "SERVICE")
|
||||
PictureRootPath = Cfg.MustValue("picture", "PATH")
|
||||
|
||||
// Determine and create root git reposiroty path.
|
||||
RepoRootPath = Cfg.MustValue("repository", "ROOT")
|
||||
if err = os.MkdirAll(RepoRootPath, os.ModePerm); err != nil {
|
||||
|
@ -226,6 +283,7 @@ func NewServices() {
|
|||
newService()
|
||||
newLogService()
|
||||
newCacheService()
|
||||
newSessionService()
|
||||
newMailService()
|
||||
newRegisterMailService()
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ func (options *CustomRender) Link(out *bytes.Buffer, link []byte, title []byte,
|
|||
|
||||
func RenderMarkdown(rawBytes []byte, urlPrefix string) []byte {
|
||||
htmlFlags := 0
|
||||
htmlFlags |= gfm.HTML_USE_XHTML
|
||||
// htmlFlags |= gfm.HTML_USE_XHTML
|
||||
// htmlFlags |= gfm.HTML_USE_SMARTYPANTS
|
||||
// htmlFlags |= gfm.HTML_SMARTYPANTS_FRACTIONS
|
||||
// htmlFlags |= gfm.HTML_SMARTYPANTS_LATEX_DASHES
|
||||
|
@ -81,7 +81,7 @@ func RenderMarkdown(rawBytes []byte, urlPrefix string) []byte {
|
|||
htmlFlags |= gfm.HTML_SKIP_SCRIPT
|
||||
htmlFlags |= gfm.HTML_GITHUB_BLOCKCODE
|
||||
htmlFlags |= gfm.HTML_OMIT_CONTENTS
|
||||
htmlFlags |= gfm.HTML_COMPLETE_PAGE
|
||||
// htmlFlags |= gfm.HTML_COMPLETE_PAGE
|
||||
renderer := &CustomRender{
|
||||
Renderer: gfm.HtmlRenderer(htmlFlags, "", ""),
|
||||
urlPrefix: urlPrefix,
|
||||
|
|
|
@ -25,13 +25,17 @@ func EncodeMd5(str string) string {
|
|||
return hex.EncodeToString(m.Sum(nil))
|
||||
}
|
||||
|
||||
// Random generate string
|
||||
func GetRandomString(n int) string {
|
||||
// GetRandomString generate random string by specify chars.
|
||||
func GetRandomString(n int, alphabets ...byte) string {
|
||||
const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
var bytes = make([]byte, n)
|
||||
rand.Read(bytes)
|
||||
for i, b := range bytes {
|
||||
bytes[i] = alphanum[b%byte(len(alphanum))]
|
||||
if len(alphabets) == 0 {
|
||||
bytes[i] = alphanum[b%byte(len(alphanum))]
|
||||
} else {
|
||||
bytes[i] = alphabets[b%byte(len(alphabets))]
|
||||
}
|
||||
}
|
||||
return string(bytes)
|
||||
}
|
||||
|
@ -111,6 +115,85 @@ const (
|
|||
Year = 12 * Month
|
||||
)
|
||||
|
||||
func computeTimeDiff(diff int64) (int64, string) {
|
||||
diffStr := ""
|
||||
switch {
|
||||
case diff <= 0:
|
||||
diff = 0
|
||||
diffStr = "now"
|
||||
case diff < 2:
|
||||
diff = 0
|
||||
diffStr = "1 second"
|
||||
case diff < 1*Minute:
|
||||
diffStr = fmt.Sprintf("%d seconds", diff)
|
||||
diff = 0
|
||||
|
||||
case diff < 2*Minute:
|
||||
diff -= 1 * Minute
|
||||
diffStr = "1 minute"
|
||||
case diff < 1*Hour:
|
||||
diffStr = fmt.Sprintf("%d minutes", diff/Minute)
|
||||
diff -= diff / Minute * Minute
|
||||
|
||||
case diff < 2*Hour:
|
||||
diff -= 1 * Hour
|
||||
diffStr = "1 hour"
|
||||
case diff < 1*Day:
|
||||
diffStr = fmt.Sprintf("%d hours", diff/Hour)
|
||||
diff -= diff / Hour * Hour
|
||||
|
||||
case diff < 2*Day:
|
||||
diff -= 1 * Day
|
||||
diffStr = "1 day"
|
||||
case diff < 1*Week:
|
||||
diffStr = fmt.Sprintf("%d days", diff/Day)
|
||||
diff -= diff / Day * Day
|
||||
|
||||
case diff < 2*Week:
|
||||
diff -= 1 * Week
|
||||
diffStr = "1 week"
|
||||
case diff < 1*Month:
|
||||
diffStr = fmt.Sprintf("%d weeks", diff/Week)
|
||||
diff -= diff / Week * Week
|
||||
|
||||
case diff < 2*Month:
|
||||
diff -= 1 * Month
|
||||
diffStr = "1 month"
|
||||
case diff < 1*Year:
|
||||
diffStr = fmt.Sprintf("%d months", diff/Month)
|
||||
diff -= diff / Month * Month
|
||||
|
||||
case diff < 2*Year:
|
||||
diff -= 1 * Year
|
||||
diffStr = "1 year"
|
||||
default:
|
||||
diffStr = fmt.Sprintf("%d years", diff/Year)
|
||||
diff = 0
|
||||
}
|
||||
return diff, diffStr
|
||||
}
|
||||
|
||||
// TimeSincePro calculates the time interval and generate full user-friendly string.
|
||||
func TimeSincePro(then time.Time) string {
|
||||
now := time.Now()
|
||||
diff := now.Unix() - then.Unix()
|
||||
|
||||
if then.After(now) {
|
||||
return "future"
|
||||
}
|
||||
|
||||
var timeStr, diffStr string
|
||||
for {
|
||||
if diff == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
diff, diffStr = computeTimeDiff(diff)
|
||||
timeStr += ", " + diffStr
|
||||
}
|
||||
return strings.TrimPrefix(timeStr, ", ")
|
||||
}
|
||||
|
||||
// TimeSince calculates the time interval and generate user-friendly string.
|
||||
func TimeSince(then time.Time) string {
|
||||
now := time.Now()
|
||||
|
@ -123,7 +206,6 @@ func TimeSince(then time.Time) string {
|
|||
}
|
||||
|
||||
switch {
|
||||
|
||||
case diff <= 0:
|
||||
return "now"
|
||||
case diff <= 2:
|
||||
|
@ -156,8 +238,10 @@ func TimeSince(then time.Time) string {
|
|||
case diff < 1*Year:
|
||||
return fmt.Sprintf("%d months %s", diff/Month, lbl)
|
||||
|
||||
case diff < 18*Month:
|
||||
case diff < 2*Year:
|
||||
return fmt.Sprintf("1 year %s", lbl)
|
||||
default:
|
||||
return fmt.Sprintf("%d years %s", diff/Year, lbl)
|
||||
}
|
||||
return then.String()
|
||||
}
|
||||
|
@ -387,6 +471,7 @@ type Actioner interface {
|
|||
GetOpType() int
|
||||
GetActUserName() string
|
||||
GetRepoName() string
|
||||
GetBranch() string
|
||||
GetContent() string
|
||||
}
|
||||
|
||||
|
@ -409,25 +494,34 @@ const (
|
|||
TPL_COMMIT_REPO_LI = `<div><img id="gogs-user-avatar-commit" src="%s?s=16" alt="user-avatar" title="username"/> <a href="/%s/%s/commit/%s">%s</a> %s</div>`
|
||||
)
|
||||
|
||||
type PushCommits struct {
|
||||
Len int
|
||||
Commits [][]string
|
||||
}
|
||||
|
||||
// ActionDesc accepts int that represents action operation type
|
||||
// and returns the description.
|
||||
func ActionDesc(act Actioner, avatarLink string) string {
|
||||
actUserName := act.GetActUserName()
|
||||
repoName := act.GetRepoName()
|
||||
branch := act.GetBranch()
|
||||
content := act.GetContent()
|
||||
switch act.GetOpType() {
|
||||
case 1: // Create repository.
|
||||
return fmt.Sprintf(TPL_CREATE_REPO, actUserName, actUserName, actUserName, repoName, repoName)
|
||||
case 5: // Commit repository.
|
||||
var commits [][]string
|
||||
if err := json.Unmarshal([]byte(content), &commits); err != nil {
|
||||
var push *PushCommits
|
||||
if err := json.Unmarshal([]byte(content), &push); err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
buf := bytes.NewBuffer([]byte("\n"))
|
||||
for _, commit := range commits {
|
||||
for _, commit := range push.Commits {
|
||||
buf.WriteString(fmt.Sprintf(TPL_COMMIT_REPO_LI, avatarLink, actUserName, repoName, commit[0], commit[0][:7], commit[1]) + "\n")
|
||||
}
|
||||
return fmt.Sprintf(TPL_COMMIT_REPO, actUserName, actUserName, actUserName, repoName, "master", "master", actUserName, repoName, actUserName, repoName,
|
||||
if push.Len > 3 {
|
||||
buf.WriteString(fmt.Sprintf(`<div><a href="/%s/%s/commits/%s">%d other commits >></a></div>`, actUserName, repoName, branch, push.Len))
|
||||
}
|
||||
return fmt.Sprintf(TPL_COMMIT_REPO, actUserName, actUserName, actUserName, repoName, branch, branch, actUserName, repoName, actUserName, repoName,
|
||||
buf.String())
|
||||
default:
|
||||
return "invalid type"
|
||||
|
|
|
@ -5,44 +5,54 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
|
||||
"github.com/codegangsta/martini"
|
||||
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
)
|
||||
|
||||
// SignInRequire requires user to sign in.
|
||||
func SignInRequire(redirect bool) martini.Handler {
|
||||
return func(ctx *Context) {
|
||||
if !ctx.IsSigned {
|
||||
if redirect {
|
||||
ctx.Redirect("/user/login")
|
||||
}
|
||||
return
|
||||
} else if !ctx.User.IsActive && base.Service.RegisterEmailConfirm {
|
||||
ctx.Data["Title"] = "Activate Your Account"
|
||||
ctx.HTML(200, "user/active")
|
||||
return
|
||||
}
|
||||
}
|
||||
type ToggleOptions struct {
|
||||
SignInRequire bool
|
||||
SignOutRequire bool
|
||||
AdminRequire bool
|
||||
DisableCsrf bool
|
||||
}
|
||||
|
||||
// SignOutRequire requires user to sign out.
|
||||
func SignOutRequire() martini.Handler {
|
||||
func Toggle(options *ToggleOptions) martini.Handler {
|
||||
return func(ctx *Context) {
|
||||
if ctx.IsSigned {
|
||||
if options.SignOutRequire && ctx.IsSigned {
|
||||
ctx.Redirect("/")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AdminRequire requires user signed in as administor.
|
||||
func AdminRequire() martini.Handler {
|
||||
return func(ctx *Context) {
|
||||
if !ctx.User.IsAdmin {
|
||||
ctx.Error(403)
|
||||
return
|
||||
if !options.DisableCsrf {
|
||||
if ctx.Req.Method == "POST" {
|
||||
if !ctx.CsrfTokenValid() {
|
||||
ctx.Error(403, "CSRF token does not match")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if options.SignInRequire {
|
||||
if !ctx.IsSigned {
|
||||
ctx.SetCookie("redirect_to", "/"+url.QueryEscape(ctx.Req.RequestURI))
|
||||
ctx.Redirect("/user/login")
|
||||
return
|
||||
} else if !ctx.User.IsActive && base.Service.RegisterEmailConfirm {
|
||||
ctx.Data["Title"] = "Activate Your Account"
|
||||
ctx.HTML(200, "user/active")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if options.AdminRequire {
|
||||
if !ctx.User.IsAdmin {
|
||||
ctx.Error(403)
|
||||
return
|
||||
}
|
||||
ctx.Data["PageIsAdmin"] = true
|
||||
}
|
||||
ctx.Data["PageIsAdmin"] = true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,14 +5,20 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/codegangsta/martini"
|
||||
"github.com/martini-contrib/sessions"
|
||||
|
||||
"github.com/gogits/cache"
|
||||
"github.com/gogits/session"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/auth"
|
||||
|
@ -27,11 +33,13 @@ type Context struct {
|
|||
p martini.Params
|
||||
Req *http.Request
|
||||
Res http.ResponseWriter
|
||||
Session sessions.Session
|
||||
Session session.SessionStore
|
||||
Cache cache.Cache
|
||||
User *models.User
|
||||
IsSigned bool
|
||||
|
||||
csrfToken string
|
||||
|
||||
Repo struct {
|
||||
IsValid bool
|
||||
IsOwner bool
|
||||
|
@ -90,23 +98,157 @@ func (ctx *Context) Handle(status int, title string, err error) {
|
|||
ctx.HTML(status, fmt.Sprintf("status/%d", status))
|
||||
}
|
||||
|
||||
func (ctx *Context) GetCookie(name string) string {
|
||||
cookie, err := ctx.Req.Cookie(name)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return cookie.Value
|
||||
}
|
||||
|
||||
func (ctx *Context) SetCookie(name string, value string, others ...interface{}) {
|
||||
cookie := http.Cookie{}
|
||||
cookie.Name = name
|
||||
cookie.Value = value
|
||||
|
||||
if len(others) > 0 {
|
||||
switch v := others[0].(type) {
|
||||
case int:
|
||||
cookie.MaxAge = v
|
||||
case int64:
|
||||
cookie.MaxAge = int(v)
|
||||
case int32:
|
||||
cookie.MaxAge = int(v)
|
||||
}
|
||||
}
|
||||
|
||||
// default "/"
|
||||
if len(others) > 1 {
|
||||
if v, ok := others[1].(string); ok && len(v) > 0 {
|
||||
cookie.Path = v
|
||||
}
|
||||
} else {
|
||||
cookie.Path = "/"
|
||||
}
|
||||
|
||||
// default empty
|
||||
if len(others) > 2 {
|
||||
if v, ok := others[2].(string); ok && len(v) > 0 {
|
||||
cookie.Domain = v
|
||||
}
|
||||
}
|
||||
|
||||
// default empty
|
||||
if len(others) > 3 {
|
||||
switch v := others[3].(type) {
|
||||
case bool:
|
||||
cookie.Secure = v
|
||||
default:
|
||||
if others[3] != nil {
|
||||
cookie.Secure = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// default false. for session cookie default true
|
||||
if len(others) > 4 {
|
||||
if v, ok := others[4].(bool); ok && v {
|
||||
cookie.HttpOnly = true
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Res.Header().Add("Set-Cookie", cookie.String())
|
||||
}
|
||||
|
||||
// Get secure cookie from request by a given key.
|
||||
func (ctx *Context) GetSecureCookie(Secret, key string) (string, bool) {
|
||||
val := ctx.GetCookie(key)
|
||||
if val == "" {
|
||||
return "", false
|
||||
}
|
||||
|
||||
parts := strings.SplitN(val, "|", 3)
|
||||
|
||||
if len(parts) != 3 {
|
||||
return "", false
|
||||
}
|
||||
|
||||
vs := parts[0]
|
||||
timestamp := parts[1]
|
||||
sig := parts[2]
|
||||
|
||||
h := hmac.New(sha1.New, []byte(Secret))
|
||||
fmt.Fprintf(h, "%s%s", vs, timestamp)
|
||||
|
||||
if fmt.Sprintf("%02x", h.Sum(nil)) != sig {
|
||||
return "", false
|
||||
}
|
||||
res, _ := base64.URLEncoding.DecodeString(vs)
|
||||
return string(res), true
|
||||
}
|
||||
|
||||
// Set Secure cookie for response.
|
||||
func (ctx *Context) SetSecureCookie(Secret, name, value string, others ...interface{}) {
|
||||
vs := base64.URLEncoding.EncodeToString([]byte(value))
|
||||
timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
|
||||
h := hmac.New(sha1.New, []byte(Secret))
|
||||
fmt.Fprintf(h, "%s%s", vs, timestamp)
|
||||
sig := fmt.Sprintf("%02x", h.Sum(nil))
|
||||
cookie := strings.Join([]string{vs, timestamp, sig}, "|")
|
||||
ctx.SetCookie(name, cookie, others...)
|
||||
}
|
||||
|
||||
func (ctx *Context) CsrfToken() string {
|
||||
if len(ctx.csrfToken) > 0 {
|
||||
return ctx.csrfToken
|
||||
}
|
||||
|
||||
token := ctx.GetCookie("_csrf")
|
||||
if len(token) == 0 {
|
||||
token = base.GetRandomString(30)
|
||||
ctx.SetCookie("_csrf", token)
|
||||
}
|
||||
ctx.csrfToken = token
|
||||
return token
|
||||
}
|
||||
|
||||
func (ctx *Context) CsrfTokenValid() bool {
|
||||
token := ctx.Query("_csrf")
|
||||
if token == "" {
|
||||
token = ctx.Req.Header.Get("X-Csrf-Token")
|
||||
}
|
||||
if token == "" {
|
||||
return false
|
||||
} else if ctx.csrfToken != token {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// InitContext initializes a classic context for a request.
|
||||
func InitContext() martini.Handler {
|
||||
return func(res http.ResponseWriter, r *http.Request, c martini.Context,
|
||||
session sessions.Session, rd *Render) {
|
||||
return func(res http.ResponseWriter, r *http.Request, c martini.Context, rd *Render) {
|
||||
|
||||
ctx := &Context{
|
||||
c: c,
|
||||
// p: p,
|
||||
Req: r,
|
||||
Res: res,
|
||||
Session: session,
|
||||
Cache: base.Cache,
|
||||
Render: rd,
|
||||
Req: r,
|
||||
Res: res,
|
||||
Cache: base.Cache,
|
||||
Render: rd,
|
||||
}
|
||||
|
||||
ctx.Data["PageStartTime"] = time.Now()
|
||||
|
||||
// start session
|
||||
ctx.Session = base.SessionManager.SessionStart(res, r)
|
||||
rw := res.(martini.ResponseWriter)
|
||||
rw.Before(func(martini.ResponseWriter) {
|
||||
ctx.Session.SessionRelease(res)
|
||||
})
|
||||
|
||||
// Get user from session if logined.
|
||||
user := auth.SignedInUser(session)
|
||||
user := auth.SignedInUser(ctx.Session)
|
||||
ctx.User = user
|
||||
ctx.IsSigned = user != nil
|
||||
|
||||
|
@ -119,7 +261,9 @@ func InitContext() martini.Handler {
|
|||
ctx.Data["IsAdmin"] = ctx.User.IsAdmin
|
||||
}
|
||||
|
||||
ctx.Data["PageStartTime"] = time.Now()
|
||||
// get or create csrf token
|
||||
ctx.Data["CsrfToken"] = ctx.CsrfToken()
|
||||
ctx.Data["CsrfTokenHtml"] = template.HTML(`<input type="hidden" name="_csrf" value="` + ctx.csrfToken + `">`)
|
||||
|
||||
c.Map(ctx)
|
||||
|
||||
|
|
|
@ -242,8 +242,11 @@ func (r *Render) HTMLString(name string, binding interface{}, htmlOpt ...HTMLOpt
|
|||
}
|
||||
}
|
||||
|
||||
func (r *Render) Error(status int) {
|
||||
func (r *Render) Error(status int, message ...string) {
|
||||
r.WriteHeader(status)
|
||||
if len(message) > 0 {
|
||||
r.Write([]byte(message[0]))
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Render) Redirect(location string, status ...int) {
|
||||
|
|
|
@ -54,7 +54,7 @@ func RepoAssignment(redirect bool) martini.Handler {
|
|||
ctx.Repo.Owner = user
|
||||
|
||||
// get repository
|
||||
repo, err := models.GetRepositoryByName(user, params["reponame"])
|
||||
repo, err := models.GetRepositoryByName(user.Id, params["reponame"])
|
||||
if err != nil {
|
||||
if redirect {
|
||||
ctx.Redirect("/")
|
||||
|
@ -69,8 +69,12 @@ func RepoAssignment(redirect bool) martini.Handler {
|
|||
ctx.Repo.IsWatching = models.IsWatching(ctx.User.Id, repo.Id)
|
||||
}
|
||||
ctx.Repo.Repository = repo
|
||||
scheme := "http"
|
||||
if base.EnableHttpsClone {
|
||||
scheme = "https"
|
||||
}
|
||||
ctx.Repo.CloneLink.SSH = fmt.Sprintf("git@%s:%s/%s.git", base.Domain, user.LowerName, repo.LowerName)
|
||||
ctx.Repo.CloneLink.HTTPS = fmt.Sprintf("https://%s/%s/%s.git", base.Domain, user.LowerName, repo.LowerName)
|
||||
ctx.Repo.CloneLink.HTTPS = fmt.Sprintf("%s://%s/%s/%s.git", scheme, base.Domain, user.LowerName, repo.LowerName)
|
||||
|
||||
ctx.Data["IsRepositoryValid"] = true
|
||||
ctx.Data["Repository"] = repo
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue