diff --git a/server/database/perm.go b/server/database/perm.go
index b1c5c9e5..375f50c6 100644
--- a/server/database/perm.go
+++ b/server/database/perm.go
@@ -16,6 +16,9 @@ type PermManager interface {
// Revoke will revoke all user permissions to the specified repository.
Revoke(u *model.User, r *model.Repo) error
+ // Find returns the user's permission to access the specified repository.
+ Find(u *model.User, r *model.Repo) *model.Perm
+
// Read returns true if the specified user has read
// access to the repository.
Read(u *model.User, r *model.Repo) (bool, error)
@@ -53,17 +56,6 @@ const deletePermStmt = `
DELETE FROM perms WHERE user_id=? AND repo_id=?
`
-type perm struct {
- ID int64 `meddler:"perm_id,pk"`
- UserID int64 `meddler:"user_id"`
- RepoID int64 `meddler:"repo_id"`
- Read bool `meddler:"perm_read"`
- Write bool `meddler:"perm_write"`
- Admin bool `meddler:"perm_admin"`
- Created int64 `meddler:"perm_created"`
- Updated int64 `meddler:"perm_updated"`
-}
-
// NewManager initiales a new PermManager intended to
// manage user permission and access control.
func NewPermManager(db *sql.DB) PermManager {
@@ -103,6 +95,44 @@ func (db *permManager) Revoke(u *model.User, r *model.Repo) error {
return err
}
+func (db *permManager) Find(u *model.User, r *model.Repo) *model.Perm {
+ // if the user is a gues they should only be granted
+ // read access to public repositories.
+ switch {
+ case u == nil && r.Private:
+ return &model.Perm{
+ Read: false,
+ Write: false,
+ Admin: false}
+ case u == nil && !r.Private:
+ return &model.Perm{
+ Read: true,
+ Write: false,
+ Admin: false}
+ }
+
+ // if the user is authenticated we'll retireive the
+ // permission details from the database.
+ perm, err := db.find(u, r)
+ if err != nil {
+ return perm
+ }
+
+ switch {
+ // if the user is a system admin grant super access.
+ case u.Admin == true:
+ perm.Read = true
+ perm.Write = true
+ perm.Admin = true
+
+ // if the repo is public, grant read access only.
+ case r.Private == false:
+ perm.Read = true
+ }
+
+ return perm
+}
+
func (db *permManager) Read(u *model.User, r *model.Repo) (bool, error) {
switch {
// if the repo is public, grant access.
@@ -165,8 +195,8 @@ func (db *permManager) Member(u *model.User, r *model.Repo) (bool, error) {
return perm.Read, err
}
-func (db *permManager) find(u *model.User, r *model.Repo) (*perm, error) {
- var dst = perm{}
+func (db *permManager) find(u *model.User, r *model.Repo) (*model.Perm, error) {
+ var dst = model.Perm{}
var err = meddler.QueryRow(db, &dst, findPermQuery, u.ID, r.ID)
return &dst, err
}
diff --git a/server/handler/repo.go b/server/handler/repo.go
index c53ad686..af9aacd6 100644
--- a/server/handler/repo.go
+++ b/server/handler/repo.go
@@ -43,14 +43,18 @@ func (h *RepoHandler) GetRepo(w http.ResponseWriter, r *http.Request) error {
}
// user must have read access to the repository.
- if ok, _ := h.perms.Read(user, repo); !ok {
+ role := h.perms.Find(user, repo)
+ if !role.Read {
return notFound{err}
}
// if the user is not requesting admin data we can
// return exactly what we have.
if len(admin) == 0 {
- return json.NewEncoder(w).Encode(repo)
+ return json.NewEncoder(w).Encode(struct {
+ *model.Repo
+ Role *model.Perm `json:"role"`
+ }{repo, role})
}
// ammend the response to include data that otherwise
@@ -62,9 +66,10 @@ func (h *RepoHandler) GetRepo(w http.ResponseWriter, r *http.Request) error {
return json.NewEncoder(w).Encode(struct {
*model.Repo
- PublicKey string `json:"public_key"`
- Params string `json:"params"`
- }{repo, repo.PublicKey, repo.Params})
+ Role *model.Perm `json:"role"`
+ PublicKey string `json:"public_key"`
+ Params string `json:"params"`
+ }{repo, role, repo.PublicKey, repo.Params})
}
// PostRepo activates the named repository.
diff --git a/shared/model/perm.go b/shared/model/perm.go
new file mode 100644
index 00000000..e3b8c1fa
--- /dev/null
+++ b/shared/model/perm.go
@@ -0,0 +1,12 @@
+package model
+
+type Perm struct {
+ ID int64 `meddler:"perm_id,pk" json:"-"`
+ UserID int64 `meddler:"user_id" json:"-"`
+ RepoID int64 `meddler:"repo_id" json:"-"`
+ Read bool `meddler:"perm_read" json:"read"`
+ Write bool `meddler:"perm_write" json:"write"`
+ Admin bool `meddler:"perm_admin" json:"admin"`
+ Created int64 `meddler:"perm_created" json:"-"`
+ Updated int64 `meddler:"perm_updated" json:"-"`
+}