diff --git a/conf/app.ini b/conf/app.ini index 3e5a126f8..f8ff81db7 100644 --- a/conf/app.ini +++ b/conf/app.ini @@ -3,8 +3,8 @@ RUN_USER = lunny [repository] ROOT = /Users/%(RUN_USER)s/git/gogs-repositories -LANG_IGNS=Google Go|C|Python -LICENSES=Apache v2 License|GPL v2|BSD (3-Clause) License +LANG_IGNS=Google Go|C|Python|Ruby +LICENSES=Apache v2 License|GPL v2|MIT License|BSD (3-Clause) License [server] HTTP_ADDR = diff --git a/conf/gitignore/Ruby b/conf/gitignore/Ruby new file mode 100644 index 000000000..eb76b2485 --- /dev/null +++ b/conf/gitignore/Ruby @@ -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/ \ No newline at end of file diff --git a/conf/license/MIT License b/conf/license/MIT License new file mode 100644 index 000000000..be1d1ae04 --- /dev/null +++ b/conf/license/MIT License @@ -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. \ No newline at end of file diff --git a/models/publickey.go b/models/publickey.go index 49d7f3082..2f32dc3f0 100644 --- a/models/publickey.go +++ b/models/publickey.go @@ -1,21 +1,30 @@ +// 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 ( + "bufio" "fmt" + "io" "os" "os/exec" "path/filepath" + "strings" + "sync" "time" "github.com/Unknwon/com" ) var ( + sshOpLocker = sync.Mutex{} //publicKeyRootPath string - sshPath string - appPath string - tmplPublicKey = "### autogenerated by gitgos, DO NOT EDIT\n" + - "command=\"%s serv key-%d\",no-port-forwarding," + + sshPath string + appPath string + // "### autogenerated by gitgos, DO NOT EDIT\n" + tmplPublicKey = "command=\"%s serv key-%d\",no-port-forwarding," + "no-X11-forwarding,no-agent-forwarding,no-pty %s\n" ) @@ -77,9 +86,69 @@ func AddPublicKey(key *PublicKey) error { return nil } -func DeletePublicKey(key *PublicKey) error { - _, err := orm.Delete(key) - return err +// DeletePublicKey deletes SSH key information both in database and authorized_keys file. +func DeletePublicKey(key *PublicKey) (err error) { + 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, key.Content) { + if _, err = io.Copy(fw, fr); err != nil { + return err + } + break + } + + // 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) { @@ -89,11 +158,16 @@ func ListPublicKey(userId int64) ([]PublicKey, error) { } func SaveAuthorizedKeyFile(key *PublicKey) error { + sshOpLocker.Lock() + defer sshOpLocker.Unlock() + p := filepath.Join(sshPath, "authorized_keys") f, err := os.OpenFile(p, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600) if err != nil { return err } + defer f.Close() + //os.Chmod(p, 0600) _, err = f.WriteString(GenAuthorizedKey(key.Id, key.Content)) return err diff --git a/models/user.go b/models/user.go index a0e4bb800..ffeb72525 100644 --- a/models/user.go +++ b/models/user.go @@ -142,6 +142,7 @@ func UpdateUser(user *User) (err error) { // DeleteUser completely deletes everything of the user. func DeleteUser(user *User) error { + // Check ownership of repository. count, err := GetRepositoryCount(user) if err != nil { return errors.New("modesl.GetRepositories: " + err.Error()) @@ -151,6 +152,17 @@ func DeleteUser(user *User) error { // TODO: check issues, other repos' commits + // Delete 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) // TODO: delete and update follower information. return err diff --git a/routers/repo/single.go b/routers/repo/single.go index a0f444716..eda30c00a 100644 --- a/routers/repo/single.go +++ b/routers/repo/single.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 repo import (