From: Unknown Date: Tue, 11 Mar 2014 00:48:58 +0000 (-0400) Subject: Add add and delete SSH key X-Git-Tag: v0.9.99~2483 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=897329a64416dd46b9e4f5a81c3c7a1666fc1173;p=gitea.git Add add and delete SSH key --- diff --git a/gogs.go b/gogs.go index a63cc571e3..7dcc66831f 100644 --- a/gogs.go +++ b/gogs.go @@ -19,7 +19,7 @@ import ( // Test that go1.1 tag above is included in builds. main.go refers to this definition. const go11tag = true -const APP_VER = "0.0.2.0309" +const APP_VER = "0.0.2.0310" func init() { runtime.GOMAXPROCS(runtime.NumCPU()) diff --git a/models/repo.go b/models/repo.go index 05612a4229..d17f32976a 100644 --- a/models/repo.go +++ b/models/repo.go @@ -6,6 +6,7 @@ package models import ( "errors" + "fmt" "os" "path/filepath" "strings" @@ -83,7 +84,8 @@ func CreateRepository(user *User, repoName, desc string, private bool) (*Reposit if _, err = session.Insert(repo); err != nil { if err2 := os.RemoveAll(f); err2 != nil { - log.Error("delete repo directory %s/%s failed", user.Name, repoName) + return nil, errors.New(fmt.Sprintf( + "delete repo directory %s/%s failed", user.Name, repoName)) } session.Rollback() return nil, err @@ -97,7 +99,8 @@ func CreateRepository(user *User, repoName, desc string, private bool) (*Reposit } if _, err = session.Insert(&access); err != nil { if err2 := os.RemoveAll(f); err2 != nil { - log.Error("delete repo directory %s/%s failed", user.Name, repoName) + return nil, errors.New(fmt.Sprintf( + "delete repo directory %s/%s failed", user.Name, repoName)) } session.Rollback() return nil, err @@ -105,7 +108,8 @@ func CreateRepository(user *User, repoName, desc string, private bool) (*Reposit if _, err = session.Exec("update user set num_repos = num_repos + 1 where id = ?", user.Id); err != nil { if err2 := os.RemoveAll(f); err2 != nil { - log.Error("delete repo directory %s/%s failed", user.Name, repoName) + return nil, errors.New(fmt.Sprintf( + "delete repo directory %s/%s failed", user.Name, repoName)) } session.Rollback() return nil, err @@ -113,7 +117,8 @@ func CreateRepository(user *User, repoName, desc string, private bool) (*Reposit if err = session.Commit(); err != nil { if err2 := os.RemoveAll(f); err2 != nil { - log.Error("delete repo directory %s/%s failed", user.Name, repoName) + return nil, errors.New(fmt.Sprintf( + "delete repo directory %s/%s failed", user.Name, repoName)) } session.Rollback() return nil, err @@ -121,6 +126,14 @@ func CreateRepository(user *User, repoName, desc string, private bool) (*Reposit return repo, nil } +// InitRepository initializes README and .gitignore if needed. +func InitRepository(repo *Repository, initReadme bool, repoLang string) error { + // README. + + // .gitignore + return nil +} + // GetRepositories returns the list of repositories of given user. func GetRepositories(user *User) ([]Repository, error) { repos := make([]Repository, 0, 10) diff --git a/modules/auth/auth.go b/modules/auth/auth.go new file mode 100644 index 0000000000..b085527554 --- /dev/null +++ b/modules/auth/auth.go @@ -0,0 +1,162 @@ +// Copyright 2014 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package auth + +import ( + "net/http" + "reflect" + "strings" + + "github.com/codegangsta/martini" + + "github.com/gogits/binding" + + "github.com/gogits/gogs/modules/base" + "github.com/gogits/gogs/modules/log" +) + +// Web form interface. +type Form interface { + Name(field string) string +} + +type RegisterForm struct { + UserName string `form:"username" binding:"Required;AlphaDash;MinSize(5);MaxSize(30)"` + Email string `form:"email" binding:"Required;Email;MaxSize(50)"` + Password string `form:"passwd" binding:"Required;MinSize(6);MaxSize(30)"` + RetypePasswd string `form:"retypepasswd"` +} + +func (f *RegisterForm) Name(field string) string { + names := map[string]string{ + "UserName": "Username", + "Email": "E-mail address", + "Password": "Password", + "RetypePasswd": "Re-type password", + } + return names[field] +} + +func (f *RegisterForm) Validate(errors *binding.Errors, req *http.Request, context martini.Context) { + if req.Method == "GET" || errors.Count() == 0 { + return + } + + data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData) + data["HasError"] = true + AssignForm(f, data) + + if len(errors.Overall) > 0 { + for _, err := range errors.Overall { + log.Error("RegisterForm.Validate: %v", err) + } + return + } + + validate(errors, data, f) +} + +type LogInForm struct { + UserName string `form:"username" binding:"Required;AlphaDash;MinSize(5);MaxSize(30)"` + Password string `form:"passwd" binding:"Required;MinSize(6);MaxSize(30)"` +} + +func (f *LogInForm) Name(field string) string { + names := map[string]string{ + "UserName": "Username", + "Password": "Password", + } + return names[field] +} + +func (f *LogInForm) Validate(errors *binding.Errors, req *http.Request, context martini.Context) { + if req.Method == "GET" || errors.Count() == 0 { + return + } + + data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData) + data["HasError"] = true + AssignForm(f, data) + + if len(errors.Overall) > 0 { + for _, err := range errors.Overall { + log.Error("LogInForm.Validate: %v", err) + } + return + } + + validate(errors, data, f) +} + +func getMinMaxSize(field reflect.StructField) string { + for _, rule := range strings.Split(field.Tag.Get("binding"), ";") { + if strings.HasPrefix(rule, "MinSize(") || strings.HasPrefix(rule, "MaxSize(") { + return rule[8 : len(rule)-1] + } + } + return "" +} + +func validate(errors *binding.Errors, data base.TmplData, form Form) { + typ := reflect.TypeOf(form) + val := reflect.ValueOf(form) + + if typ.Kind() == reflect.Ptr { + typ = typ.Elem() + val = val.Elem() + } + + for i := 0; i < typ.NumField(); i++ { + field := typ.Field(i) + + fieldName := field.Tag.Get("form") + // Allow ignored fields in the struct + if fieldName == "-" { + continue + } + + if err, ok := errors.Fields[field.Name]; ok { + data["Err_"+field.Name] = true + switch err { + case binding.RequireError: + data["ErrorMsg"] = form.Name(field.Name) + " cannot be empty" + case binding.AlphaDashError: + data["ErrorMsg"] = form.Name(field.Name) + " must be valid alpha or numeric or dash(-_) characters" + case binding.MinSizeError: + data["ErrorMsg"] = form.Name(field.Name) + " must contain at least " + getMinMaxSize(field) + " characters" + case binding.MaxSizeError: + data["ErrorMsg"] = form.Name(field.Name) + " must contain at most " + getMinMaxSize(field) + " characters" + case binding.EmailError: + data["ErrorMsg"] = form.Name(field.Name) + " is not valid" + default: + data["ErrorMsg"] = "Unknown error: " + err + } + return + } + } +} + +// AssignForm assign form values back to the template data. +func AssignForm(form interface{}, data base.TmplData) { + typ := reflect.TypeOf(form) + val := reflect.ValueOf(form) + + if typ.Kind() == reflect.Ptr { + typ = typ.Elem() + val = val.Elem() + } + + for i := 0; i < typ.NumField(); i++ { + field := typ.Field(i) + + fieldName := field.Tag.Get("form") + // Allow ignored fields in the struct + if fieldName == "-" { + continue + } + + data[fieldName] = val.Field(i).Interface() + } +} diff --git a/modules/auth/form.go b/modules/auth/form.go deleted file mode 100644 index b085527554..0000000000 --- a/modules/auth/form.go +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright 2014 The Gogs Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package auth - -import ( - "net/http" - "reflect" - "strings" - - "github.com/codegangsta/martini" - - "github.com/gogits/binding" - - "github.com/gogits/gogs/modules/base" - "github.com/gogits/gogs/modules/log" -) - -// Web form interface. -type Form interface { - Name(field string) string -} - -type RegisterForm struct { - UserName string `form:"username" binding:"Required;AlphaDash;MinSize(5);MaxSize(30)"` - Email string `form:"email" binding:"Required;Email;MaxSize(50)"` - Password string `form:"passwd" binding:"Required;MinSize(6);MaxSize(30)"` - RetypePasswd string `form:"retypepasswd"` -} - -func (f *RegisterForm) Name(field string) string { - names := map[string]string{ - "UserName": "Username", - "Email": "E-mail address", - "Password": "Password", - "RetypePasswd": "Re-type password", - } - return names[field] -} - -func (f *RegisterForm) Validate(errors *binding.Errors, req *http.Request, context martini.Context) { - if req.Method == "GET" || errors.Count() == 0 { - return - } - - data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData) - data["HasError"] = true - AssignForm(f, data) - - if len(errors.Overall) > 0 { - for _, err := range errors.Overall { - log.Error("RegisterForm.Validate: %v", err) - } - return - } - - validate(errors, data, f) -} - -type LogInForm struct { - UserName string `form:"username" binding:"Required;AlphaDash;MinSize(5);MaxSize(30)"` - Password string `form:"passwd" binding:"Required;MinSize(6);MaxSize(30)"` -} - -func (f *LogInForm) Name(field string) string { - names := map[string]string{ - "UserName": "Username", - "Password": "Password", - } - return names[field] -} - -func (f *LogInForm) Validate(errors *binding.Errors, req *http.Request, context martini.Context) { - if req.Method == "GET" || errors.Count() == 0 { - return - } - - data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData) - data["HasError"] = true - AssignForm(f, data) - - if len(errors.Overall) > 0 { - for _, err := range errors.Overall { - log.Error("LogInForm.Validate: %v", err) - } - return - } - - validate(errors, data, f) -} - -func getMinMaxSize(field reflect.StructField) string { - for _, rule := range strings.Split(field.Tag.Get("binding"), ";") { - if strings.HasPrefix(rule, "MinSize(") || strings.HasPrefix(rule, "MaxSize(") { - return rule[8 : len(rule)-1] - } - } - return "" -} - -func validate(errors *binding.Errors, data base.TmplData, form Form) { - typ := reflect.TypeOf(form) - val := reflect.ValueOf(form) - - if typ.Kind() == reflect.Ptr { - typ = typ.Elem() - val = val.Elem() - } - - for i := 0; i < typ.NumField(); i++ { - field := typ.Field(i) - - fieldName := field.Tag.Get("form") - // Allow ignored fields in the struct - if fieldName == "-" { - continue - } - - if err, ok := errors.Fields[field.Name]; ok { - data["Err_"+field.Name] = true - switch err { - case binding.RequireError: - data["ErrorMsg"] = form.Name(field.Name) + " cannot be empty" - case binding.AlphaDashError: - data["ErrorMsg"] = form.Name(field.Name) + " must be valid alpha or numeric or dash(-_) characters" - case binding.MinSizeError: - data["ErrorMsg"] = form.Name(field.Name) + " must contain at least " + getMinMaxSize(field) + " characters" - case binding.MaxSizeError: - data["ErrorMsg"] = form.Name(field.Name) + " must contain at most " + getMinMaxSize(field) + " characters" - case binding.EmailError: - data["ErrorMsg"] = form.Name(field.Name) + " is not valid" - default: - data["ErrorMsg"] = "Unknown error: " + err - } - return - } - } -} - -// AssignForm assign form values back to the template data. -func AssignForm(form interface{}, data base.TmplData) { - typ := reflect.TypeOf(form) - val := reflect.ValueOf(form) - - if typ.Kind() == reflect.Ptr { - typ = typ.Elem() - val = val.Elem() - } - - for i := 0; i < typ.NumField(); i++ { - field := typ.Field(i) - - fieldName := field.Tag.Get("form") - // Allow ignored fields in the struct - if fieldName == "-" { - continue - } - - data[fieldName] = val.Field(i).Interface() - } -} diff --git a/modules/auth/setting.go b/modules/auth/setting.go new file mode 100644 index 0000000000..0bc6afd4a6 --- /dev/null +++ b/modules/auth/setting.go @@ -0,0 +1,55 @@ +// Copyright 2014 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package auth + +import ( + "net/http" + "reflect" + "strings" + + "github.com/codegangsta/martini" + + "github.com/gogits/binding" + + "github.com/gogits/gogs/modules/base" + "github.com/gogits/gogs/modules/log" +) + +type AddSSHKeyForm struct { + KeyName string `form:"keyname" binding:"Required"` + KeyContent string `form:"key_content" binding:"Required"` +} + +func (f *AddSSHKeyForm) Name(field string) string { + names := map[string]string{ + "KeyName": "SSH key name", + "KeyContent": "SSH key content", + } + return names[field] +} + +func (f *AddSSHKeyForm) Validate(errors *binding.Errors, req *http.Request, context martini.Context) { + data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData) + AssignForm(f, data) + + if req.Method == "GET" || errors.Count() == 0 { + if req.Method == "POST" && + (len(f.KeyContent) < 100 || !strings.HasPrefix(f.KeyContent, "ssh-rsa")) { + data["HasError"] = true + data["ErrorMsg"] = "SSH key content is not valid" + } + return + } + + data["HasError"] = true + if len(errors.Overall) > 0 { + for _, err := range errors.Overall { + log.Error("AddSSHKeyForm.Validate: %v", err) + } + return + } + + validate(errors, data, f) +} diff --git a/routers/repo/repo.go b/routers/repo/repo.go index 7353436a5f..6f59b408e0 100644 --- a/routers/repo/repo.go +++ b/routers/repo/repo.go @@ -44,16 +44,14 @@ func Create(form auth.CreateRepoForm, req *http.Request, r render.Render, data b } fmt.Println(models.RepoPath(user.Name, form.RepoName)) if err == nil { - if _, err = models.CreateRepository(user, + if repo, err := models.CreateRepository(user, form.RepoName, form.Description, form.Visibility == "private"); err == nil { - // Initialize README. - if form.InitReadme == "true" { - // TODO + err = models.InitRepository(repo, form.InitReadme == "true", form.Language) + if err == nil { + data["RepoName"] = user.Name + "/" + form.RepoName + r.HTML(200, "repo/created", data) + return } - // TODO: init .gitignore file - data["RepoName"] = user.Name + "/" + form.RepoName - r.HTML(200, "repo/created", data) - return } } diff --git a/routers/user/setting.go b/routers/user/setting.go index aabbc21293..96a02b6f46 100644 --- a/routers/user/setting.go +++ b/routers/user/setting.go @@ -5,14 +5,16 @@ package user import ( + "net/http" + "strconv" + + "github.com/martini-contrib/render" + "github.com/martini-contrib/sessions" + "github.com/gogits/gogs/models" "github.com/gogits/gogs/modules/auth" "github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/log" - "github.com/martini-contrib/render" - "github.com/martini-contrib/sessions" - "net/http" - "strconv" ) func Setting(r render.Render, data base.TmplData, session sessions.Session) { @@ -21,9 +23,12 @@ func Setting(r render.Render, data base.TmplData, session sessions.Session) { r.HTML(200, "user/setting", data) } -func SettingSSHKeys(r render.Render, data base.TmplData, req *http.Request, session sessions.Session) { - // del ssh ky +func SettingSSHKeys(form auth.AddSSHKeyForm, r render.Render, data base.TmplData, req *http.Request, session sessions.Session) { + data["Title"] = "SSH Keys" + + // Delete SSH key. if req.Method == "DELETE" || req.FormValue("_method") == "DELETE" { + println(1) id, err := strconv.ParseInt(req.FormValue("id"), 10, 64) if err != nil { data["ErrorMsg"] = err @@ -38,8 +43,8 @@ func SettingSSHKeys(r render.Render, data base.TmplData, req *http.Request, sess Id: id, OwnerId: auth.SignedInId(session), } - err = models.DeletePublicKey(k) - if err != nil { + + if err = models.DeletePublicKey(k); err != nil { data["ErrorMsg"] = err log.Error("ssh.DelPublicKey: %v", err) r.JSON(200, map[string]interface{}{ @@ -51,16 +56,21 @@ func SettingSSHKeys(r render.Render, data base.TmplData, req *http.Request, sess "ok": true, }) } - return } - // add ssh key + + // Add new SSH key. if req.Method == "POST" { + if hasErr, ok := data["HasError"]; ok && hasErr.(bool) { + r.HTML(200, "user/publickey", data) + return + } + k := &models.PublicKey{OwnerId: auth.SignedInId(session), - Name: req.FormValue("keyname"), - Content: req.FormValue("key_content"), + Name: form.KeyName, + Content: form.KeyContent, } - err := models.AddPublicKey(k) - if err != nil { + + if err := models.AddPublicKey(k); err != nil { data["ErrorMsg"] = err log.Error("ssh.AddPublicKey: %v", err) r.HTML(200, "base/error", data) @@ -69,7 +79,8 @@ func SettingSSHKeys(r render.Render, data base.TmplData, req *http.Request, sess data["AddSSHKeySuccess"] = true } } - // get keys + + // List existed SSH keys. keys, err := models.ListPublicKey(auth.SignedInId(session)) if err != nil { data["ErrorMsg"] = err @@ -78,8 +89,6 @@ func SettingSSHKeys(r render.Render, data base.TmplData, req *http.Request, sess return } - // set to template - data["Title"] = "SSH Keys" data["PageIsUserSetting"] = true data["Keys"] = keys r.HTML(200, "user/publickey", data) diff --git a/routers/user/ssh.go b/routers/user/ssh.go index 0144f7a96d..1a5837dc88 100644 --- a/routers/user/ssh.go +++ b/routers/user/ssh.go @@ -17,28 +17,6 @@ import ( "github.com/gogits/gogs/modules/log" ) -func AddPublicKey(req *http.Request, data base.TmplData, r render.Render, session sessions.Session) { - data["Title"] = "Add Public Key" - - if req.Method == "GET" { - r.HTML(200, "user/publickey_add", data) - return - } - - k := &models.PublicKey{OwnerId: auth.SignedInId(session), - Name: req.FormValue("keyname"), - Content: req.FormValue("key_content"), - } - err := models.AddPublicKey(k) - if err != nil { - data["ErrorMsg"] = err - log.Error("ssh.AddPublicKey: %v", err) - r.HTML(200, "base/error", data) - } else { - r.HTML(200, "user/publickey_added", data) - } -} - func DelPublicKey(req *http.Request, data base.TmplData, r render.Render, session sessions.Session) { data["Title"] = "Del Public Key" @@ -78,18 +56,3 @@ func DelPublicKey(req *http.Request, data base.TmplData, r render.Render, sessio } } } - -func ListPublicKey(req *http.Request, data base.TmplData, r render.Render, session sessions.Session) { - data["Title"] = "Public Keys" - - keys, err := models.ListPublicKey(auth.SignedInId(session)) - if err != nil { - data["ErrorMsg"] = err - log.Error("ssh.ListPublicKey: %v", err) - r.HTML(200, "base/error", data) - return - } - - data["Keys"] = keys - r.HTML(200, "user/publickey_list", data) -} diff --git a/templates/user/publickey.tmpl b/templates/user/publickey.tmpl index 0c8b527db9..7510616d86 100644 --- a/templates/user/publickey.tmpl +++ b/templates/user/publickey.tmpl @@ -12,10 +12,11 @@
  • Kill Myself
  • +

    SSH Keys

    {{if .AddSSHKeySuccess}} -

    New SSH Key is added !

    {{end}} +

    New SSH Key has been added !

    {{else if .HasError}}

    {{.ErrorMsg}}

    {{end}}
    • SSH Key's name
    • {{range .Keys}}
    • @@ -34,6 +35,7 @@
    + +
    @@ -48,6 +51,7 @@
    + -

    Need help? Check out our guide to generating SSH keys or troubleshoot common SSH Problems

    +

    Need help? Check out the guide to generating SSH keys or troubleshoot common SSH Problems

    diff --git a/templates/user/publickey_add.tmpl b/templates/user/publickey_add.tmpl index b6757d1f63..634b859ddd 100644 --- a/templates/user/publickey_add.tmpl +++ b/templates/user/publickey_add.tmpl @@ -5,14 +5,14 @@
    - +
    - +
    diff --git a/templates/user/setting.tmpl b/templates/user/setting.tmpl index b2b595ffe2..cc527a25ac 100644 --- a/templates/user/setting.tmpl +++ b/templates/user/setting.tmpl @@ -9,7 +9,7 @@
  • Notifications
  • SSH Keys
  • Security
  • -
  • Kill myself
  • +
  • Kill Myself
  • diff --git a/web.go b/web.go index 7c030af082..c7c704c168 100644 --- a/web.go +++ b/web.go @@ -65,14 +65,11 @@ func runWeb(*cli.Context) { m.Any("/user/sign_up", auth.SignOutRequire(), binding.BindIgnErr(auth.RegisterForm{}), user.SignUp) m.Any("/user/delete", auth.SignInRequire(true), user.Delete) - m.Any("/user/setting",auth.SignInRequire(true),user.Setting) - m.Any("/user/setting/ssh",auth.SignInRequire(true),user.SettingSSHKeys) + m.Any("/user/setting", auth.SignInRequire(true), user.Setting) + m.Any("/user/setting/ssh", auth.SignInRequire(true), binding.BindIgnErr(auth.AddSSHKeyForm{}), user.SettingSSHKeys) m.Get("/user/:username", auth.SignInRequire(false), user.Profile) - //m.Any("/user/publickey/add", auth.SignInRequire(true), user.AddPublicKey) - //m.Any("/user/publickey/list", auth.SignInRequire(true), user.ListPublicKey) - m.Any("/repo/create", auth.SignInRequire(true), binding.BindIgnErr(auth.CreateRepoForm{}), repo.Create) m.Any("/repo/delete", auth.SignInRequire(true), repo.Delete) m.Any("/repo/list", auth.SignInRequire(false), repo.List)