Support private repo
This commit is contained in:
		
							parent
							
								
									d6dac160df
								
							
						
					
					
						commit
						33aa4f7438
					
				
					 13 changed files with 87 additions and 31 deletions
				
			
		|  | @ -5,7 +5,7 @@ Gogs(Go Git Service) is a Self Hosted Git Service in the Go Programming Language | |||
| 
 | ||||
|  | ||||
| 
 | ||||
| ##### Current version: 0.2.6 Alpha | ||||
| ##### Current version: 0.2.7 Alpha | ||||
| 
 | ||||
| #### Due to testing purpose, data of [try.gogits.org](http://try.gogits.org) has been reset in April 6, 2014 and will reset multiple times after. Please do NOT put your important data on the site. | ||||
| 
 | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ Gogs(Go Git Service) 是一个由 Go 语言编写的自助 Git 托管服务。 | |||
| 
 | ||||
|  | ||||
| 
 | ||||
| ##### 当前版本:0.2.6 Alpha | ||||
| ##### 当前版本:0.2.7 Alpha | ||||
| 
 | ||||
| ## 开发目的 | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								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.2.6.0411 Alpha" | ||||
| const APP_VER = "0.2.7.0411 Alpha" | ||||
| 
 | ||||
| func init() { | ||||
| 	base.AppVer = APP_VER | ||||
|  |  | |||
|  | @ -53,10 +53,17 @@ func UpdateAccessWithSession(sess *xorm.Session, access *Access) error { | |||
| 
 | ||||
| // HasAccess returns true if someone can read or write to given repository.
 | ||||
| func HasAccess(userName, repoName string, mode int) (bool, error) { | ||||
| 	return orm.Get(&Access{ | ||||
| 		Id:       0, | ||||
| 	access := &Access{ | ||||
| 		UserName: strings.ToLower(userName), | ||||
| 		RepoName: strings.ToLower(repoName), | ||||
| 		Mode:     mode, | ||||
| 	}) | ||||
| 	} | ||||
| 	has, err := orm.Get(access) | ||||
| 	if err != nil { | ||||
| 		return false, err | ||||
| 	} else if !has { | ||||
| 		return false, nil | ||||
| 	} else if mode > access.Mode { | ||||
| 		return false, nil | ||||
| 	} | ||||
| 	return true, nil | ||||
| } | ||||
|  |  | |||
|  | @ -295,6 +295,9 @@ func DeleteUser(user *User) error { | |||
| 	} | ||||
| 
 | ||||
| 	// Delete oauth2.
 | ||||
| 	if _, err = orm.Delete(&Oauth2{Uid: user.Id}); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	// Delete all feeds.
 | ||||
| 	if _, err = orm.Delete(&Action{UserId: user.Id}); err != nil { | ||||
|  |  | |||
|  | @ -18,7 +18,7 @@ import ( | |||
| 
 | ||||
| type CreateRepoForm struct { | ||||
| 	RepoName    string `form:"repo" binding:"Required;AlphaDash"` | ||||
| 	Visibility  string `form:"visibility"` | ||||
| 	Private     string `form:"private"` | ||||
| 	Description string `form:"desc" binding:"MaxSize(100)"` | ||||
| 	Language    string `form:"language"` | ||||
| 	License     string `form:"license"` | ||||
|  |  | |||
|  | @ -49,6 +49,7 @@ type Context struct { | |||
| 		IsBranch   bool | ||||
| 		IsTag      bool | ||||
| 		IsCommit   bool | ||||
| 		HasAccess  bool | ||||
| 		Repository *models.Repository | ||||
| 		Owner      *models.User | ||||
| 		Commit     *git.Commit | ||||
|  | @ -102,12 +103,10 @@ func (ctx *Context) RenderWithErr(msg, tpl string, form auth.Form) { | |||
| // Handle handles and logs error by given status.
 | ||||
| func (ctx *Context) Handle(status int, title string, err error) { | ||||
| 	log.Error("%s: %v", title, err) | ||||
| 	if martini.Dev == martini.Prod { | ||||
| 		ctx.HTML(200, "status/500") | ||||
| 		return | ||||
| 	if martini.Dev != martini.Prod { | ||||
| 		ctx.Data["ErrorMsg"] = err | ||||
| 	} | ||||
| 
 | ||||
| 	ctx.Data["ErrorMsg"] = err | ||||
| 	ctx.HTML(status, fmt.Sprintf("status/%d", status)) | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -67,12 +67,14 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler { | |||
| 			ctx.Handle(200, "RepoAssignment", errors.New("invliad user account for single repository")) | ||||
| 			return | ||||
| 		} | ||||
| 		ctx.Repo.Owner = user | ||||
| 
 | ||||
| 		// get repository
 | ||||
| 		repo, err := models.GetRepositoryByName(user.Id, repoName) | ||||
| 		if err != nil { | ||||
| 			if err == models.ErrRepoNotExist { | ||||
| 				ctx.Handle(404, "RepoAssignment", err) | ||||
| 				return | ||||
| 			} else if redirect { | ||||
| 				ctx.Redirect("/") | ||||
| 				return | ||||
|  | @ -80,6 +82,26 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler { | |||
| 			ctx.Handle(500, "RepoAssignment", err) | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		// Check access.
 | ||||
| 		if repo.IsPrivate { | ||||
| 			if ctx.User == nil { | ||||
| 				ctx.Handle(404, "RepoAssignment(HasAccess)", nil) | ||||
| 				return | ||||
| 			} | ||||
| 
 | ||||
| 			hasAccess, err := models.HasAccess(ctx.User.Name, ctx.Repo.Owner.Name+"/"+repo.Name, models.AU_READABLE) | ||||
| 			if err != nil { | ||||
| 				ctx.Handle(500, "RepoAssignment(HasAccess)", err) | ||||
| 				return | ||||
| 			} else if !hasAccess { | ||||
| 				ctx.Handle(404, "RepoAssignment(HasAccess)", nil) | ||||
| 				return | ||||
| 			} | ||||
| 		} | ||||
| 		ctx.Repo.HasAccess = true | ||||
| 		ctx.Data["HasAccess"] = true | ||||
| 
 | ||||
| 		repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues | ||||
| 		ctx.Repo.Repository = repo | ||||
| 
 | ||||
|  | @ -91,8 +113,6 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler { | |||
| 			return | ||||
| 		} | ||||
| 		ctx.Repo.GitRepo = gitRepo | ||||
| 
 | ||||
| 		ctx.Repo.Owner = user | ||||
| 		ctx.Repo.RepoLink = "/" + user.Name + "/" + repo.Name | ||||
| 
 | ||||
| 		ctx.Data["Title"] = user.Name + "/" + repo.Name | ||||
|  | @ -170,3 +190,27 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler { | |||
| 		ctx.Data["IsRepositoryWatching"] = ctx.Repo.IsWatching | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func WriteAccess() martini.Handler { | ||||
| 	return func(ctx *Context) { | ||||
| 		if ctx.Repo.Repository.IsPrivate { | ||||
| 			ctx.Repo.HasAccess = false | ||||
| 			ctx.Data["HasAccess"] = false | ||||
| 			if ctx.User == nil { | ||||
| 				ctx.Handle(404, "WriteAccess", nil) | ||||
| 				return | ||||
| 			} | ||||
| 
 | ||||
| 			hasAccess, err := models.HasAccess(ctx.User.Name, ctx.Repo.Owner.Name+"/"+ctx.Repo.Repository.Name, models.AU_WRITABLE) | ||||
| 			if err != nil { | ||||
| 				ctx.Handle(500, "WriteAccess(HasAccess)", err) | ||||
| 				return | ||||
| 			} else if !hasAccess { | ||||
| 				ctx.Handle(404, "WriteAccess(HasAccess)", nil) | ||||
| 				return | ||||
| 			} | ||||
| 		} | ||||
| 		ctx.Repo.HasAccess = true | ||||
| 		ctx.Data["HasAccess"] = true | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -41,7 +41,7 @@ func CreatePost(ctx *middleware.Context, form auth.CreateRepoForm) { | |||
| 	} | ||||
| 
 | ||||
| 	_, err := models.CreateRepository(ctx.User, form.RepoName, form.Description, | ||||
| 		form.Language, form.License, form.Visibility == "private", form.InitReadme == "on") | ||||
| 		form.Language, form.License, form.Private == "on", form.InitReadme == "on") | ||||
| 	if err == nil { | ||||
| 		log.Trace("%s Repository created: %s/%s", ctx.Req.RequestURI, ctx.User.LowerName, form.RepoName) | ||||
| 		ctx.Redirect("/" + ctx.User.Name + "/" + form.RepoName) | ||||
|  | @ -72,7 +72,7 @@ func MirrorPost(ctx *middleware.Context, form auth.CreateRepoForm) { | |||
| 	} | ||||
| 
 | ||||
| 	_, err := models.CreateRepository(ctx.User, form.RepoName, form.Description, | ||||
| 		"", form.License, form.Visibility == "private", false) | ||||
| 		"", form.License, form.Private == "on", false) | ||||
| 	if err == nil { | ||||
| 		log.Trace("%s Repository created: %s/%s", ctx.Req.RequestURI, ctx.User.LowerName, form.RepoName) | ||||
| 		ctx.Redirect("/" + ctx.User.Name + "/" + form.RepoName) | ||||
|  |  | |||
							
								
								
									
										7
									
								
								serve.go
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								serve.go
									
									
									
									
									
								
							|  | @ -120,10 +120,7 @@ func runServ(k *cli.Context) { | |||
| 		qlog.Fatalf("Unavilable repository %v", args) | ||||
| 	} | ||||
| 	repoUserName := rr[0] | ||||
| 	repoName := rr[1] | ||||
| 	if strings.HasSuffix(repoName, ".git") { | ||||
| 		repoName = repoName[:len(repoName)-4] | ||||
| 	} | ||||
| 	repoName := strings.TrimSuffix(rr[1], ".git") | ||||
| 
 | ||||
| 	isWrite := In(verb, COMMANDS_WRITE) | ||||
| 	isRead := In(verb, COMMANDS_READONLY) | ||||
|  | @ -156,7 +153,7 @@ func runServ(k *cli.Context) { | |||
| 			break | ||||
| 		} | ||||
| 
 | ||||
| 		has, err := models.HasAccess(user.Name, repoPath, models.AU_READABLE) | ||||
| 		has, err := models.HasAccess(user.Name, path.Join(repoUserName, repoName), models.AU_READABLE) | ||||
| 		if err != nil { | ||||
| 			println("Inernel error") | ||||
| 			qlog.Fatal(err) | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
|             <a id="nav-logo" class="nav-item pull-left{{if .PageIsHome}} active{{end}}" href="/"><img src="/img/favicon.png" alt="Gogs Logo" id="logo"></a> | ||||
|             <a class="nav-item pull-left{{if .PageIsUserDashboard}} active{{end}}" href="/">Dashboard</a> | ||||
|             <a class="nav-item pull-left{{if .PageIsHelp}} active{{end}}" href="https://github.com/gogits/gogs/wiki">Help</a>{{if .IsSigned}} | ||||
|             <form class="nav-item pull-left{{if .PageIsNewRepo}} active{{end}}" id="nav-search-form"> | ||||
|             {{if .HasAccess}}<form class="nav-item pull-left{{if .PageIsNewRepo}} active{{end}}" id="nav-search-form"> | ||||
|                 <div class="input-group"> | ||||
|                     <div class="input-group-btn"> | ||||
|                         <button type="button" class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown">{{if .Repository}}This Repository{{else}}All Repositories{{end}} <span class="caret"></span></button> | ||||
|  | @ -16,7 +16,7 @@ | |||
|                     </div> | ||||
|                     <input type="search" class="form-control input-sm" name="q" placeholder="search code, commits and issues"/> | ||||
|                 </div> | ||||
|             </form> | ||||
|             </form>{{end}} | ||||
|             <a id="nav-out" class="nav-item navbar-right navbar-btn btn btn-danger" href="/user/logout/"><i class="fa fa-power-off fa-lg"></i></a> | ||||
|             <a id="nav-avatar" class="nav-item navbar-right{{if .PageIsUserProfile}} active{{end}}" href="{{.SignedUser.HomeLink}}" data-toggle="tooltip" data-placement="bottom" title="{{.SignedUserName}}"> | ||||
|                 <img src="{{.SignedUser.AvatarLink}}?s=28" alt="user-avatar" title="username"/> | ||||
|  |  | |||
|  | @ -22,10 +22,14 @@ | |||
|         </div> | ||||
| 
 | ||||
|         <div class="form-group"> | ||||
|             <label class="col-md-2 control-label">Visibility<strong class="text-danger">*</strong></label> | ||||
|             <label class="col-md-2 control-label">Visibility</label> | ||||
|             <div class="col-md-8"> | ||||
|                 <p class="form-control-static">Public</p> | ||||
|                 <input type="hidden" value="public" name="visibility"/> | ||||
|                 <div class="checkbox"> | ||||
|                     <label> | ||||
|                         <input type="checkbox" name="private" {{if .private}}checked{{end}}> | ||||
|                         <strong>This repository is private</strong> | ||||
|                     </label> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										12
									
								
								web.go
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								web.go
									
									
									
									
									
								
							|  | @ -156,22 +156,24 @@ func runWeb(*cli.Context) { | |||
| 		m.Get("/template/**", dev.TemplatePreview) | ||||
| 	} | ||||
| 
 | ||||
| 	writeable := middleware.WriteAccess() | ||||
| 
 | ||||
| 	m.Group("/:username/:reponame", func(r martini.Router) { | ||||
| 		r.Post("/settings", repo.SettingPost) | ||||
| 		r.Get("/settings", repo.Setting) | ||||
| 		r.Get("/settings", writeable, repo.Setting) | ||||
| 		r.Post("/settings", writeable, repo.SettingPost) | ||||
| 		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) | ||||
| 		r.Post("/comment/:action", repo.Comment) | ||||
| 		r.Post("/import", repo.Import) | ||||
| 		r.Post("/import", writeable, repo.Import) | ||||
| 	}, reqSignIn, middleware.RepoAssignment(true)) | ||||
| 
 | ||||
| 	m.Group("/:username/:reponame", func(r martini.Router) { | ||||
| 		r.Get("/issues", repo.Issues) | ||||
| 		r.Get("/issues/:index", repo.ViewIssue) | ||||
| 		r.Get("/releases", repo.Releases) | ||||
| 		r.Any("/releases/new", repo.ReleasesNew) // TODO:
 | ||||
| 		r.Any("/releases/new", writeable, repo.ReleasesNew) // TODO:
 | ||||
| 		r.Get("/pulls", repo.Pulls) | ||||
| 		r.Get("/branches", repo.Branches) | ||||
| 	}, ignSignIn, middleware.RepoAssignment(true)) | ||||
|  | @ -187,8 +189,8 @@ func runWeb(*cli.Context) { | |||
| 	}, ignSignIn, middleware.RepoAssignment(true, true)) | ||||
| 
 | ||||
| 	m.Group("/:username", func(r martini.Router) { | ||||
| 		r.Any("/:reponame/**", repo.Http) | ||||
| 		r.Get("/:reponame", middleware.RepoAssignment(true, true, true), repo.Single) | ||||
| 		r.Any("/:reponame/**", repo.Http) | ||||
| 	}, ignSignInAndCsrf) | ||||
| 
 | ||||
| 	// Not found handler.
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue