summaryrefslogtreecommitdiffstats
path: root/modules/middleware/repo.go
blob: d1b68b052cd3d9d2c2d8f45b5cba47c4b1d97633 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// 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 middleware

import (
	"errors"
	"fmt"
	"strings"

	"github.com/codegangsta/martini"

	"github.com/gogits/git"

	"github.com/gogits/gogs/models"
	"github.com/gogits/gogs/modules/base"
)

func RepoAssignment(redirect bool) martini.Handler {
	return func(ctx *Context, params martini.Params) {
		// assign false first
		ctx.Data["IsRepositoryValid"] = false

		var (
			user *models.User
			err  error
		)

		userName := params["username"]
		repoName := params["reponame"]
		branchName := params["branchname"]

		// get repository owner
		ctx.Repo.IsOwner = ctx.IsSigned && ctx.User.LowerName == strings.ToLower(userName)

		if !ctx.Repo.IsOwner {
			user, err = models.GetUserByName(params["username"])
			if err != nil {
				if redirect {
					ctx.Redirect("/")
					return
				}
				ctx.Handle(200, "RepoAssignment", err)
				return
			}
		} else {
			user = ctx.User
		}

		if user == nil {
			if redirect {
				ctx.Redirect("/")
				return
			}
			ctx.Handle(200, "RepoAssignment", errors.New("invliad user account for single repository"))
			return
		}

		// get repository
		repo, err := models.GetRepositoryByName(user.Id, repoName)
		if err != nil {
			if err == models.ErrRepoNotExist {
				ctx.Handle(404, "RepoAssignment", err)
			} else if redirect {
				ctx.Redirect("/")
				return
			}
			ctx.Handle(404, "RepoAssignment", err)
			return
		}
		ctx.Repo.Repository = repo

		gitRepo, err := git.OpenRepository(models.RepoPath(userName, repoName))
		if err != nil {
			ctx.Handle(404, "RepoAssignment Invalid repo", err)
			return
		}
		ctx.Repo.GitRepo = gitRepo

	detect:
		if len(branchName) > 0 {
			// TODO check tag
			if models.IsBranchExist(user.Name, repoName, branchName) {
				ctx.Repo.IsBranch = true
				ctx.Repo.BranchName = branchName

				ctx.Repo.Commit, err = gitRepo.GetCommitOfBranch(branchName)
				if err != nil {
					ctx.Handle(404, "RepoAssignment invalid branch", nil)
					return
				}

				ctx.Repo.CommitId = ctx.Repo.Commit.Oid.String()

			} else if len(branchName) == 40 {
				ctx.Repo.IsCommit = true
				ctx.Repo.CommitId = branchName
				ctx.Repo.BranchName = branchName

				ctx.Repo.Commit, err = gitRepo.GetCommit(branchName)
				if err != nil {
					ctx.Handle(404, "RepoAssignment invalid commit", nil)
					return
				}
			} else {
				ctx.Handle(404, "RepoAssignment invalid repo", nil)
				return
			}

		} else {
			branchName = "master"
			goto detect
		}

		if ctx.IsSigned {
			ctx.Repo.IsWatching = models.IsWatching(ctx.User.Id, repo.Id)
		}

		ctx.Repo.Owner = user
		ctx.Repo.CloneLink.SSH = fmt.Sprintf("%s@%s:%s/%s.git", base.RunUser, base.Domain, user.LowerName, repo.LowerName)
		ctx.Repo.CloneLink.HTTPS = fmt.Sprintf("%s%s/%s.git", base.AppUrl, user.LowerName, repo.LowerName)
		ctx.Repo.RepoLink = "/" + user.Name + "/" + repo.Name

		ctx.Data["BranchName"] = ctx.Repo.BranchName
		ctx.Data["CommitId"] = ctx.Repo.CommitId
		ctx.Data["Repository"] = repo
		ctx.Data["Owner"] = user
		ctx.Data["Title"] = user.Name + "/" + repo.Name
		ctx.Data["CloneLink"] = ctx.Repo.CloneLink
		ctx.Data["RepoLink"] = ctx.Repo.RepoLink
		ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner
		ctx.Data["IsRepositoryWatching"] = ctx.Repo.IsWatching
	}
}