diff --git a/.gitignore b/.gitignore
index f8d8a2869..65252f8c2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,7 @@ public/img/avatar/
*.o
*.a
*.so
+dev
# Folders
_obj
diff --git a/.gopmfile b/.gopmfile
index 296d02367..c58f4299d 100644
--- a/.gopmfile
+++ b/.gopmfile
@@ -19,6 +19,7 @@ github.com/lib/pq =
github.com/nfnt/resize =
github.com/qiniu/log =
github.com/robfig/cron =
+github.com/juju2013/goldap =
[res]
include = templates|public|conf
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index cfc6c14f2..6cc88515f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -10,6 +10,8 @@ Want to hack on Gogs? Awesome! Here are instructions to get you started. They ar
### Pull requests are always welcome
+**ALL PULL REQUESTS MUST SEND TO `DEV` BRANCH**
+
We are always thrilled to receive pull requests, and do our best to process them as fast as possible. Not sure if that typo is worth a pull request? Do it! We will appreciate it.
If your pull request is not accepted on the first try, don't be discouraged! If there's a problem with the implementation, hopefully you received feedback on what to improve.
diff --git a/README.md b/README.md
index 038780721..c16f721aa 100644
--- a/README.md
+++ b/README.md
@@ -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.3.0 Alpha
+##### Current version: 0.3.1 Alpha
### NOTICES
@@ -42,6 +42,11 @@ More importantly, Gogs only needs one binary to setup your own project hosting o
- Supports MySQL, PostgreSQL and SQLite3.
- Social account login(GitHub, Google, QQ, Weibo)
+## System Requirements
+
+- A cheap Raspberry Pi is powerful enough to match the minimal requirement.
+- 4 CPU Cores and 1GB RAM would be the baseline for teamwork.
+
## Installation
Make sure you install [Prerequirements](https://github.com/gogits/gogs/wiki/Prerequirements) first.
diff --git a/README_ZH.md b/README_ZH.md
index 6d7553a68..b82782235 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.3.0 Alpha
+##### 当前版本:0.3.1 Alpha
## 开发目的
@@ -33,6 +33,12 @@ Gogs 完全使用 Go 语言来实现对 Git 数据的操作,实现 **零** 依
- 支持 MySQL、PostgreSQL 以及 SQLite3 数据库
- 社交帐号登录(GitHub、Google、QQ、微博)
+## 系统要求
+
+- 最低的系统硬件要求为一个廉价的树莓派
+- 如果用于团队项目,建议使用 4 核 CPU 及 1GB 内存
+
+
## 安装部署
在安装 Gogs 之前,您需要先安装 [基本环境](https://github.com/gogits/gogs/wiki/Prerequirements)。
diff --git a/conf/app.ini b/conf/app.ini
index 25fd41091..e7174e225 100644
--- a/conf/app.ini
+++ b/conf/app.ini
@@ -16,6 +16,8 @@ LICENSES = Apache v2 License|GPL v2|MIT License|Affero GPL|Artistic License 2.0|
PROTOCOL = http
DOMAIN = localhost
ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/
+; Disable CDN even in "prod" mode
+OFFLINE_MODE = false
HTTP_ADDR =
HTTP_PORT = 3000
; Generate steps:
diff --git a/doc/install_gogs_from_binary_on_ubuntu.md b/doc/install_gogs_from_binary_on_ubuntu.md
new file mode 100644
index 000000000..3b406b364
--- /dev/null
+++ b/doc/install_gogs_from_binary_on_ubuntu.md
@@ -0,0 +1,26 @@
+### Binary install gogs on ubuntu 14.04 LTS
+
+### create user and install denpendency
+- sudo adduser git
+- sudo apt-get update
+- sudo apt-get upgrade
+- sudo apt-get install git
+- sudo apt-get install mysql-server
+
+### create the database
+- $mysql -u root -p
+- mysql> SET GLOBAL storage_engine = 'InnoDB';
+- mysql> CREATE DATABASE gogs CHARACTER SET utf8 COLLATE utf8_bin;
+- mysql> GRANT ALL PRIVILEGES ON gogs.* TO 'root'@'localhost' IDENTIFIED BY 'password';
+- mysql> FLUSH PRIVILEGES;
+- mysql> QUIT
+
+### install the gogs
+- mkdir gogs
+- cd gogs
+- curl -L http://gobuild.io/github.com/gogits/gogs/v0.3.0/linux/amd64 -o v0.3.0.zip
+- unzip v0.3.0.zip
+- ./start.sh
+
+> The up-to-date binary could be found at
+> http://gobuild.io/download/github.com/gogits/gogs
diff --git a/doc/install_gogs_from_source_on_ubuntu.md b/doc/install_gogs_from_source_on_ubuntu.md
new file mode 100644
index 000000000..b8ae6fc79
--- /dev/null
+++ b/doc/install_gogs_from_source_on_ubuntu.md
@@ -0,0 +1,48 @@
+##Install gogs under ubuntu 14.04 LTS 32bit from source code
+
+###Requirements
+- Go Programming Language: Version >= 1.2
+- git(bash): Version >= 1.6.6(both server and client)
+- MySQL: Version >= 5.1 or PostgreSQL or NOTHING.
+
+### Create the user which will run git
+- sudo adduser git
+- su git
+
+### Install git and Mysql-server
+- sudo apt-get install git
+- sudo apt-get install mysql-server
+
+### Create database
+- $ mysql -u root -p
+- mysql> SET GLOBAL storage_engine = 'InnoDB';
+- mysql> CREATE DATABASE gogs CHARACTER SET utf8 COLLATE utf8_bin;
+- mysql> GRANT ALL PRIVILEGES ON gogs.* TO 'root'@'localhost' IDENTIFIED BY 'pasword';
+- mysql> FLUSH PRIVILEGES;
+- mysql> QUIT
+
+### install go from source
+- sudo apt-get install build-essential
+- sudo apt-get install mercurial
+- hg clone -r release https://go.googlecode.com/hg/ /home/git/golang/
+
+
+- echo export GOROOT=/home/git/golang >>.bashrc
+- echo export GOARCH=386 >>.bashrc
+- echo export GOOS=linux >>.bashrc
+- echo export GOBIN= /home/git/golang/bin >>.bashrc
+- echo export GOPATH=$HOME/app/Go >>.bashrc
+- echo PATH=${PATH}: /$HOME/golang/bin >>.bashrc
+- cd $GOROOT/src
+- ./make.bash
+
+### Download and install dependencies
+- $ go get -u github.com/gogits/gogs
+
+### Build main program
+- $ cd $GOPATH/src/github.com/gogits/gogs
+- $ go build
+- $ ./start.sh
+
+### At present, you could access gogs from http://localhost:3000
+
diff --git a/dockerfiles/README.md b/dockerfiles/README.md
index 83ca3e954..fbd9f7aa1 100644
--- a/dockerfiles/README.md
+++ b/dockerfiles/README.md
@@ -1,6 +1,6 @@
### Install Gogs With Docker
-Deplying gogs in [Docker](http://www.docker.io/) is just as easy as eating a pie, what you do is just open the `dockerfiles/build.sh` file, replace the confis:
+Deploying gogs in [Docker](http://www.docker.io/) is just as easy as eating a pie, what you do is just open the `dockerfiles/build.sh` file, replace the configs:
```
DB_TYPE="YOUR_DB_TYPE" # type of database, support 'mysql' and 'postgres'
diff --git a/dockerfiles/images/gogits/Dockerfile b/dockerfiles/images/gogits/Dockerfile
index a460ca500..087168f5b 100644
--- a/dockerfiles/images/gogits/Dockerfile
+++ b/dockerfiles/images/gogits/Dockerfile
@@ -13,7 +13,7 @@ ENV GOROOT /usr/local/go
ENV GOPATH /go
RUN apt-get update && apt-get install --yes --force-yes curl git mercurial zip wget ca-certificates build-essential
-RUN apt-get install -yq vim
+RUN apt-get install -yq vim sudo
RUN curl -s http://docker.u.qiniudn.com/go1.2.1.src.tar.gz | tar -v -C /usr/local -xz
RUN cd /usr/local/go/src && ./make.bash --no-clean 2>&1
diff --git a/dockerfiles/images/postgres/Dockerfile b/dockerfiles/images/postgres/Dockerfile
index 44e82b7d8..0188dd78f 100644
--- a/dockerfiles/images/postgres/Dockerfile
+++ b/dockerfiles/images/postgres/Dockerfile
@@ -9,7 +9,8 @@ RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys B97B0AFCAA
# Add PostgreSQL's repository. It contains the most recent stable release
# of PostgreSQL, ``9.3``.
-RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main" > /etc/apt/sources.list.d/pgdg.list
+# See http://apt.postgresql.org/pub/repos/apt/README
+RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list
# Update the Ubuntu and PostgreSQL repository indexes
RUN apt-get update
diff --git a/dockerfiles/images/redis/Dockerfile b/dockerfiles/images/redis/Dockerfile
index 7dfcba334..cdbbea21a 100644
--- a/dockerfiles/images/redis/Dockerfile
+++ b/dockerfiles/images/redis/Dockerfile
@@ -1,8 +1,6 @@
FROM ubuntu
MAINTAINER Meaglith Ma (@genedna), Lance Ju (@crystaldust)
-ENV DEBIAN_FRONTEND noninteractive
-
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && apt-get install -y redis-server
diff --git a/gogs.go b/gogs.go
index 73555adab..d723aa33a 100644
--- a/gogs.go
+++ b/gogs.go
@@ -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.3.0.0421 Alpha"
+const APP_VER = "0.3.1.0427 Alpha"
func init() {
base.AppVer = APP_VER
diff --git a/models/issue.go b/models/issue.go
index f14030df5..26b8cecdd 100644
--- a/models/issue.go
+++ b/models/issue.go
@@ -71,7 +71,7 @@ func CreateIssue(userId, repoId, milestoneId, assigneeId int64, issueCount int,
}
if err = sess.Commit(); err != nil {
- sess.Rollback()
+ //sess.Rollback()
return nil, err
}
@@ -196,7 +196,7 @@ func CreateComment(userId, repoId, issueId, commitId, line int64, cmtType int, c
defer sess.Close()
sess.Begin()
- if _, err := orm.Insert(&Comment{PosterId: userId, Type: cmtType, IssueId: issueId,
+ if _, err := sess.Insert(&Comment{PosterId: userId, Type: cmtType, IssueId: issueId,
CommitId: commitId, Line: line, Content: content}); err != nil {
sess.Rollback()
return err
diff --git a/models/ldap.go b/models/ldap.go
new file mode 100644
index 000000000..cc9058765
--- /dev/null
+++ b/models/ldap.go
@@ -0,0 +1,38 @@
+// Copyright github.com/juju2013. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package models
+
+import (
+ "strings"
+
+ "github.com/gogits/gogs/modules/auth/ldap"
+ "github.com/gogits/gogs/modules/log"
+)
+
+// Query if name/passwd can login against the LDAP direcotry pool
+// Create a local user if success
+// Return the same LoginUserPlain semantic
+func LoginUserLdap(name, passwd string) (*User, error) {
+ mail, logged := ldap.LoginUser(name, passwd)
+ if !logged {
+ // user not in LDAP, do nothing
+ return nil, ErrUserNotExist
+ }
+ // fake a local user creation
+ user := User{
+ LowerName: strings.ToLower(name),
+ Name: strings.ToLower(name),
+ LoginType: 389,
+ IsActive: true,
+ Passwd: passwd,
+ Email: mail}
+ _, err := RegisterUser(&user)
+ if err != nil {
+ log.Debug("LDAP local user %s fond (%s) ", name, err)
+ }
+ // simulate local user login
+ localUser, err2 := GetUserByName(user.Name)
+ return localUser, err2
+}
diff --git a/models/publickey.go b/models/publickey.go
index ed47ff209..b80412812 100644
--- a/models/publickey.go
+++ b/models/publickey.go
@@ -77,12 +77,12 @@ func init() {
// PublicKey represents a SSH key of user.
type PublicKey struct {
Id int64
- OwnerId int64 `xorm:"unique(s) index not null"`
- Name string `xorm:"unique(s) not null"`
+ OwnerId int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
+ Name string `xorm:"UNIQUE(s) NOT NULL"`
Fingerprint string
- Content string `xorm:"TEXT not null"`
- Created time.Time `xorm:"created"`
- Updated time.Time `xorm:"updated"`
+ Content string `xorm:"TEXT NOT NULL"`
+ Created time.Time `xorm:"CREATED"`
+ Updated time.Time `xorm:"UPDATED"`
}
// GenAuthorizedKey returns formatted public key string.
@@ -107,9 +107,9 @@ func AddPublicKey(key *PublicKey) (err error) {
if err = ioutil.WriteFile(tmpPath, []byte(key.Content), os.ModePerm); err != nil {
return err
}
- stdout, _, err := com.ExecCmd("ssh-keygen", "-l", "-f", tmpPath)
+ stdout, stderr, err := com.ExecCmd("ssh-keygen", "-l", "-f", tmpPath)
if err != nil {
- return err
+ return errors.New("ssh-keygen -l -f: " + stderr)
} else if len(stdout) < 2 {
return errors.New("Not enough output for calculating fingerprint")
}
diff --git a/models/repo.go b/models/repo.go
index 19fe6e288..5f66bca86 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -47,16 +47,16 @@ func NewRepoContext() {
zip.Verbose = false
// Check if server has basic git setting.
- stdout, _, err := com.ExecCmd("git", "config", "--get", "user.name")
- if err != nil {
- fmt.Printf("repo.init(fail to get git user.name): %v", err)
+ stdout, stderr, err := com.ExecCmd("git", "config", "--get", "user.name")
+ if strings.Contains(stderr, "fatal:") {
+ fmt.Printf("repo.NewRepoContext(fail to get git user.name): %s", stderr)
os.Exit(2)
- } else if len(stdout) == 0 {
- if _, _, err = com.ExecCmd("git", "config", "--global", "user.email", "gogitservice@gmail.com"); err != nil {
- fmt.Printf("repo.init(fail to set git user.email): %v", err)
+ } else if err != nil || len(strings.TrimSpace(stdout)) == 0 {
+ if _, stderr, err = com.ExecCmd("git", "config", "--global", "user.email", "gogitservice@gmail.com"); err != nil {
+ fmt.Printf("repo.NewRepoContext(fail to set git user.email): %s", stderr)
os.Exit(2)
- } else if _, _, err = com.ExecCmd("git", "config", "--global", "user.name", "Gogs"); err != nil {
- fmt.Printf("repo.init(fail to set git user.name): %v", err)
+ } else if _, stderr, err = com.ExecCmd("git", "config", "--global", "user.name", "Gogs"); err != nil {
+ fmt.Printf("repo.NewRepoContext(fail to set git user.name): %s", stderr)
os.Exit(2)
}
}
@@ -159,9 +159,7 @@ func MirrorUpdate() {
repoPath := filepath.Join(base.RepoRootPath, m.RepoName+".git")
_, stderr, err := com.ExecCmdDir(repoPath, "git", "remote", "update")
if err != nil {
- return err
- } else if strings.Contains(stderr, "fatal:") {
- return errors.New(stderr)
+ return errors.New("git remote update: " + stderr)
} else if err = git.UnpackRefs(repoPath); err != nil {
return err
}
@@ -177,9 +175,7 @@ func MirrorUpdate() {
func MirrorRepository(repoId int64, userName, repoName, repoPath, url string) error {
_, stderr, err := com.ExecCmd("git", "clone", "--mirror", url, repoPath)
if err != nil {
- return err
- } else if strings.Contains(stderr, "fatal:") {
- return errors.New(stderr)
+ return errors.New("git clone --mirror: " + stderr)
}
if _, err = orm.InsertOne(&Mirror{
@@ -219,23 +215,17 @@ func MigrateRepository(user *User, name, desc string, private, mirror bool, url
// Clone from local repository.
_, stderr, err := com.ExecCmd("git", "clone", repoPath, tmpDir)
if err != nil {
- return repo, err
- } else if strings.Contains(stderr, "fatal:") {
return repo, errors.New("git clone: " + stderr)
}
// Pull data from source.
_, stderr, err = com.ExecCmdDir(tmpDir, "git", "pull", url)
if err != nil {
- return repo, err
- } else if strings.Contains(stderr, "fatal:") {
return repo, errors.New("git pull: " + stderr)
}
// Push data to local repository.
if _, stderr, err = com.ExecCmdDir(tmpDir, "git", "push", "origin", "master"); err != nil {
- return repo, err
- } else if strings.Contains(stderr, "fatal:") {
return repo, errors.New("git push: " + stderr)
}
@@ -352,7 +342,6 @@ func CreateRepository(user *User, name, desc, lang, license string, private, mir
func extractGitBareZip(repoPath string) error {
z, err := zip.Open("conf/content/git-bare.zip")
if err != nil {
- fmt.Println("shi?")
return err
}
defer z.Close()
@@ -364,21 +353,14 @@ func extractGitBareZip(repoPath string) error {
func initRepoCommit(tmpPath string, sig *git.Signature) (err error) {
var stderr string
if _, stderr, err = com.ExecCmdDir(tmpPath, "git", "add", "--all"); err != nil {
- return err
- } else if strings.Contains(stderr, "fatal:") {
return errors.New("git add: " + stderr)
}
-
if _, stderr, err = com.ExecCmdDir(tmpPath, "git", "commit", fmt.Sprintf("--author='%s <%s>'", sig.Name, sig.Email),
"-m", "Init commit"); err != nil {
- return err
- } else if strings.Contains(stderr, "fatal:") {
return errors.New("git commit: " + stderr)
}
if _, stderr, err = com.ExecCmdDir(tmpPath, "git", "push", "origin", "master"); err != nil {
- return err
- } else if strings.Contains(stderr, "fatal:") {
return errors.New("git push: " + stderr)
}
return nil
@@ -411,10 +393,11 @@ func initRepository(f string, user *User, repo *Repository, initReadme bool, rep
return err
}
+ rp := strings.NewReplacer("\\", "/", " ", "\\ ")
// hook/post-update
if err := createHookUpdate(filepath.Join(repoPath, "hooks", "update"),
fmt.Sprintf("#!/usr/bin/env %s\n%s update $1 $2 $3\n", base.ScriptType,
- strings.Replace(appPath, "\\", "/", -1))); err != nil {
+ rp.Replace(appPath))); err != nil {
return err
}
@@ -436,8 +419,6 @@ func initRepository(f string, user *User, repo *Repository, initReadme bool, rep
_, stderr, err := com.ExecCmd("git", "clone", repoPath, tmpDir)
if err != nil {
- return err
- } else if strings.Contains(stderr, "fatal:") {
return errors.New("git clone: " + stderr)
}
diff --git a/models/update.go b/models/update.go
index 2f59547b7..648c45f16 100644
--- a/models/update.go
+++ b/models/update.go
@@ -1,3 +1,7 @@
+// 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 models
import (
@@ -5,9 +9,11 @@ import (
"os/exec"
"strings"
+ qlog "github.com/qiniu/log"
+
"github.com/gogits/git"
+
"github.com/gogits/gogs/modules/base"
- qlog "github.com/qiniu/log"
)
func Update(refName, oldCommitId, newCommitId, userName, repoName string, userId int64) {
diff --git a/models/user.go b/models/user.go
index ab43df7a1..661eff2fd 100644
--- a/models/user.go
+++ b/models/user.go
@@ -125,6 +125,7 @@ func GetUserSalt() string {
// RegisterUser creates record of a new user.
func RegisterUser(user *User) (*User, error) {
+
if !IsLegalName(user.Name) {
return nil, ErrUserNameIllegal
}
@@ -409,21 +410,27 @@ func GetUserByEmail(email string) (*User, error) {
}
// LoginUserPlain validates user by raw user name and password.
-func LoginUserPlain(name, passwd string) (*User, error) {
- user := User{LowerName: strings.ToLower(name)}
- has, err := orm.Get(&user)
+func LoginUserPlain(uname, passwd string) (*User, error) {
+ var u *User
+ if strings.Contains(uname, "@") {
+ u = &User{Email: uname}
+ } else {
+ u = &User{LowerName: strings.ToLower(uname)}
+ }
+
+ has, err := orm.Get(u)
if err != nil {
return nil, err
} else if !has {
return nil, ErrUserNotExist
}
- newUser := &User{Passwd: passwd, Salt: user.Salt}
+ newUser := &User{Passwd: passwd, Salt: u.Salt}
newUser.EncodePasswd()
- if user.Passwd != newUser.Passwd {
+ if u.Passwd != newUser.Passwd {
return nil, ErrUserNotExist
}
- return &user, nil
+ return u, nil
}
// Follow is connection request for receiving user notifycation.
diff --git a/modules/auth/auth.go b/modules/auth/auth.go
index 350ef4fcb..e493faefe 100644
--- a/modules/auth/auth.go
+++ b/modules/auth/auth.go
@@ -57,7 +57,7 @@ func (f *RegisterForm) Validate(errors *base.BindingErrors, req *http.Request, c
}
type LogInForm struct {
- UserName string `form:"username" binding:"Required;AlphaDash;MaxSize(30)"`
+ UserName string `form:"username" binding:"Required;MaxSize(35)"`
Password string `form:"passwd" binding:"Required;MinSize(6);MaxSize(30)"`
Remember string `form:"remember"`
}
diff --git a/modules/auth/ldap/README.md b/modules/auth/ldap/README.md
new file mode 100644
index 000000000..8b508e0fe
--- /dev/null
+++ b/modules/auth/ldap/README.md
@@ -0,0 +1,43 @@
+LDAP authentication
+===================
+
+## Goal
+
+Authenticat user against LDAP directories
+
+It will bind with the user's login/pasword and query attributs ("mail" for instance) in a pool of directory servers
+
+The first OK wins.
+
+If there's connection error, the server will be disabled and won't be checked again
+
+## Usage
+
+In the [security] section, set
+> LDAP_AUTH = true
+
+then for each LDAP source, set
+
+> [LdapSource-someuniquename]
+> name=canonicalName
+> host=hostname-or-ip
+> port=3268 # or regular LDAP port
+> # the following settings depend highly how you've configured your AD
+> basedn=dc=ACME,dc=COM
+> MSADSAFORMAT=%s@ACME.COM
+> filter=(&(objectClass=user)(sAMAccountName=%s))
+
+### Limitation
+
+Only tested on an MS 2008R2 DC, using global catalog (TCP/3268)
+
+This MSAD is a mess.
+
+The way how one checks the directory (CN, DN etc...) may be highly depending local custom configuration
+
+### Todo
+* Define a timeout per server
+* Check servers marked as "Disabled" when they'll come back online
+* Find a more flexible way to define filter/MSADSAFORMAT/Attributes etc... maybe text/template ?
+* Check OpenLDAP server
+* SSL support ?
\ No newline at end of file
diff --git a/modules/auth/ldap/ldap.go b/modules/auth/ldap/ldap.go
new file mode 100644
index 000000000..29773cda5
--- /dev/null
+++ b/modules/auth/ldap/ldap.go
@@ -0,0 +1,86 @@
+// Copyright github.com/juju2013. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+// package ldap provide functions & structure to query a LDAP ldap directory
+// For now, it's mainly tested again an MS Active Directory service, see README.md for more information
+package ldap
+
+import (
+ "fmt"
+ "github.com/gogits/gogs/modules/log"
+ goldap "github.com/juju2013/goldap"
+)
+
+// Basic LDAP authentication service
+type ldapsource struct {
+ Name string // canonical name (ie. corporate.ad)
+ Host string // LDAP host
+ Port int // port number
+ BaseDN string // Base DN
+ Attributes string // Attribut to search
+ Filter string // Query filter to validate entry
+ MsAdSAFormat string // in the case of MS AD Simple Authen, the format to use (see: http://msdn.microsoft.com/en-us/library/cc223499.aspx)
+ Enabled bool // if this source is disabled
+}
+
+//Global LDAP directory pool
+var (
+ Authensource []ldapsource
+)
+
+// Add a new source (LDAP directory) to the global pool
+func AddSource(name string, host string, port int, basedn string, attributes string, filter string, msadsaformat string) {
+ ldaphost := ldapsource{name, host, port, basedn, attributes, filter, msadsaformat, true}
+ Authensource = append(Authensource, ldaphost)
+}
+
+//LoginUser : try to login an user to LDAP sources, return requested (attribut,true) if ok, ("",false) other wise
+//First match wins
+//Returns first attribute if exists
+func LoginUser(name, passwd string) (a string, r bool) {
+ r = false
+ for _, ls := range Authensource {
+ a, r = ls.searchEntry(name, passwd)
+ if r {
+ return
+ }
+ }
+ return
+}
+
+// searchEntry : search an LDAP source if an entry (name, passwd) is valide and in the specific filter
+func (ls ldapsource) searchEntry(name, passwd string) (string, bool) {
+ l, err := goldap.Dial("tcp", fmt.Sprintf("%s:%d", ls.Host, ls.Port))
+ if err != nil {
+ log.Debug("LDAP Connect error, disabled source %s", ls.Host)
+ ls.Enabled = false
+ return "", false
+ }
+ defer l.Close()
+
+ nx := fmt.Sprintf(ls.MsAdSAFormat, name)
+ err = l.Bind(nx, passwd)
+ if err != nil {
+ log.Debug("LDAP Authan failed for %s, reason: %s", nx, err.Error())
+ return "", false
+ }
+
+ search := goldap.NewSearchRequest(
+ ls.BaseDN,
+ goldap.ScopeWholeSubtree, goldap.NeverDerefAliases, 0, 0, false,
+ fmt.Sprintf(ls.Filter, name),
+ []string{ls.Attributes},
+ nil)
+ sr, err := l.Search(search)
+ if err != nil {
+ log.Debug("LDAP Authen OK but not in filter %s", name)
+ return "", false
+ }
+ log.Debug("LDAP Authen OK: %s", name)
+ if len(sr.Entries) > 0 {
+ r := sr.Entries[0].GetAttributeValue(ls.Attributes)
+ return r, true
+ }
+ return "", true
+}
diff --git a/modules/base/base_redis.go b/modules/base/base_redis.go
index 327af8415..42430df77 100644
--- a/modules/base/base_redis.go
+++ b/modules/base/base_redis.go
@@ -4,6 +4,7 @@ package base
import (
_ "github.com/gogits/cache/redis"
+ _ "github.com/gogits/session/redis"
)
func init() {
diff --git a/modules/base/conf.go b/modules/base/conf.go
index abb67f6d8..cfc85ff51 100644
--- a/modules/base/conf.go
+++ b/modules/base/conf.go
@@ -10,6 +10,7 @@ import (
"os/exec"
"path"
"path/filepath"
+ "regexp"
"strings"
"github.com/Unknwon/com"
@@ -19,6 +20,7 @@ import (
"github.com/gogits/cache"
"github.com/gogits/session"
+ "github.com/gogits/gogs/modules/auth/ldap"
"github.com/gogits/gogs/modules/log"
)
@@ -43,14 +45,15 @@ type Oauther struct {
}
var (
- AppVer string
- AppName string
- AppLogo string
- AppUrl string
- IsProdMode bool
- Domain string
- SecretKey string
- RunUser string
+ AppVer string
+ AppName string
+ AppLogo string
+ AppUrl string
+ OfflineMode bool
+ ProdMode bool
+ Domain string
+ SecretKey string
+ RunUser string
RepoRootPath string
ScriptType string
@@ -83,13 +86,14 @@ var (
)
var Service struct {
- RegisterEmailConfirm bool
- DisableRegistration bool
- RequireSignInView bool
- EnableCacheAvatar bool
- NotifyMail bool
- ActiveCodeLives int
- ResetPwdCodeLives int
+ RegisterEmailConfirm bool
+ DisableRegistration bool
+ RequireSignInView bool
+ EnableCacheAvatar bool
+ NotifyMail bool
+ ActiveCodeLives int
+ ResetPwdCodeLives int
+ LdapAuth bool
}
func ExecDir() (string, error) {
@@ -175,6 +179,36 @@ func newLogService() {
log.Info("Log Mode: %s(%s)", strings.Title(LogMode), levelName)
}
+func newLdapService() {
+ Service.LdapAuth = Cfg.MustBool("security", "LDAP_AUTH", false)
+ if !Service.LdapAuth {
+ return
+ }
+
+ nbsrc := 0
+ for _, v := range Cfg.GetSectionList() {
+ if matched, _ := regexp.MatchString("(?i)^LDAPSOURCE.*", v); matched {
+ ldapname := Cfg.MustValue(v, "name", v)
+ ldaphost := Cfg.MustValue(v, "host")
+ ldapport := Cfg.MustInt(v, "port", 389)
+ ldapbasedn := Cfg.MustValue(v, "basedn", "dc=*,dc=*")
+ ldapattribute := Cfg.MustValue(v, "attribute", "mail")
+ ldapfilter := Cfg.MustValue(v, "filter", "(*)")
+ ldapmsadsaformat := Cfg.MustValue(v, "MSADSAFORMAT", "%s")
+ ldap.AddSource(ldapname, ldaphost, ldapport, ldapbasedn, ldapattribute, ldapfilter, ldapmsadsaformat)
+ nbsrc++
+ log.Debug("%s added as LDAP source", ldapname)
+ }
+ }
+ if nbsrc == 0 {
+ log.Warn("No valide LDAP found, LDAP Authentication NOT enabled")
+ Service.LdapAuth = false
+ return
+ }
+
+ log.Info("LDAP Authentication Enabled")
+}
+
func newCacheService() {
CacheAdapter = Cfg.MustValue("cache", "ADAPTER", "memory")
if EnableRedis {
@@ -292,6 +326,7 @@ func NewConfigContext() {
AppLogo = Cfg.MustValue("", "APP_LOGO", "img/favicon.png")
AppUrl = Cfg.MustValue("server", "ROOT_URL")
Domain = Cfg.MustValue("server", "DOMAIN")
+ OfflineMode = Cfg.MustBool("server", "OFFLINE_MODE", false)
SecretKey = Cfg.MustValue("security", "SECRET_KEY")
InstallLock = Cfg.MustBool("security", "INSTALL_LOCK", false)
@@ -309,7 +344,6 @@ func NewConfigContext() {
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")
// Determine and create root git reposiroty path.
@@ -327,6 +361,7 @@ func NewConfigContext() {
func NewBaseServices() {
newService()
newLogService()
+ newLdapService()
newCacheService()
newSessionService()
newMailService()
diff --git a/modules/base/template.go b/modules/base/template.go
index 79aeeb9d7..dd98df75b 100644
--- a/modules/base/template.go
+++ b/modules/base/template.go
@@ -56,8 +56,8 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{
"AppDomain": func() string {
return Domain
},
- "IsProdMode": func() bool {
- return IsProdMode
+ "CdnMode": func() bool {
+ return ProdMode && !OfflineMode
},
"LoadTimes": func(startTime time.Time) string {
return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms"
@@ -124,11 +124,11 @@ func ActionIcon(opType int) string {
const (
TPL_CREATE_REPO = `%s created repository %s`
TPL_COMMIT_REPO = `%s pushed to %s at %s%s`
- TPL_COMMIT_REPO_LI = ``
+ TPL_COMMIT_REPO_LI = ``
TPL_CREATE_ISSUE = `%s opened issue %s#%s
%s
`
TPL_TRANSFER_REPO = `%s transfered repository %s
to %s`
- TPL_PUSH_TAG = `%s pushed tag %s at %s`
+ TPL_PUSH_TAG = `%s pushed tag %s at %s`
)
type PushCommit struct {
@@ -165,7 +165,7 @@ func ActionDesc(act Actioner) string {
buf.WriteString(fmt.Sprintf(TPL_COMMIT_REPO_LI, AvatarLink(commit.AuthorEmail), repoLink, commit.Sha1, commit.Sha1[:7], commit.Message) + "\n")
}
if push.Len > 3 {
- buf.WriteString(fmt.Sprintf(``, actUserName, repoName, branch, push.Len))
+ buf.WriteString(fmt.Sprintf(``, actUserName, repoName, branch, push.Len))
}
return fmt.Sprintf(TPL_COMMIT_REPO, actUserName, actUserName, repoLink, branch, branch, repoLink, repoLink,
buf.String())
diff --git a/modules/middleware/repo.go b/modules/middleware/repo.go
index 34144fe3d..2d2778cb0 100644
--- a/modules/middleware/repo.go
+++ b/modules/middleware/repo.go
@@ -26,11 +26,14 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler {
var displayBare bool
if len(args) >= 1 {
- validBranch = args[0]
+ // Note: argument has wrong value in Go1.3 martini.
+ // validBranch = args[0]
+ validBranch = true
}
if len(args) >= 2 {
- displayBare = args[1]
+ // displayBare = args[1]
+ displayBare = true
}
var (
diff --git a/public/img/favicon.bak.png b/public/img/favicon.bak.png
new file mode 100644
index 000000000..ba9bd0375
Binary files /dev/null and b/public/img/favicon.bak.png differ
diff --git a/public/img/favicon.png b/public/img/favicon.png
index ba9bd0375..87282f9a7 100644
Binary files a/public/img/favicon.png and b/public/img/favicon.png differ
diff --git a/public/js/app.js b/public/js/app.js
index a5c79a398..b7b5deb83 100644
--- a/public/js/app.js
+++ b/public/js/app.js
@@ -470,10 +470,10 @@ function initInstall() {
(function () {
$('#install-database').on("change", function () {
var val = $(this).val();
- if (val != "sqlite") {
+ if (val != "SQLite3") {
$('.server-sql').show();
$('.sqlite-setting').addClass("hide");
- if (val == "pgsql") {
+ if (val == "PostgreSQL") {
$('.pgsql-setting').removeClass("hide");
} else {
$('.pgsql-setting').addClass("hide");
diff --git a/routers/admin/admin.go b/routers/admin/admin.go
index d0f737e64..fddd83018 100644
--- a/routers/admin/admin.go
+++ b/routers/admin/admin.go
@@ -139,9 +139,11 @@ func Config(ctx *middleware.Context) {
ctx.Data["AppUrl"] = base.AppUrl
ctx.Data["Domain"] = base.Domain
+ ctx.Data["OfflineMode"] = base.OfflineMode
ctx.Data["RunUser"] = base.RunUser
ctx.Data["RunMode"] = strings.Title(martini.Env)
ctx.Data["RepoRootPath"] = base.RepoRootPath
+ ctx.Data["ScriptType"] = base.ScriptType
ctx.Data["Service"] = base.Service
diff --git a/routers/install.go b/routers/install.go
index 12182ad30..38bf896f4 100644
--- a/routers/install.go
+++ b/routers/install.go
@@ -30,7 +30,7 @@ func checkRunMode() {
switch base.Cfg.MustValue("", "RUN_MODE") {
case "prod":
martini.Env = martini.Prod
- base.IsProdMode = true
+ base.ProdMode = true
case "test":
martini.Env = martini.Test
}
@@ -65,6 +65,10 @@ func GlobalInit() {
checkRunMode()
}
+func renderDbOption(ctx *middleware.Context) {
+ ctx.Data["DbOptions"] = []string{"MySQL", "PostgreSQL", "SQLite3"}
+}
+
func Install(ctx *middleware.Context, form auth.InstallForm) {
if base.InstallLock {
ctx.Handle(404, "install.Install", errors.New("Installation is prohibited"))
@@ -104,6 +108,13 @@ func Install(ctx *middleware.Context, form auth.InstallForm) {
form.AppUrl = base.AppUrl
}
+ renderDbOption(ctx)
+ curDbValue := ""
+ if models.EnableSQLite3 {
+ curDbValue = "SQLite3" // Default when enabled.
+ }
+ ctx.Data["CurDbValue"] = curDbValue
+
auth.AssignForm(form, ctx.Data)
ctx.HTML(200, "install")
}
@@ -117,6 +128,9 @@ func InstallPost(ctx *middleware.Context, form auth.InstallForm) {
ctx.Data["Title"] = "Install"
ctx.Data["PageIsInstall"] = true
+ renderDbOption(ctx)
+ ctx.Data["CurDbValue"] = form.Database
+
if ctx.HasError() {
ctx.HTML(200, "install")
return
@@ -129,7 +143,7 @@ func InstallPost(ctx *middleware.Context, form auth.InstallForm) {
// Pass basic check, now test configuration.
// Test database setting.
- dbTypes := map[string]string{"mysql": "mysql", "pgsql": "postgres", "sqlite": "sqlite3"}
+ dbTypes := map[string]string{"MySQL": "mysql", "PostgreSQL": "postgres", "SQLite3": "sqlite3"}
models.DbCfg.Type = dbTypes[form.Database]
models.DbCfg.Host = form.Host
models.DbCfg.User = form.User
diff --git a/routers/repo/commit.go b/routers/repo/commit.go
index 6e20a7b7f..bc33fe447 100644
--- a/routers/repo/commit.go
+++ b/routers/repo/commit.go
@@ -91,10 +91,23 @@ func Diff(ctx *middleware.Context, params martini.Params) {
return isImage
}
+ parents := make([]string, commit.ParentCount())
+ for i := 0; i < commit.ParentCount(); i++ {
+ sha, err := commit.ParentId(i)
+ parents[i] = sha.String()
+ if err != nil {
+ ctx.Handle(404, "repo.Diff", err)
+ return
+ }
+ }
+
+ ctx.Data["Username"] = userName
+ ctx.Data["Reponame"] = repoName
ctx.Data["IsImageFile"] = isImageFile
- ctx.Data["Title"] = commit.Message() + " · " + base.ShortSha(commitId)
+ ctx.Data["Title"] = commit.Summary() + " · " + base.ShortSha(commitId)
ctx.Data["Commit"] = commit
ctx.Data["Diff"] = diff
+ ctx.Data["Parents"] = parents
ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
ctx.Data["IsRepoToolbarCommits"] = true
ctx.Data["SourcePath"] = "/" + path.Join(userName, repoName, "src", commitId)
diff --git a/routers/repo/release.go b/routers/repo/release.go
index a4baa4792..b386bac80 100644
--- a/routers/repo/release.go
+++ b/routers/repo/release.go
@@ -87,7 +87,6 @@ func Releases(ctx *middleware.Context) {
return
}
tags.rels[i].NumCommitsBehind = commitsCount - tags.rels[i].NumCommits
- tags.rels[i].Created = commit.Author.When
}
}
diff --git a/routers/repo/repo.go b/routers/repo/repo.go
index f733378b3..76964dff1 100644
--- a/routers/repo/repo.go
+++ b/routers/repo/repo.go
@@ -134,7 +134,6 @@ func Single(ctx *middleware.Context, params martini.Params) {
}
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treename)
-
if err != nil && err != git.ErrNotExist {
ctx.Handle(404, "repo.Single(GetTreeEntryByPath)", err)
return
diff --git a/routers/user/setting.go b/routers/user/setting.go
index a8fdc116c..a55e617f4 100644
--- a/routers/user/setting.go
+++ b/routers/user/setting.go
@@ -66,7 +66,7 @@ func SettingPost(ctx *middleware.Context, form auth.UpdateProfileForm) {
log.Trace("%s User setting updated: %s", ctx.Req.RequestURI, ctx.User.LowerName)
ctx.Flash.Success("Your profile has been successfully updated.")
- ctx.Redirect("/user/setting")
+ ctx.Redirect("/user/settings")
}
func SettingSocial(ctx *middleware.Context) {
@@ -122,7 +122,7 @@ func SettingPasswordPost(ctx *middleware.Context, form auth.UpdatePasswdForm) {
ctx.Flash.Success("Password is changed successfully. You can now sign in via new password.")
}
- ctx.Redirect("/user/setting/password")
+ ctx.Redirect("/user/settings/password")
}
func SettingSSHKeys(ctx *middleware.Context, form auth.AddSSHKeyForm) {
@@ -166,7 +166,8 @@ func SettingSSHKeys(ctx *middleware.Context, form auth.AddSSHKeyForm) {
return
}
- k := &models.PublicKey{OwnerId: ctx.User.Id,
+ k := &models.PublicKey{
+ OwnerId: ctx.User.Id,
Name: form.KeyName,
Content: form.KeyContent,
}
@@ -181,7 +182,7 @@ func SettingSSHKeys(ctx *middleware.Context, form auth.AddSSHKeyForm) {
} else {
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")
+ ctx.Redirect("/user/settings/ssh")
return
}
}
diff --git a/routers/user/user.go b/routers/user/user.go
index 7decd72d4..9cce4e719 100644
--- a/routers/user/user.go
+++ b/routers/user/user.go
@@ -89,7 +89,18 @@ func SignInPost(ctx *middleware.Context, form auth.LogInForm) {
return
}
- user, err := models.LoginUserPlain(form.UserName, form.Password)
+ var user *models.User
+ var err error
+ if base.Service.LdapAuth {
+ user, err = models.LoginUserLdap(form.UserName, form.Password)
+ if err != nil {
+ log.Error("Fail to login through LDAP: %v", err)
+ }
+ }
+ // try local if not LDAP or it's failed
+ if !base.Service.LdapAuth || err != nil {
+ user, err = models.LoginUserPlain(form.UserName, form.Password)
+ }
if err != nil {
if err == models.ErrUserNotExist {
log.Trace("%s Log in failed: %s/%s", ctx.Req.RequestURI, form.UserName, form.Password)
@@ -133,27 +144,6 @@ func SignInPost(ctx *middleware.Context, form auth.LogInForm) {
ctx.Redirect("/")
}
-func oauthSignInPost(ctx *middleware.Context, sid int64) {
- ctx.Data["Title"] = "OAuth Sign Up"
- ctx.Data["PageIsSignUp"] = true
-
- if _, err := models.GetOauth2ById(sid); err != nil {
- if err == models.ErrOauth2RecordNotExist {
- ctx.Handle(404, "user.oauthSignUp(GetOauth2ById)", err)
- } else {
- ctx.Handle(500, "user.oauthSignUp(GetOauth2ById)", err)
- }
- return
- }
-
- ctx.Data["IsSocialLogin"] = true
- ctx.Data["username"] = ctx.Session.Get("socialName")
- ctx.Data["email"] = ctx.Session.Get("socialEmail")
- log.Trace("user.oauthSignUp(social ID): %v", ctx.Session.Get("socialId"))
-
- ctx.HTML(200, "user/signup")
-}
-
func SignOut(ctx *middleware.Context) {
ctx.Session.Delete("userId")
ctx.Session.Delete("userName")
diff --git a/serve.go b/serve.go
index 321227957..e3197a23d 100644
--- a/serve.go
+++ b/serve.go
@@ -53,6 +53,7 @@ func newLogger(execDir string) {
}
qlog.SetOutput(f)
+ //qlog.SetOutputLevel(qlog.Ldebug)
qlog.Info("Start logging serv...")
}
@@ -159,7 +160,7 @@ func runServ(k *cli.Context) {
qlog.Fatal(err)
}
if !has {
- has, err = models.HasAccess(user.Name, repoPath, models.AU_WRITABLE)
+ has, err = models.HasAccess(user.Name, path.Join(repoUserName, repoName), models.AU_WRITABLE)
if err != nil {
println("Internal error")
qlog.Fatal(err)
diff --git a/templates/admin/config.tmpl b/templates/admin/config.tmpl
index d25d40275..b2b25e90f 100644
--- a/templates/admin/config.tmpl
+++ b/templates/admin/config.tmpl
@@ -18,6 +18,8 @@
{{.AppUrl}}
Domain
{{.Domain}}
+ Offline Mode
+
Run User
{{.RunUser}}
@@ -26,6 +28,8 @@
Repository Root Path
{{.RepoRootPath}}
+ Script Type
+ {{.ScriptType}}
diff --git a/templates/base/footer.tmpl b/templates/base/footer.tmpl
index 6c2da63e5..30f068913 100644
--- a/templates/base/footer.tmpl
+++ b/templates/base/footer.tmpl
@@ -13,7 +13,10 @@
-
+
+
diff --git a/templates/base/head.tmpl b/templates/base/head.tmpl
index 68231391c..6794b0171 100644
--- a/templates/base/head.tmpl
+++ b/templates/base/head.tmpl
@@ -12,7 +12,7 @@
{{if .Repository.IsGoget}}{{end}}
- {{if IsProdMode}}
+ {{if CdnMode}}
diff --git a/templates/base/navbar.tmpl b/templates/base/navbar.tmpl
index e5b22192f..b8cba5faa 100644
--- a/templates/base/navbar.tmpl
+++ b/templates/base/navbar.tmpl
@@ -3,7 +3,7 @@
{{else}}
-
+
- zip
+ zip
@@ -50,30 +50,6 @@
{{end}}
{{end}}
-
diff --git a/templates/repo/commits.tmpl b/templates/repo/commits.tmpl
index b14c6bc8c..74b03074b 100644
--- a/templates/repo/commits.tmpl
+++ b/templates/repo/commits.tmpl
@@ -33,7 +33,7 @@
{{.Author.Name}} |
{{SubStr .Id.String 0 10}} |
- {{.Message}} |
+ {{.Summary}} |
{{TimeSince .Author.When}} |
{{end}}
@@ -41,8 +41,8 @@
{{if not .IsSearchPage}}{{end}}
diff --git a/templates/repo/diff.tmpl b/templates/repo/diff.tmpl
index 0dce40533..0b6d4f722 100644
--- a/templates/repo/diff.tmpl
+++ b/templates/repo/diff.tmpl
@@ -10,7 +10,12 @@
- commit {{ShortSha .CommitId}}
+
+ {{range .Parents}}
+ - parent {{ShortSha .}}
+ {{end}}
+ - commit {{ShortSha .CommitId}}
+
diff --git a/templates/repo/nav.tmpl b/templates/repo/nav.tmpl
index ce9c112b8..48fe31a61 100644
--- a/templates/repo/nav.tmpl
+++ b/templates/repo/nav.tmpl
@@ -23,10 +23,10 @@
- Need help cloning? Visit Help!
+ Need help cloning? Visit Help!
diff --git a/templates/repo/single_file.tmpl b/templates/repo/single_file.tmpl
index 9199ca91f..95c41b701 100644
--- a/templates/repo/single_file.tmpl
+++ b/templates/repo/single_file.tmpl
@@ -14,37 +14,38 @@
{{if not .ReadmeInSingle}}
{{end}}
+
{{if not .FileIsText}}
-
- {{else}}
- {{if .ReadmeExist}}
-
- {{.FileContent|str2html}}
-
+
+ {{if .IsImageFile}}
+
{{else}}
-
-
-
-
- |
- {{.FileContent}} |
-
-
-
-
+
View Raw
{{end}}
+
+ {{else}}
+ {{if .ReadmeExist}}
+
+ {{.FileContent|str2html}}
+
+ {{else}}
+
+
+
+
+ |
+ {{.FileContent}} |
+
+
+
+
+ {{end}}
{{end}}
diff --git a/templates/repo/single_list.tmpl b/templates/repo/single_list.tmpl
index 7b6c6e5e9..640f7f090 100644
--- a/templates/repo/single_list.tmpl
+++ b/templates/repo/single_list.tmpl
@@ -1,6 +1,6 @@
{{.LastCommit.Author.Name}} {{TimeSince .LastCommit.Author.When}}
@@ -36,7 +36,7 @@
- {{$commit.Message}}
+ {{$commit.Summary}}
|
{{TimeSince $commit.Committer.When}}
diff --git a/templates/user/password.tmpl b/templates/user/password.tmpl
index cba9cce0c..c55d27fa1 100644
--- a/templates/user/password.tmpl
+++ b/templates/user/password.tmpl
@@ -5,7 +5,7 @@
|