<commit_before>// 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 (
	"fmt"

	"github.com/gogits/gogs/modules/log"
)

type AccessMode int

const (
	ACCESS_MODE_NONE AccessMode = iota
	ACCESS_MODE_READ
	ACCESS_MODE_WRITE
	ACCESS_MODE_ADMIN
	ACCESS_MODE_OWNER
)

// Access represents the highest access level of a user to the repository. The only access type
// that is not in this table is the real owner of a repository. In case of an organization
// repository, the members of the owners team are in this table.
type Access struct {
	ID     int64 `xorm:"pk autoincr"`
	UserID int64 `xorm:"UNIQUE(s)"`
	RepoID int64 `xorm:"UNIQUE(s)"`
	Mode   AccessMode
}

func accessLevel(e Engine, u *User, repo *Repository) (AccessMode, error) {
	mode := ACCESS_MODE_NONE
	if !repo.IsPrivate {
		mode = ACCESS_MODE_READ
	}

	if u != nil {
		if u.Id == repo.OwnerID {
			return ACCESS_MODE_OWNER, nil
		}

		a := &Access{UserID: u.Id, RepoID: repo.ID}
		if has, err := e.Get(a); !has || err != nil {
			return mode, err
		}
		return a.Mode, nil
	}

	return mode, nil
}

// AccessLevel returns the Access a user has to a repository. Will return NoneAccess if the
// user does not have access. User can be nil!
func AccessLevel(u *User, repo *Repository) (AccessMode, error) {
	return accessLevel(x, u, repo)
}

func hasAccess(e Engine, u *User, repo *Repository, testMode AccessMode) (bool, error) {
	mode, err := accessLevel(e, u, repo)
	return testMode <= mode, err
}

// HasAccess returns true if someone has the request access level. User can be nil!
func HasAccess(u *User, repo *Repository, testMode AccessMode) (bool, error) {
	return hasAccess(x, u, repo, testMode)
}

// GetRepositoryAccesses finds all repositories with their access mode where a user has access but does not own.
func (u *User) GetRepositoryAccesses() (map[*Repository]AccessMode, error) {
	accesses := make([]*Access, 0, 10)
	if err := x.Find(&accesses, &Access{UserID: u.Id}); err != nil {
		return nil, err
	}

	repos := make(map[*Repository]AccessMode, len(accesses))
	for _, access := range accesses {
		repo, err := GetRepositoryByID(access.RepoID)
		if err != nil {
			if IsErrRepoNotExist(err) {
				log.Error(4, "GetRepositoryByID: %v", err)
				continue
			}
			return nil, err
		}
		if err = repo.GetOwner(); err != nil {
			return nil, err
		} else if repo.OwnerID == u.Id {
			continue
		}
		repos[repo] = access.Mode
	}
	return repos, nil
}

// GetAccessibleRepositories finds all repositories where a user has access but does not own.
func (u *User) GetAccessibleRepositories() ([]*Repository, error) {
	accesses := make([]*Access, 0, 10)
	if err := x.Find(&accesses, &Access{UserID: u.Id}); err != nil {
		return nil, err
	}

	repoIDs := make([]int64, 0, len(accesses))
	for _, access := range accesses {
		repoIDs = append(repoIDs, access.RepoID)<commit_msg>fix #1953<commit_after>// 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 (
	"fmt"

	"github.com/gogits/gogs/modules/log"
)

type AccessMode int

const (
	ACCESS_MODE_NONE AccessMode = iota
	ACCESS_MODE_READ
	ACCESS_MODE_WRITE
	ACCESS_MODE_ADMIN
	ACCESS_MODE_OWNER
)

// Access represents the highest access level of a user to the repository. The only access type
// that is not in this table is the real owner of a repository. In case of an organization
// repository, the members of the owners team are in this table.
type Access struct {
	ID     int64 `xorm:"pk autoincr"`
	UserID int64 `xorm:"UNIQUE(s)"`
	RepoID int64 `xorm:"UNIQUE(s)"`
	Mode   AccessMode
}

func accessLevel(e Engine, u *User, repo *Repository) (AccessMode, error) {
	mode := ACCESS_MODE_NONE
	if !repo.IsPrivate {
		mode = ACCESS_MODE_READ
	}

	if u != nil {
		if u.Id == repo.OwnerID {
			return ACCESS_MODE_OWNER, nil
		}

		a := &Access{UserID: u.Id, RepoID: repo.ID}
		if has, err := e.Get(a); !has || err != nil {
			return mode, err
		}
		return a.Mode, nil
	}

	return mode, nil
}

// AccessLevel returns the Access a user has to a repository. Will return NoneAccess if the
// user does not have access. User can be nil!
func AccessLevel(u *User, repo *Repository) (AccessMode, error) {
	return accessLevel(x, u, repo)
}

func hasAccess(e Engine, u *User, repo *Repository, testMode AccessMode) (bool, error) {
	mode, err := accessLevel(e, u, repo)
	return testMode <= mode, err
}

// HasAccess returns true if someone has the request access level. User can be nil!
func HasAccess(u *User, repo *Repository, testMode AccessMode) (bool, error) {
	return hasAccess(x, u, repo, testMode)
}

// GetRepositoryAccesses finds all repositories with their access mode where a user has access but does not own.
func (u *User) GetRepositoryAccesses() (map[*Repository]AccessMode, error) {
	accesses := make([]*Access, 0, 10)
	if err := x.Find(&accesses, &Access{UserID: u.Id}); err != nil {
		return nil, err
	}

	repos := make(map[*Repository]AccessMode, len(accesses))
	for _, access := range accesses {
		repo, err := GetRepositoryByID(access.RepoID)
		if err != nil {
			if IsErrRepoNotExist(err) {
				log.Error(4, "GetRepositoryByID: %v", err)
				continue
			}
			return nil, err
		}
		if err = repo.GetOwner(); err != nil {
			return nil, err
		} else if repo.OwnerID == u.Id {
			continue
		}
		repos[repo] = access.Mode
	}
	return repos, nil
}

// GetAccessibleRepositories finds all repositories where a user has access but does not own.
func (u *User) GetAccessibleRepositories() ([]*Repository, error) {
	accesses := make([]*Access, 0, 10)
	if err := x.Find(&accesses, &Access{UserID: u.Id}); err != nil {
		return nil, err
	}

	if len(accesses) == 0 {
		return []*Repository{}, nil
	}

	repoIDs := make([]int64, 0, len(accesses))
	for _, access := range accesses {
		repoIDs = append(repoIDs, access.RepoID)
{'fraction_non_alphanumeric': 0.11626355296080067, 'fraction_numerical': 0.007506255212677231, 'mean_word_length': 3.858995137763371, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1727160', 'n_tokens_mistral': 2137, 'n_tokens_neox': 1997, 'n_words': 714}