mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-04 02:04:11 +01:00 
			
		
		
		
	Improve delete SSH key
This commit is contained in:
		
							parent
							
								
									7cb5a15c9b
								
							
						
					
					
						commit
						8ca14e2109
					
				@ -30,4 +30,4 @@ Any significant improvement should be documented as [a GitHub issue](https://git
 | 
			
		||||
 | 
			
		||||
### ...but check for existing issues first!
 | 
			
		||||
 | 
			
		||||
Please take a moment to check that an issue doesn't already exist documenting your bug report or improvement proposal. If it does, it never hurts to add a quick "+1" or "I have this problem too". This will help prioritize the most common problems and requests.
 | 
			
		||||
Please take a moment to check that an issue or card on [Trello](https://trello.com/b/uxAoeLUl/gogs-go-git-service) doesn't already exist documenting your bug report or improvement proposal. If it does, it never hurts to add a quick "+1" or "I have this problem too". This will help prioritize the most common problems and requests.
 | 
			
		||||
							
								
								
									
										3
									
								
								bee.json
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								bee.json
									
									
									
									
									
								
							@ -13,8 +13,7 @@
 | 
			
		||||
		"others": [
 | 
			
		||||
			"modules",
 | 
			
		||||
			"$GOPATH/src/github.com/gogits/logs",
 | 
			
		||||
			"$GOPATH/src/github.com/gogits/git",
 | 
			
		||||
			"$GOPATH/src/github.com/gogits/gfm"
 | 
			
		||||
			"$GOPATH/src/github.com/gogits/git"
 | 
			
		||||
		]
 | 
			
		||||
	},
 | 
			
		||||
	"cmd_args": [
 | 
			
		||||
 | 
			
		||||
@ -180,7 +180,7 @@ func runWeb(*cli.Context) {
 | 
			
		||||
	}, reqSignIn, middleware.RepoAssignment(true), reqOwner)
 | 
			
		||||
 | 
			
		||||
	m.Group("/:username/:reponame", func(r martini.Router) {
 | 
			
		||||
		r.Get("/action/:action", repo.Action) // TODO
 | 
			
		||||
		r.Get("/action/:action", repo.Action)
 | 
			
		||||
		r.Get("/issues/new", repo.CreateIssue)
 | 
			
		||||
		r.Post("/issues/new", bindIgnErr(auth.CreateIssueForm{}), repo.CreateIssuePost)
 | 
			
		||||
		r.Post("/issues/:index", bindIgnErr(auth.CreateIssueForm{}), repo.UpdateIssue)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										3
									
								
								gogs.go
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								gogs.go
									
									
									
									
									
								
							@ -17,9 +17,6 @@ import (
 | 
			
		||||
	"github.com/gogits/gogs/modules/base"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Test that go1.2 tag above is included in builds. main.go refers to this definition.
 | 
			
		||||
const go12tag = true
 | 
			
		||||
 | 
			
		||||
const APP_VER = "0.3.3.0506 Alpha"
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
 | 
			
		||||
@ -30,19 +30,17 @@ type Issue struct {
 | 
			
		||||
	IsPull          bool // Indicates whether is a pull request or not.
 | 
			
		||||
	IsClosed        bool
 | 
			
		||||
	Labels          string `xorm:"TEXT"`
 | 
			
		||||
	Mentions        string `xorm:"TEXT"`
 | 
			
		||||
	Content         string `xorm:"TEXT"`
 | 
			
		||||
	RenderedContent string `xorm:"-"`
 | 
			
		||||
	Priority        int
 | 
			
		||||
	NumComments     int
 | 
			
		||||
	Deadline        time.Time
 | 
			
		||||
	Created         time.Time `xorm:"created"`
 | 
			
		||||
	Updated         time.Time `xorm:"updated"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CreateIssue creates new issue for repository.
 | 
			
		||||
func CreateIssue(userId, repoId, milestoneId, assigneeId int64, issueCount int, name, labels, content string, isPull bool) (issue *Issue, err error) {
 | 
			
		||||
	// TODO: find out mentions
 | 
			
		||||
	mentions := ""
 | 
			
		||||
 | 
			
		||||
	sess := orm.NewSession()
 | 
			
		||||
	defer sess.Close()
 | 
			
		||||
	sess.Begin()
 | 
			
		||||
@ -56,7 +54,6 @@ func CreateIssue(userId, repoId, milestoneId, assigneeId int64, issueCount int,
 | 
			
		||||
		AssigneeId:  assigneeId,
 | 
			
		||||
		IsPull:      isPull,
 | 
			
		||||
		Labels:      labels,
 | 
			
		||||
		Mentions:    mentions,
 | 
			
		||||
		Content:     content,
 | 
			
		||||
	}
 | 
			
		||||
	if _, err = sess.Insert(issue); err != nil {
 | 
			
		||||
 | 
			
		||||
@ -139,10 +139,9 @@ func NewEngine() (err error) {
 | 
			
		||||
 | 
			
		||||
type Statistic struct {
 | 
			
		||||
	Counter struct {
 | 
			
		||||
		User, PublicKey, Repo,
 | 
			
		||||
		Watch, Action, Access,
 | 
			
		||||
		Issue, Comment,
 | 
			
		||||
		Mirror, Oauth, Release int64
 | 
			
		||||
		User, PublicKey, Repo, Watch, Action, Access,
 | 
			
		||||
		Issue, Comment, Mirror, Oauth, Release,
 | 
			
		||||
		LoginSource, Webhook int64
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -158,6 +157,8 @@ func GetStatistic() (stats Statistic) {
 | 
			
		||||
	stats.Counter.Mirror, _ = orm.Count(new(Mirror))
 | 
			
		||||
	stats.Counter.Oauth, _ = orm.Count(new(Oauth2))
 | 
			
		||||
	stats.Counter.Release, _ = orm.Count(new(Release))
 | 
			
		||||
	stats.Counter.LoginSource, _ = orm.Count(new(LoginSource))
 | 
			
		||||
	stats.Counter.Webhook, _ = orm.Count(new(Webhook))
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -6,12 +6,11 @@ package models
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/exec"
 | 
			
		||||
	"path"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
@ -19,7 +18,9 @@ import (
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/Unknwon/com"
 | 
			
		||||
	qlog "github.com/qiniu/log"
 | 
			
		||||
 | 
			
		||||
	"github.com/gogits/gogs/modules/base"
 | 
			
		||||
	"github.com/gogits/gogs/modules/log"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@ -30,29 +31,21 @@ const (
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	ErrKeyAlreadyExist = errors.New("Public key already exist")
 | 
			
		||||
	ErrKeyNotExist     = errors.New("Public key does not exist")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var sshOpLocker = sync.Mutex{}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	sshPath string
 | 
			
		||||
	appPath string
 | 
			
		||||
	sshPath string // SSH directory.
 | 
			
		||||
	appPath string // Execution(binary) path.
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// exePath returns the executable path.
 | 
			
		||||
func exePath() (string, error) {
 | 
			
		||||
	file, err := exec.LookPath(os.Args[0])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	return filepath.Abs(file)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// homeDir returns the home directory of current user.
 | 
			
		||||
func homeDir() string {
 | 
			
		||||
	home, err := com.HomeDir()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "/"
 | 
			
		||||
		qlog.Fatalln(err)
 | 
			
		||||
	}
 | 
			
		||||
	return home
 | 
			
		||||
}
 | 
			
		||||
@ -60,17 +53,14 @@ func homeDir() string {
 | 
			
		||||
func init() {
 | 
			
		||||
	var err error
 | 
			
		||||
 | 
			
		||||
	appPath, err = exePath()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		fmt.Printf("publickey.init(fail to get app path): %v\n", err)
 | 
			
		||||
		os.Exit(2)
 | 
			
		||||
	if appPath, err = base.ExecDir(); err != nil {
 | 
			
		||||
		qlog.Fatalf("publickey.init(fail to get app path): %v\n", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Determine and create .ssh path.
 | 
			
		||||
	sshPath = filepath.Join(homeDir(), ".ssh")
 | 
			
		||||
	if err = os.MkdirAll(sshPath, os.ModePerm); err != nil {
 | 
			
		||||
		fmt.Printf("publickey.init(fail to create sshPath(%s)): %v\n", sshPath, err)
 | 
			
		||||
		os.Exit(2)
 | 
			
		||||
		qlog.Fatalf("publickey.init(fail to create sshPath(%s)): %v\n", sshPath, err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -129,8 +119,8 @@ func AddPublicKey(key *PublicKey) (err error) {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// rewriteAuthorizedKeys finds and deletes corresponding line in authorized_keys file.
 | 
			
		||||
func rewriteAuthorizedKeys(key *PublicKey, p, tmpP string) error {
 | 
			
		||||
	// Delete SSH key in SSH key file.
 | 
			
		||||
	sshOpLocker.Lock()
 | 
			
		||||
	defer sshOpLocker.Unlock()
 | 
			
		||||
 | 
			
		||||
@ -146,55 +136,48 @@ func rewriteAuthorizedKeys(key *PublicKey, p, tmpP string) error {
 | 
			
		||||
	}
 | 
			
		||||
	defer fw.Close()
 | 
			
		||||
 | 
			
		||||
	buf := bufio.NewReader(fr)
 | 
			
		||||
	for {
 | 
			
		||||
		line, errRead := buf.ReadString('\n')
 | 
			
		||||
		line = strings.TrimSpace(line)
 | 
			
		||||
	isFound := false
 | 
			
		||||
	keyword := []byte(fmt.Sprintf("key-%d", key.Id))
 | 
			
		||||
	content := []byte(key.Content)
 | 
			
		||||
 | 
			
		||||
		if errRead != nil {
 | 
			
		||||
			if errRead != io.EOF {
 | 
			
		||||
				return errRead
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Reached end of file, if nothing to read then break,
 | 
			
		||||
			// otherwise handle the last line.
 | 
			
		||||
	snr := bufio.NewScanner(fr)
 | 
			
		||||
	for snr.Scan() {
 | 
			
		||||
		line := append(bytes.TrimSpace(snr.Bytes()), '\n')
 | 
			
		||||
		if len(line) == 0 {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Found the line and copy rest of file.
 | 
			
		||||
		if strings.Contains(line, fmt.Sprintf("key-%d", key.Id)) && strings.Contains(line, key.Content) {
 | 
			
		||||
		if !isFound && bytes.Contains(line, keyword) && bytes.Contains(line, content) {
 | 
			
		||||
			isFound = true
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Still finding the line, copy the line that currently read.
 | 
			
		||||
		if _, err = fw.WriteString(line + "\n"); err != nil {
 | 
			
		||||
		if _, err = fw.Write(line); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
		if errRead == io.EOF {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DeletePublicKey deletes SSH key information both in database and authorized_keys file.
 | 
			
		||||
func DeletePublicKey(key *PublicKey) (err error) {
 | 
			
		||||
	// Delete SSH key in database.
 | 
			
		||||
	has, err := orm.Id(key.Id).Get(key)
 | 
			
		||||
func DeletePublicKey(key *PublicKey) error {
 | 
			
		||||
	has, err := orm.Get(key)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	} else if !has {
 | 
			
		||||
		return errors.New("Public key does not exist")
 | 
			
		||||
		return ErrKeyNotExist
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if _, err = orm.Delete(key); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p := filepath.Join(sshPath, "authorized_keys")
 | 
			
		||||
	tmpP := filepath.Join(sshPath, "authorized_keys.tmp")
 | 
			
		||||
	log.Trace("ssh.DeletePublicKey(authorized_keys): %s", p)
 | 
			
		||||
	log.Trace("publickey.DeletePublicKey(authorized_keys): %s", p)
 | 
			
		||||
 | 
			
		||||
	if err = rewriteAuthorizedKeys(key, p, tmpP); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,6 @@ var (
 | 
			
		||||
	ErrUserNotExist     = errors.New("User does not exist")
 | 
			
		||||
	ErrEmailAlreadyUsed = errors.New("E-mail already used")
 | 
			
		||||
	ErrUserNameIllegal  = errors.New("User name contains illegal characters")
 | 
			
		||||
	ErrKeyNotExist      = errors.New("Public key does not exist")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// User represents the object of individual and member of organization.
 | 
			
		||||
@ -315,12 +314,12 @@ func DeleteUser(user *User) error {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Delete all SSH keys.
 | 
			
		||||
	keys := make([]PublicKey, 0, 10)
 | 
			
		||||
	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 {
 | 
			
		||||
		if err = DeletePublicKey(key); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,6 @@ import (
 | 
			
		||||
	"github.com/go-martini/martini"
 | 
			
		||||
 | 
			
		||||
	"github.com/gogits/gogs/modules/base"
 | 
			
		||||
	"github.com/gogits/gogs/modules/log"
 | 
			
		||||
	"github.com/gogits/gogs/modules/middleware/binding"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@ -31,20 +30,6 @@ func (f *CreateIssueForm) Name(field string) string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *CreateIssueForm) Validate(errors *binding.BindingErrors, 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)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,6 @@ import (
 | 
			
		||||
	"github.com/go-martini/martini"
 | 
			
		||||
 | 
			
		||||
	"github.com/gogits/gogs/modules/base"
 | 
			
		||||
	"github.com/gogits/gogs/modules/log"
 | 
			
		||||
	"github.com/gogits/gogs/modules/middleware/binding"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@ -32,20 +31,6 @@ func (f *NewReleaseForm) Name(field string) string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *NewReleaseForm) Validate(errors *binding.BindingErrors, 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("NewReleaseForm.Validate: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	validate(errors, data, f)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -98,6 +98,7 @@ var Service struct {
 | 
			
		||||
	LdapAuth             bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ExecDir returns absolute path execution(binary) path.
 | 
			
		||||
func ExecDir() (string, error) {
 | 
			
		||||
	file, err := exec.LookPath(os.Args[0])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@ package middleware
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/go-martini/martini"
 | 
			
		||||
 | 
			
		||||
@ -40,6 +41,10 @@ func Toggle(options *ToggleOptions) martini.Handler {
 | 
			
		||||
 | 
			
		||||
		if options.SignInRequire {
 | 
			
		||||
			if !ctx.IsSigned {
 | 
			
		||||
				// Ignore watch repository operation.
 | 
			
		||||
				if strings.HasSuffix(ctx.Req.RequestURI, "watch") {
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
				ctx.SetCookie("redirect_to", "/"+url.QueryEscape(ctx.Req.RequestURI))
 | 
			
		||||
				ctx.Redirect("/user/login")
 | 
			
		||||
				return
 | 
			
		||||
 | 
			
		||||
@ -154,12 +154,8 @@ func SettingSSHKeys(ctx *middleware.Context, form auth.AddSSHKeyForm) {
 | 
			
		||||
			})
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		k := &models.PublicKey{
 | 
			
		||||
			Id:      id,
 | 
			
		||||
			OwnerId: ctx.User.Id,
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if err = models.DeletePublicKey(k); err != nil {
 | 
			
		||||
		if err = models.DeletePublicKey(&models.PublicKey{Id: id}); err != nil {
 | 
			
		||||
			log.Error("ssh.DelPublicKey: %v", err)
 | 
			
		||||
			ctx.JSON(200, map[string]interface{}{
 | 
			
		||||
				"ok":  false,
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,7 @@
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <div class="panel-body">
 | 
			
		||||
                Gogs database has <b>{{.Stats.Counter.User}}</b> users, <b>{{.Stats.Counter.PublicKey}}</b> SSH keys, <b>{{.Stats.Counter.Repo}}</b> repositories, <b>{{.Stats.Counter.Watch}}</b> watches, <b>{{.Stats.Counter.Action}}</b> actions, <b>{{.Stats.Counter.Access}}</b> accesses, <b>{{.Stats.Counter.Issue}}</b> issues, <b>{{.Stats.Counter.Comment}}</b> comments, <b>{{.Stats.Counter.Mirror}}</b> mirrors, <b>{{.Stats.Counter.Oauth}}</b> oauthes, <b>{{.Stats.Counter.Release}}</b> releases.
 | 
			
		||||
                Gogs database has <b>{{.Stats.Counter.User}}</b> users, <b>{{.Stats.Counter.PublicKey}}</b> SSH keys, <b>{{.Stats.Counter.Repo}}</b> repositories, <b>{{.Stats.Counter.Watch}}</b> watches, <b>{{.Stats.Counter.Action}}</b> actions, <b>{{.Stats.Counter.Access}}</b> accesses, <b>{{.Stats.Counter.Issue}}</b> issues, <b>{{.Stats.Counter.Comment}}</b> comments, <b>{{.Stats.Counter.Mirror}}</b> mirrors, <b>{{.Stats.Counter.Oauth}}</b> oauthes, <b>{{.Stats.Counter.Release}}</b> releases, <b>{{.Stats.Counter.LoginSource}}</b> login sources, <b>{{.Stats.Counter.Webhook}}</b> webhooks.
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user