Merge branch 'master' of github.com:gogits/gogs
This commit is contained in:
commit
f824d6a4b1
27 changed files with 732 additions and 191 deletions
|
@ -17,6 +17,7 @@ Please see [Wiki](https://github.com/gogits/gogs/wiki) for project design, devel
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
|
- Activity timeline
|
||||||
- SSH protocal support.
|
- SSH protocal support.
|
||||||
- Register/delete account.
|
- Register/delete account.
|
||||||
- Create/delete public repository.
|
- Create/delete public repository.
|
||||||
|
|
|
@ -3,8 +3,8 @@ RUN_USER = lunny
|
||||||
|
|
||||||
[repository]
|
[repository]
|
||||||
ROOT = /Users/%(RUN_USER)s/git/gogs-repositories
|
ROOT = /Users/%(RUN_USER)s/git/gogs-repositories
|
||||||
LANG_IGNS=Google Go|C|Python
|
LANG_IGNS=Google Go|C|Python|Ruby
|
||||||
LICENSES=Apache v2 License|GPL v2|BSD (3-Clause) License
|
LICENSES=Apache v2 License|GPL v2|MIT License|BSD (3-Clause) License
|
||||||
|
|
||||||
[server]
|
[server]
|
||||||
HTTP_ADDR =
|
HTTP_ADDR =
|
||||||
|
|
18
conf/gitignore/Ruby
Normal file
18
conf/gitignore/Ruby
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
*.gem
|
||||||
|
*.rbc
|
||||||
|
.bundle
|
||||||
|
.config
|
||||||
|
coverage
|
||||||
|
InstalledFiles
|
||||||
|
lib/bundler/man
|
||||||
|
pkg
|
||||||
|
rdoc
|
||||||
|
spec/reports
|
||||||
|
test/tmp
|
||||||
|
test/version_tmp
|
||||||
|
tmp
|
||||||
|
|
||||||
|
# YARD artifacts
|
||||||
|
.yardoc
|
||||||
|
_yardoc
|
||||||
|
doc/
|
21
conf/license/MIT License
Normal file
21
conf/license/MIT License
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
24
gogs.go
24
gogs.go
|
@ -7,7 +7,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"os/user"
|
// "os/user"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
|
@ -20,21 +20,21 @@ import (
|
||||||
// Test that go1.1 tag above is included in builds. main.go refers to this definition.
|
// Test that go1.1 tag above is included in builds. main.go refers to this definition.
|
||||||
const go11tag = true
|
const go11tag = true
|
||||||
|
|
||||||
const APP_VER = "0.0.8.0315"
|
const APP_VER = "0.0.8.0316.1"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
base.AppVer = APP_VER
|
base.AppVer = APP_VER
|
||||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkRunUser() bool {
|
// func checkRunUser() bool {
|
||||||
u, err := user.Current()
|
// u, err := user.Current()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
// TODO: log
|
// // TODO: log
|
||||||
return false
|
// return false
|
||||||
}
|
// }
|
||||||
return u.Username == base.Cfg.MustValue("", "RUN_USER")
|
// return u.Username == base.Cfg.MustValue("", "RUN_USER")
|
||||||
}
|
// }
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
/*if !checkRunUser() {
|
/*if !checkRunUser() {
|
||||||
|
@ -51,8 +51,6 @@ func main() {
|
||||||
CmdServ,
|
CmdServ,
|
||||||
CmdUpdate,
|
CmdUpdate,
|
||||||
}
|
}
|
||||||
app.Flags = append(app.Flags, []cli.Flag{
|
app.Flags = append(app.Flags, []cli.Flag{}...)
|
||||||
cli.BoolFlag{"noterm", "disable color output"},
|
|
||||||
}...)
|
|
||||||
app.Run(os.Args)
|
app.Run(os.Args)
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ func (a Action) GetRepoName() string {
|
||||||
return a.RepoName
|
return a.RepoName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CommitRepoAction records action for commit repository.
|
||||||
func CommitRepoAction(userId int64, userName string,
|
func CommitRepoAction(userId int64, userName string,
|
||||||
repoId int64, repoName string, msg string) error {
|
repoId int64, repoName string, msg string) error {
|
||||||
_, err := orm.InsertOne(&Action{
|
_, err := orm.InsertOne(&Action{
|
||||||
|
@ -57,8 +58,7 @@ func CommitRepoAction(userId int64, userName string,
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRepoAction inserts action for create repository.
|
// NewRepoAction records action for create repository.
|
||||||
|
|
||||||
func NewRepoAction(user *User, repo *Repository) error {
|
func NewRepoAction(user *User, repo *Repository) error {
|
||||||
_, err := orm.InsertOne(&Action{
|
_, err := orm.InsertOne(&Action{
|
||||||
UserId: user.Id,
|
UserId: user.Id,
|
||||||
|
|
|
@ -1,21 +1,32 @@
|
||||||
|
// 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
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Unknwon/com"
|
"github.com/Unknwon/com"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
sshOpLocker = sync.Mutex{}
|
||||||
//publicKeyRootPath string
|
//publicKeyRootPath string
|
||||||
sshPath string
|
sshPath string
|
||||||
appPath string
|
appPath string
|
||||||
tmplPublicKey = "### autogenerated by gitgos, DO NOT EDIT\n" +
|
// "### autogenerated by gitgos, DO NOT EDIT\n"
|
||||||
"command=\"%s serv key-%d\",no-port-forwarding," +
|
tmplPublicKey = "command=\"%s serv key-%d\",no-port-forwarding," +
|
||||||
"no-X11-forwarding,no-agent-forwarding,no-pty %s\n"
|
"no-X11-forwarding,no-agent-forwarding,no-pty %s\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -50,26 +61,57 @@ type PublicKey struct {
|
||||||
Id int64
|
Id int64
|
||||||
OwnerId int64 `xorm:"index"`
|
OwnerId int64 `xorm:"index"`
|
||||||
Name string `xorm:"unique not null"`
|
Name string `xorm:"unique not null"`
|
||||||
|
Fingerprint string
|
||||||
Content string `xorm:"text not null"`
|
Content string `xorm:"text not null"`
|
||||||
Created time.Time `xorm:"created"`
|
Created time.Time `xorm:"created"`
|
||||||
Updated time.Time `xorm:"updated"`
|
Updated time.Time `xorm:"updated"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrKeyAlreadyExist = errors.New("Public key already exist")
|
||||||
|
)
|
||||||
|
|
||||||
func GenAuthorizedKey(keyId int64, key string) string {
|
func GenAuthorizedKey(keyId int64, key string) string {
|
||||||
return fmt.Sprintf(tmplPublicKey, appPath, keyId, key)
|
return fmt.Sprintf(tmplPublicKey, appPath, keyId, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddPublicKey(key *PublicKey) error {
|
func AddPublicKey(key *PublicKey) (err error) {
|
||||||
_, err := orm.Insert(key)
|
// Check if public key name has been used.
|
||||||
|
has, err := orm.Get(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
} else if has {
|
||||||
|
return ErrKeyAlreadyExist
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate fingerprint.
|
||||||
|
tmpPath := filepath.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().Nanosecond()),
|
||||||
|
"id_rsa.pub")
|
||||||
|
os.MkdirAll(path.Dir(tmpPath), os.ModePerm)
|
||||||
|
f, err := os.Create(tmpPath)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, err = f.WriteString(key.Content); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
f.Close()
|
||||||
|
stdout, _, err := com.ExecCmd("ssh-keygen", "-l", "-f", tmpPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if len(stdout) < 2 {
|
||||||
|
return errors.New("Not enough output for calculating fingerprint")
|
||||||
|
}
|
||||||
|
key.Fingerprint = strings.Split(stdout, " ")[1]
|
||||||
|
|
||||||
|
// Save SSH key.
|
||||||
|
if _, err = orm.Insert(key); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = SaveAuthorizedKeyFile(key)
|
if err = SaveAuthorizedKeyFile(key); err != nil {
|
||||||
if err != nil {
|
if _, err2 := orm.Delete(key); err2 != nil {
|
||||||
_, err2 := orm.Delete(key)
|
return err2
|
||||||
if err2 != nil {
|
|
||||||
// TODO: log the error
|
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -77,9 +119,71 @@ func AddPublicKey(key *PublicKey) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeletePublicKey(key *PublicKey) error {
|
// DeletePublicKey deletes SSH key information both in database and authorized_keys file.
|
||||||
_, err := orm.Delete(key)
|
func DeletePublicKey(key *PublicKey) (err error) {
|
||||||
|
has, err := orm.Id(key.Id).Get(key)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
} else if !has {
|
||||||
|
return errors.New("Public key does not exist")
|
||||||
|
}
|
||||||
|
if _, err = orm.Delete(key); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
sshOpLocker.Lock()
|
||||||
|
defer sshOpLocker.Unlock()
|
||||||
|
|
||||||
|
p := filepath.Join(sshPath, "authorized_keys")
|
||||||
|
tmpP := filepath.Join(sshPath, "authorized_keys.tmp")
|
||||||
|
fr, err := os.Open(p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fr.Close()
|
||||||
|
|
||||||
|
fw, err := os.Create(tmpP)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fw.Close()
|
||||||
|
|
||||||
|
buf := bufio.NewReader(fr)
|
||||||
|
for {
|
||||||
|
line, errRead := buf.ReadString('\n')
|
||||||
|
line = strings.TrimSpace(line)
|
||||||
|
|
||||||
|
if errRead != nil {
|
||||||
|
if errRead != io.EOF {
|
||||||
|
return errRead
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reached end of file, if nothing to read then break,
|
||||||
|
// otherwise handle the last line.
|
||||||
|
if len(line) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Found the line and copy rest of file.
|
||||||
|
if strings.Contains(line, fmt.Sprintf("key-%d", key.Id)) && strings.Contains(line, key.Content) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Still finding the line, copy the line that currently read.
|
||||||
|
if _, err = fw.WriteString(line + "\n"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if errRead == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = os.Remove(p); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return os.Rename(tmpP, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListPublicKey(userId int64) ([]PublicKey, error) {
|
func ListPublicKey(userId int64) ([]PublicKey, error) {
|
||||||
|
@ -89,11 +193,16 @@ func ListPublicKey(userId int64) ([]PublicKey, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func SaveAuthorizedKeyFile(key *PublicKey) error {
|
func SaveAuthorizedKeyFile(key *PublicKey) error {
|
||||||
|
sshOpLocker.Lock()
|
||||||
|
defer sshOpLocker.Unlock()
|
||||||
|
|
||||||
p := filepath.Join(sshPath, "authorized_keys")
|
p := filepath.Join(sshPath, "authorized_keys")
|
||||||
f, err := os.OpenFile(p, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
|
f, err := os.OpenFile(p, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
//os.Chmod(p, 0600)
|
//os.Chmod(p, 0600)
|
||||||
_, err = f.WriteString(GenAuthorizedKey(key.Id, key.Content))
|
_, err = f.WriteString(GenAuthorizedKey(key.Id, key.Content))
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -264,7 +264,7 @@ func GetRepositoryById(id int64) (repo *Repository, err error) {
|
||||||
// GetRepositories returns the list of repositories of given user.
|
// GetRepositories returns the list of repositories of given user.
|
||||||
func GetRepositories(user *User) ([]Repository, error) {
|
func GetRepositories(user *User) ([]Repository, error) {
|
||||||
repos := make([]Repository, 0, 10)
|
repos := make([]Repository, 0, 10)
|
||||||
err := orm.Find(&repos, &Repository{OwnerId: user.Id})
|
err := orm.Desc("updated").Find(&repos, &Repository{OwnerId: user.Id})
|
||||||
return repos, err
|
return repos, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -142,6 +142,7 @@ func UpdateUser(user *User) (err error) {
|
||||||
|
|
||||||
// DeleteUser completely deletes everything of the user.
|
// DeleteUser completely deletes everything of the user.
|
||||||
func DeleteUser(user *User) error {
|
func DeleteUser(user *User) error {
|
||||||
|
// Check ownership of repository.
|
||||||
count, err := GetRepositoryCount(user)
|
count, err := GetRepositoryCount(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("modesl.GetRepositories: " + err.Error())
|
return errors.New("modesl.GetRepositories: " + err.Error())
|
||||||
|
@ -151,6 +152,22 @@ func DeleteUser(user *User) error {
|
||||||
|
|
||||||
// TODO: check issues, other repos' commits
|
// TODO: check issues, other repos' commits
|
||||||
|
|
||||||
|
// Delete all feeds.
|
||||||
|
if _, err = orm.Delete(&Action{UserId: user.Id}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete all SSH keys.
|
||||||
|
keys := make([]PublicKey, 0, 10)
|
||||||
|
if err = orm.Find(&keys, &PublicKey{OwnerId: user.Id}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, key := range keys {
|
||||||
|
if err = DeletePublicKey(&key); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_, err = orm.Delete(user)
|
_, err = orm.Delete(user)
|
||||||
// TODO: delete and update follower information.
|
// TODO: delete and update follower information.
|
||||||
return err
|
return err
|
||||||
|
@ -158,8 +175,8 @@ func DeleteUser(user *User) error {
|
||||||
|
|
||||||
// EncodePasswd encodes password to safe format.
|
// EncodePasswd encodes password to safe format.
|
||||||
func (user *User) EncodePasswd() error {
|
func (user *User) EncodePasswd() error {
|
||||||
newPasswd, err := scrypt.Key([]byte(user.Passwd), []byte(UserPasswdSalt), 16384, 8, 1, 64)
|
var err error
|
||||||
user.Passwd = fmt.Sprintf("%x", newPasswd)
|
user.Passwd, err = EncodePasswd(user.Passwd)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,6 +184,14 @@ func UserPath(userName string) string {
|
||||||
return filepath.Join(RepoRootPath, userName)
|
return filepath.Join(RepoRootPath, userName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func EncodePasswd(rawPasswd string) (string, error) {
|
||||||
|
newPasswd, err := scrypt.Key([]byte(rawPasswd), []byte(UserPasswdSalt), 16384, 8, 1, 64)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%x", newPasswd), nil
|
||||||
|
}
|
||||||
|
|
||||||
func GetUserByKeyId(keyId int64) (*User, error) {
|
func GetUserByKeyId(keyId int64) (*User, error) {
|
||||||
user := new(User)
|
user := new(User)
|
||||||
has, err := orm.Sql("select a.* from user as a, public_key as b where a.id = b.owner_id and b.id=?", keyId).Get(user)
|
has, err := orm.Sql("select a.* from user as a, public_key as b where a.id = b.owner_id and b.id=?", keyId).Get(user)
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
"github.com/codegangsta/martini"
|
"github.com/codegangsta/martini"
|
||||||
|
|
||||||
"github.com/gogits/gogs/models"
|
"github.com/gogits/gogs/models"
|
||||||
|
@ -31,9 +33,7 @@ func RepoAssignment(redirect bool) martini.Handler {
|
||||||
ctx.Render.Redirect("/")
|
ctx.Render.Redirect("/")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//data["ErrorMsg"] = err
|
ctx.Handle(200, "RepoAssignment", err)
|
||||||
//log.Error("repo.Single: %v", err)
|
|
||||||
//r.HTML(200, "base/error", data)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -45,9 +45,7 @@ func RepoAssignment(redirect bool) martini.Handler {
|
||||||
ctx.Render.Redirect("/")
|
ctx.Render.Redirect("/")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//data["ErrorMsg"] = "invliad user account for single repository"
|
ctx.Handle(200, "RepoAssignment", errors.New("invliad user account for single repository"))
|
||||||
//log.Error("repo.Single: %v", err)
|
|
||||||
//r.HTML(200, "base/error", data)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,9 +58,7 @@ func RepoAssignment(redirect bool) martini.Handler {
|
||||||
ctx.Render.Redirect("/")
|
ctx.Render.Redirect("/")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//data["ErrorMsg"] = err
|
ctx.Handle(200, "RepoAssignment", err)
|
||||||
//log.Error("repo.Single: %v", err)
|
|
||||||
//r.HTML(200, "base/error", data)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
public/css/bootstrap.min.css
vendored
2
public/css/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
|
@ -302,32 +302,23 @@ html, body {
|
||||||
/* gogits user ssh keys */
|
/* gogits user ssh keys */
|
||||||
|
|
||||||
#gogs-ssh-keys .list-group-item {
|
#gogs-ssh-keys .list-group-item {
|
||||||
line-height: 48px;
|
padding: 15px 0;
|
||||||
border-bottom: 1px solid #DDD;
|
border-bottom: 1px solid #DDD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#gogs-ssh-keys .list-group-item .delete {
|
||||||
|
margin: -5px 50px 0;
|
||||||
|
}
|
||||||
|
|
||||||
#gogs-ssh-keys .list-group-item:after {
|
#gogs-ssh-keys .list-group-item:after {
|
||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
|
|
||||||
#gogs-ssh-keys .list-group-item:hover a.delete {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
#gogs-ssh-keys .name {
|
#gogs-ssh-keys .name {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
#gogs-ssh-keys .list-group-item a.delete {
|
|
||||||
float: right;
|
|
||||||
color: white;
|
|
||||||
cursor: pointer;
|
|
||||||
margin-top: 10px;
|
|
||||||
border-radius: 3px;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#gogs-ssh-keys .print {
|
#gogs-ssh-keys .print {
|
||||||
padding-left: 1em;
|
padding-left: 1em;
|
||||||
color: #888;
|
color: #888;
|
||||||
|
@ -472,56 +463,6 @@ html, body {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* #gogs-source */
|
|
||||||
|
|
||||||
#gogs-source-toolbar:after {
|
|
||||||
clear: both;
|
|
||||||
}
|
|
||||||
|
|
||||||
#gogs-source-toolbar .branch-switch {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
#gogs-source-toolbar .breadcrumb {
|
|
||||||
margin: 0 .5em;
|
|
||||||
font-size: 16px;
|
|
||||||
vertical-align: middle;
|
|
||||||
display: inline-block;
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
#gogs-source-table {
|
|
||||||
margin-top: 1.5em;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#gogs-source-table .fa{
|
|
||||||
font-size: 15px;
|
|
||||||
width: 16px;
|
|
||||||
text-align: center;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
#gogs-source-table .name{
|
|
||||||
width: 160px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#gogs-source-table .size{
|
|
||||||
width: 80px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#gogs-source-table .date{
|
|
||||||
width: 120px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#gogs-source-table .is-dir .name {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
#gogs-source-table.table-hover > tbody > tr:hover > td {
|
|
||||||
background-color: #FEFEFE;
|
|
||||||
}
|
|
||||||
|
|
||||||
.activity-list {
|
.activity-list {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
@ -583,6 +524,70 @@ html, body {
|
||||||
color: #999;
|
color: #999;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* #gogs-source */
|
||||||
|
#gogs-source .source-toolbar:after {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gogs-source .source-toolbar .branch-switch {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gogs-source .source-toolbar .breadcrumb {
|
||||||
|
margin: 0 .5em;
|
||||||
|
padding: 6px 15px;
|
||||||
|
font-size: 16px;
|
||||||
|
vertical-align: middle;
|
||||||
|
display: inline-block;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gogs-source .source-toolbar,
|
||||||
|
#gogs-source .info-box,
|
||||||
|
#gogs-source .file-content {
|
||||||
|
margin: 0 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-box .info-head,
|
||||||
|
.info-box .info-content {
|
||||||
|
padding: 9px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-list {
|
||||||
|
background-color: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-list .icon {
|
||||||
|
font-size: 17px;
|
||||||
|
padding: 5px 0 4px 10px;
|
||||||
|
width: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-list .wrap {
|
||||||
|
display: inline-block;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
vertical-align: top;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-list .name .wrap {
|
||||||
|
max-width: 180px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-list .text .wrap {
|
||||||
|
max-width: 450px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-list .date .wrap {
|
||||||
|
max-width: 100px;
|
||||||
|
padding: 0 20px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-list .date {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
#wrapper {
|
#wrapper {
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
height: auto !important;
|
height: auto !important;
|
||||||
|
|
|
@ -99,8 +99,9 @@ function initRegister() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function initUserSetting(){
|
function initUserSetting(){
|
||||||
$('#gogs-ssh-keys').on("click",".delete",function(){
|
$('#gogs-ssh-keys .delete').confirmation({
|
||||||
var $this = $(this);
|
singleton: true,
|
||||||
|
onConfirm: function(e, $this){
|
||||||
Gogits.ajaxDelete("",{"id":$this.data("del")},function(json){
|
Gogits.ajaxDelete("",{"id":$this.data("del")},function(json){
|
||||||
if(json.ok){
|
if(json.ok){
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
|
@ -108,6 +109,6 @@ function initUserSetting(){
|
||||||
alert(json.err);
|
alert(json.err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return false;
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
259
public/js/bootstrap.min.js
vendored
259
public/js/bootstrap.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -17,3 +17,7 @@ func Home(ctx *middleware.Context) {
|
||||||
ctx.Data["PageIsHome"] = true
|
ctx.Data["PageIsHome"] = true
|
||||||
ctx.Render.HTML(200, "home", ctx.Data)
|
ctx.Render.HTML(200, "home", ctx.Data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Help(ctx *middleware.Context) string {
|
||||||
|
return "This is help page"
|
||||||
|
}
|
||||||
|
|
|
@ -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 repo
|
package repo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -60,3 +64,15 @@ func Setting(ctx *middleware.Context) {
|
||||||
ctx.Data["IsRepoToolbarSetting"] = true
|
ctx.Data["IsRepoToolbarSetting"] = true
|
||||||
ctx.Render.HTML(200, "repo/setting", ctx.Data)
|
ctx.Render.HTML(200, "repo/setting", ctx.Data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Commits(ctx *middleware.Context) string {
|
||||||
|
return "This is commits page"
|
||||||
|
}
|
||||||
|
|
||||||
|
func Issues(ctx *middleware.Context) string {
|
||||||
|
return "This is issues page"
|
||||||
|
}
|
||||||
|
|
||||||
|
func Pulls(ctx *middleware.Context) string {
|
||||||
|
return "This is pulls page"
|
||||||
|
}
|
||||||
|
|
|
@ -128,6 +128,10 @@ func SettingSSHKeys(ctx *middleware.Context, form auth.AddSSHKeyForm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := models.AddPublicKey(k); err != nil {
|
if err := models.AddPublicKey(k); err != nil {
|
||||||
|
if err.Error() == models.ErrKeyAlreadyExist.Error() {
|
||||||
|
ctx.RenderWithErr("Public key name has been used", "user/publickey", &form)
|
||||||
|
return
|
||||||
|
}
|
||||||
ctx.Handle(200, "ssh.AddPublicKey", err)
|
ctx.Handle(200, "ssh.AddPublicKey", err)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -157,15 +157,25 @@ func Delete(ctx *middleware.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rawPasswd := ctx.Query("password")
|
||||||
|
encodedPwd, _ := models.EncodePasswd(rawPasswd)
|
||||||
|
if len(encodedPwd) == 0 || encodedPwd != ctx.User.Passwd {
|
||||||
|
ctx.Data["HasError"] = true
|
||||||
|
ctx.Data["ErrorMsg"] = "Your password error. Make sure you are owner of this account."
|
||||||
|
} else {
|
||||||
if err := models.DeleteUser(ctx.User); err != nil {
|
if err := models.DeleteUser(ctx.User); err != nil {
|
||||||
ctx.Data["HasError"] = true
|
ctx.Data["HasError"] = true
|
||||||
switch err.Error() {
|
switch err {
|
||||||
case models.ErrUserOwnRepos.Error():
|
case models.ErrUserOwnRepos:
|
||||||
ctx.Data["ErrorMsg"] = "Your account still have ownership of repository, you have to delete or transfer them first."
|
ctx.Data["ErrorMsg"] = "Your account still have ownership of repository, you have to delete or transfer them first."
|
||||||
default:
|
default:
|
||||||
ctx.Handle(200, "user.Delete", err)
|
ctx.Handle(200, "user.Delete", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
ctx.Render.Redirect("/")
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Render.HTML(200, "user/delete", ctx.Data)
|
ctx.Render.HTML(200, "user/delete", ctx.Data)
|
||||||
|
@ -189,3 +199,15 @@ func Feeds(ctx *middleware.Context, form auth.FeedsForm) {
|
||||||
}
|
}
|
||||||
ctx.Render.JSON(200, &feeds)
|
ctx.Render.JSON(200, &feeds)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Issues(ctx *middleware.Context) string {
|
||||||
|
return "This is issues page"
|
||||||
|
}
|
||||||
|
|
||||||
|
func Pulls(ctx *middleware.Context) string {
|
||||||
|
return "This is pulls page"
|
||||||
|
}
|
||||||
|
|
||||||
|
func Stars(ctx *middleware.Context) string {
|
||||||
|
return "This is stars page"
|
||||||
|
}
|
||||||
|
|
2
serve.go
2
serve.go
|
@ -58,7 +58,7 @@ func runServ(*cli.Context) {
|
||||||
|
|
||||||
cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
|
cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
|
||||||
if cmd == "" {
|
if cmd == "" {
|
||||||
println("Hi ", user.Name, "! You've successfully authenticated, but Gogs does not provide shell access.")
|
println("Hi", user.Name, "! You've successfully authenticated, but Gogs does not provide shell access.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
<nav class="gogs-nav">
|
<nav class="gogs-nav">
|
||||||
<a id="gogs-nav-logo" class="gogs-nav-item{{if .PageIsHome}} active{{end}}" href="/"><img src="/img/favicon.png" alt="Gogs Logo" id="gogs-logo"></a>
|
<a id="gogs-nav-logo" class="gogs-nav-item{{if .PageIsHome}} active{{end}}" href="/"><img src="/img/favicon.png" alt="Gogs Logo" id="gogs-logo"></a>
|
||||||
<a class="gogs-nav-item{{if .PageIsUserDashboard}} active{{end}}" href="/">Dashboard</a>
|
<a class="gogs-nav-item{{if .PageIsUserDashboard}} active{{end}}" href="/">Dashboard</a>
|
||||||
<a class="gogs-nav-item" href="#">Explore</a>
|
<a class="gogs-nav-item" href="/help">Help</a>{{if .IsSigned}}
|
||||||
<a class="gogs-nav-item" href="#">Help</a>{{if .IsSigned}}
|
|
||||||
<a id="gogs-nav-out" class="gogs-nav-item navbar-right navbar-btn btn btn-danger" href="/user/logout/"><i class="fa fa-power-off fa-lg"></i></a>
|
<a id="gogs-nav-out" class="gogs-nav-item navbar-right navbar-btn btn btn-danger" href="/user/logout/"><i class="fa fa-power-off fa-lg"></i></a>
|
||||||
<a id="gogs-nav-avatar" class="gogs-nav-item navbar-right" href="{{.SignedUser.HomeLink}}" data-toggle="tooltip" data-placement="bottom" title="{{.SignedUserName}}">
|
<a id="gogs-nav-avatar" class="gogs-nav-item navbar-right" href="{{.SignedUser.HomeLink}}" data-toggle="tooltip" data-placement="bottom" title="{{.SignedUserName}}">
|
||||||
<img src="{{.SignedUser.AvatarLink}}?s=28" alt="user-avatar" title="username"/>
|
<img src="{{.SignedUser.AvatarLink}}?s=28" alt="user-avatar" title="username"/>
|
||||||
|
|
|
@ -59,7 +59,7 @@
|
||||||
<div class="col-md-8 col-md-offset-2">
|
<div class="col-md-8 col-md-offset-2">
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" name="initReadme">
|
<input type="checkbox" name="initReadme" {{if .initReadme}}checked{{end}}>
|
||||||
<strong>Initialize this repository with a README</strong>
|
<strong>Initialize this repository with a README</strong>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="gogs-repo-setting-container" class="col-md-9 tab-content">
|
<div id="gogs-repo-setting-container" class="col-md-9 tab-content">
|
||||||
<div id="options" class="tab-pane">
|
<div id="options" class="tab-pane">
|
||||||
repo-options
|
<h4>Repository Options</h4>
|
||||||
</div>
|
</div>
|
||||||
<div id="delete" class="tab-pane">
|
<div id="delete" class="tab-pane">
|
||||||
<h4>Delete Repository</h4>
|
<h4>Delete Repository</h4>
|
||||||
|
|
|
@ -4,14 +4,14 @@
|
||||||
{{template "repo/toolbar" .}}
|
{{template "repo/toolbar" .}}
|
||||||
<div id="gogs-body" class="container">
|
<div id="gogs-body" class="container">
|
||||||
<div id="gogs-source">
|
<div id="gogs-source">
|
||||||
<div id="gogs-source-toolbar">
|
<div class="source-toolbar">
|
||||||
<button class="btn btn-default pull-right"><i class="fa fa-plus-square"></i>Add File</button>
|
<button class="btn btn-default pull-right"><i class="fa fa-plus-square"></i>Add File</button>
|
||||||
<div class="dropdown branch-switch">
|
<div class="dropdown branch-switch">
|
||||||
<a href="#" class="btn btn-success dropdown-toggle" data-toggle="dropdown"><i class="fa fa-chain"></i>master
|
<a href="#" class="btn btn-success dropdown-toggle" data-toggle="dropdown"><i class="fa fa-chain"></i>master
|
||||||
<b class="caret"></b></a>
|
<b class="caret"></b></a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a class="current" href="/{{.RepositoryLink}}/branch/master">master</a></li>
|
<li><a class="current" href="/{{.RepositoryLink}}/tree/master">master</a></li>
|
||||||
<li><a href="//{{.RepositoryLink}}/branch/develop">develop</a></li>
|
<li><a href="/{{.RepositoryLink}}/tree/develop">develop</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{{$paths := .Paths}}
|
{{$paths := .Paths}}
|
||||||
|
@ -32,29 +32,60 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
<table id="gogs-source-table" class="table table-hover">
|
<div class="panel panel-default info-box">
|
||||||
|
<div class="panel-heading info-head">
|
||||||
|
Merge branch 'release/1.1.1'
|
||||||
|
</div>
|
||||||
|
<div class="panel-body info-content">
|
||||||
|
slene authored 4 days ago
|
||||||
|
</div>
|
||||||
|
<table class="panel-footer table file-list">
|
||||||
<thead class="hidden">
|
<thead class="hidden">
|
||||||
<tr>
|
<tr>
|
||||||
|
<th class="icon"></th>
|
||||||
<th class="name">Filename</th>
|
<th class="name">Filename</th>
|
||||||
<th class="date">Date modified</th>
|
|
||||||
<th class="text">Message</th>
|
<th class="text">Message</th>
|
||||||
|
<th class="date">Date modified</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{{range .Files}}
|
{{range .Files}}
|
||||||
<tr {{if .IsDir}}class="is-dir"{{end}}>
|
<tr {{if .IsDir}}class="is-dir"{{end}}>
|
||||||
<td class="name"><i class="fa {{if .IsDir}}fa-folder{{else}}fa-file{{end}}"></i>
|
<td class="icon">
|
||||||
|
<i class="fa {{if .IsDir}}fa-folder{{else}}fa-file-text-o{{end}}"></i>
|
||||||
|
</td>
|
||||||
|
<td class="name">
|
||||||
|
<span class="wrap">
|
||||||
{{if .IsDir}}
|
{{if .IsDir}}
|
||||||
<a href="/{{$username}}/{{$reponame}}/tree/{{$branchname}}/{{.Path}}">{{.Name}}</a>
|
<a href="/{{$username}}/{{$reponame}}/tree/{{$branchname}}/{{.Path}}">{{.Name}}</a>
|
||||||
{{else}}
|
{{else}}
|
||||||
<a href="#">{{.Name}} - {{FileSize .Size}}</a>
|
<a href="/{{$username}}/{{$reponame}}/blob/{{$branchname}}/{{.Name}}">{{.Name}}</a>
|
||||||
{{end}}</td>
|
{{end}}
|
||||||
<td class="date"><time datetime="{{.Created}}" data-title="true" title="{{.Created}}">{{TimeSince .Created}}</time></td>
|
</span>
|
||||||
<td class="text">{{.Message}}</td>
|
</td>
|
||||||
|
<td class="text">
|
||||||
|
<span class="wrap">
|
||||||
|
{{.Message}}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="date">
|
||||||
|
<span class="wrap">
|
||||||
|
{{TimeSince .Created}}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{end}}
|
{{end}}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="panel panel-default file-content">
|
||||||
|
<div class="panel-heading">
|
||||||
|
README.md
|
||||||
|
</div>
|
||||||
|
<div class="panel-body markdown">
|
||||||
|
httplib
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{template "base/footer" .}}
|
{{template "base/footer" .}}
|
|
@ -13,22 +13,33 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div id="gogs-user-setting-container" class="col-md-9">
|
<div id="gogs-user-setting-container" class="col-md-9">
|
||||||
<form action="/user/delete" method="post" class="form-horizontal" id="gogs-user-delete">
|
|
||||||
<h4>Delete Account</h4>
|
<h4>Delete Account</h4>
|
||||||
<p class="alert alert-danger">{{if not .HasError}}The operation will delete your account permanently. Sorry to see you go, but we know you'll back soon.{{else}}{{.ErrorMsg}}{{end}}</p>
|
<p class="alert alert-danger">{{if not .HasError}}The operation will delete your account permanently. Sorry to see you go, but we know you'll back soon.{{else}}{{.ErrorMsg}}{{end}}</p>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-md-3">
|
<button type="submit" class="btn btn-danger btn-lg" href="#delete-account-modal" id="gogs-delete-account" data-toggle="modal">Delete Account</button>
|
||||||
<button type="submit" class="btn btn-danger btn-lg">Delete Account</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="modal fade" id="delete-account-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<form action="/user/delete" method="post" class="modal-content" id="gogs-user-delete">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||||
|
<h4 class="modal-title" id="myModalLabel">Delete Account</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Make sure your are owner of this account. Please enter your password.<strong class="text-danger">*</strong></label>
|
||||||
|
<input name="password" class="form-control" type="password" placeholder="Type your account password" required="required">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||||||
|
<button type="submit" class="btn btn-danger">Delete</button>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
|
||||||
$(function(){
|
|
||||||
$('#gogs-user-delete').on('submit',function(){
|
|
||||||
return confirm("Are you sure ?");
|
|
||||||
})
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{{template "base/footer" .}}
|
{{template "base/footer" .}}
|
|
@ -5,7 +5,7 @@
|
||||||
<h4>Account Setting</h4>
|
<h4>Account Setting</h4>
|
||||||
<ul class="list-group">
|
<ul class="list-group">
|
||||||
<li class="list-group-item"><a href="/user/setting">Account Profile</a></li>
|
<li class="list-group-item"><a href="/user/setting">Account Profile</a></li>
|
||||||
<li class="list-group-item"><a href="/user/setting/Password">Password</a></li>
|
<li class="list-group-item"><a href="/user/setting/password">Password</a></li>
|
||||||
<li class="list-group-item"><a href="/user/setting/notification">Notifications</a></li>
|
<li class="list-group-item"><a href="/user/setting/notification">Notifications</a></li>
|
||||||
<li class="list-group-item list-group-item-success"><a href="/user/setting/ssh/">SSH Keys</a></li>
|
<li class="list-group-item list-group-item-success"><a href="/user/setting/ssh/">SSH Keys</a></li>
|
||||||
<li class="list-group-item"><a href="/user/setting/security">Security</a></li>
|
<li class="list-group-item"><a href="/user/setting/security">Security</a></li>
|
||||||
|
@ -18,12 +18,14 @@
|
||||||
<h4>SSH Keys</h4>{{if .AddSSHKeySuccess}}
|
<h4>SSH Keys</h4>{{if .AddSSHKeySuccess}}
|
||||||
<p class="alert alert-success">New SSH Key has been added !</p>{{else if .HasError}}<p class="alert alert-danger">{{.ErrorMsg}}</p>{{end}}
|
<p class="alert alert-success">New SSH Key has been added !</p>{{else if .HasError}}<p class="alert alert-danger">{{.ErrorMsg}}</p>{{end}}
|
||||||
<ul id="gogs-ssh-keys-list" class="list-group">
|
<ul id="gogs-ssh-keys-list" class="list-group">
|
||||||
<li class="list-group-item"><span class="name">SSH Key's name</span></li>{{range .Keys}}
|
<li class="list-group-item"><span class="name">SSH Key's name</span></li>
|
||||||
|
{{range .Keys}}
|
||||||
<li class="list-group-item">
|
<li class="list-group-item">
|
||||||
<span class="name">{{.Name}}</span>
|
<span class="name">{{.Name}}</span>
|
||||||
<span class="print">(print code)</span>
|
<span class="print">({{.Fingerprint}})</span>
|
||||||
<a href="#" class="btn btn-link btn-danger right delete" rel="{{.Id}}" data-del="{{.Id}}">Delete</a>
|
<button href="#" class="btn btn-danger delete pull-right" rel="{{.Id}}" data-del="{{.Id}}">Delete</button>
|
||||||
</li>{{end}}
|
</li>
|
||||||
|
{{end}}
|
||||||
<li class="list-group-item">
|
<li class="list-group-item">
|
||||||
<a class="btn btn-link btn-primary" href="#ssh-add-modal" id="gogs-ssh-add" data-toggle="modal">Add SSH Key</a>
|
<a class="btn btn-link btn-primary" href="#ssh-add-modal" id="gogs-ssh-add" data-toggle="modal">Add SSH Key</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
27
update.go
27
update.go
|
@ -1,13 +1,19 @@
|
||||||
|
// 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 main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/gogits/gogs/models"
|
|
||||||
|
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
|
|
||||||
git "github.com/gogits/git"
|
git "github.com/gogits/git"
|
||||||
|
|
||||||
|
"github.com/gogits/gogs/models"
|
||||||
|
"github.com/gogits/gogs/modules/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
var CmdUpdate = cli.Command{
|
var CmdUpdate = cli.Command{
|
||||||
|
@ -41,11 +47,18 @@ func runUpdate(*cli.Context) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sUserId, _ := strconv.Atoi(userId)
|
sUserId, err := strconv.Atoi(userId)
|
||||||
sRepoId, _ := strconv.Atoi(repoId)
|
|
||||||
err = models.CommitRepoAction(int64(sUserId), userName,
|
|
||||||
int64(sRepoId), repoName, lastCommit.Message())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//TODO: log
|
log.Error("runUpdate.Parse userId: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sRepoId, err := strconv.Atoi(repoId)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("runUpdate.Parse repoId: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = models.CommitRepoAction(int64(sUserId), userName,
|
||||||
|
int64(sRepoId), repoName, lastCommit.Message()); err != nil {
|
||||||
|
log.Error("runUpdate.models.CommitRepoAction: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
10
web.go
10
web.go
|
@ -50,6 +50,9 @@ func runWeb(*cli.Context) {
|
||||||
|
|
||||||
// Routers.
|
// Routers.
|
||||||
m.Get("/", middleware.SignInRequire(false), routers.Home)
|
m.Get("/", middleware.SignInRequire(false), routers.Home)
|
||||||
|
m.Get("/issues", middleware.SignInRequire(true), user.Issues)
|
||||||
|
m.Get("/pulls", middleware.SignInRequire(true), user.Pulls)
|
||||||
|
m.Get("/stars", middleware.SignInRequire(true), user.Stars)
|
||||||
m.Any("/user/login", middleware.SignOutRequire(), binding.BindIgnErr(auth.LogInForm{}), user.SignIn)
|
m.Any("/user/login", middleware.SignOutRequire(), binding.BindIgnErr(auth.LogInForm{}), user.SignIn)
|
||||||
m.Any("/user/logout", middleware.SignInRequire(true), user.SignOut)
|
m.Any("/user/logout", middleware.SignInRequire(true), user.SignOut)
|
||||||
m.Any("/user/sign_up", middleware.SignOutRequire(), binding.BindIgnErr(auth.RegisterForm{}), user.SignUp)
|
m.Any("/user/sign_up", middleware.SignOutRequire(), binding.BindIgnErr(auth.RegisterForm{}), user.SignUp)
|
||||||
|
@ -67,15 +70,18 @@ func runWeb(*cli.Context) {
|
||||||
m.Any("/repo/create", middleware.SignInRequire(true), binding.BindIgnErr(auth.CreateRepoForm{}), repo.Create)
|
m.Any("/repo/create", middleware.SignInRequire(true), binding.BindIgnErr(auth.CreateRepoForm{}), repo.Create)
|
||||||
m.Any("/repo/delete", middleware.SignInRequire(true), binding.Bind(auth.DeleteRepoForm{}), repo.Delete)
|
m.Any("/repo/delete", middleware.SignInRequire(true), binding.Bind(auth.DeleteRepoForm{}), repo.Delete)
|
||||||
|
|
||||||
|
m.Get("/help", routers.Help)
|
||||||
|
|
||||||
m.Get("/:username/:reponame/settings", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Setting)
|
m.Get("/:username/:reponame/settings", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Setting)
|
||||||
|
m.Get("/:username/:reponame/commits", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Commits)
|
||||||
|
m.Get("/:username/:reponame/issues", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Issues)
|
||||||
|
m.Get("/:username/:reponame/pulls", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Pulls)
|
||||||
m.Get("/:username/:reponame/tree/:branchname/**",
|
m.Get("/:username/:reponame/tree/:branchname/**",
|
||||||
middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Single)
|
middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Single)
|
||||||
m.Get("/:username/:reponame/tree/:branchname",
|
m.Get("/:username/:reponame/tree/:branchname",
|
||||||
middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Single)
|
middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Single)
|
||||||
m.Get("/:username/:reponame", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Single)
|
m.Get("/:username/:reponame", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Single)
|
||||||
|
|
||||||
//m.Get("/:username/:reponame", repo.Repo)
|
|
||||||
|
|
||||||
listenAddr := fmt.Sprintf("%s:%s",
|
listenAddr := fmt.Sprintf("%s:%s",
|
||||||
base.Cfg.MustValue("server", "HTTP_ADDR"),
|
base.Cfg.MustValue("server", "HTTP_ADDR"),
|
||||||
base.Cfg.MustValue("server", "HTTP_PORT", "3000"))
|
base.Cfg.MustValue("server", "HTTP_PORT", "3000"))
|
||||||
|
|
Loading…
Reference in a new issue