2017-02-04 18:53:46 +03:00
// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
2021-11-09 22:57:58 +03:00
package unit
2017-02-04 18:53:46 +03:00
2018-11-10 22:45:32 +03:00
import (
2019-04-22 23:40:51 +03:00
"fmt"
2018-11-10 22:45:32 +03:00
"strings"
2019-04-22 23:40:51 +03:00
2022-01-05 06:37:00 +03:00
"code.gitea.io/gitea/models/perm"
2019-04-22 23:40:51 +03:00
"code.gitea.io/gitea/modules/log"
2020-01-17 10:34:37 +03:00
"code.gitea.io/gitea/modules/setting"
2018-11-10 22:45:32 +03:00
)
2021-11-09 22:57:58 +03:00
// Type is Unit's Type
type Type int
2017-02-04 18:53:46 +03:00
// Enumerate all the unit types
const (
2022-01-05 06:37:00 +03:00
TypeInvalid Type = iota // 0 invalid
TypeCode // 1 code
TypeIssues // 2 issues
TypePullRequests // 3 PRs
TypeReleases // 4 Releases
TypeWiki // 5 Wiki
TypeExternalWiki // 6 ExternalWiki
TypeExternalTracker // 7 ExternalTracker
TypeProjects // 8 Kanban board
2017-02-04 18:53:46 +03:00
)
2019-04-25 12:00:34 +03:00
// Value returns integer value for unit type
2021-11-09 22:57:58 +03:00
func ( u Type ) Value ( ) int {
2019-04-25 12:00:34 +03:00
return int ( u )
}
2021-11-09 22:57:58 +03:00
func ( u Type ) String ( ) string {
2019-04-22 23:40:51 +03:00
switch u {
2021-11-09 22:57:58 +03:00
case TypeCode :
return "TypeCode"
case TypeIssues :
return "TypeIssues"
case TypePullRequests :
return "TypePullRequests"
case TypeReleases :
return "TypeReleases"
case TypeWiki :
return "TypeWiki"
case TypeExternalWiki :
return "TypeExternalWiki"
case TypeExternalTracker :
return "TypeExternalTracker"
case TypeProjects :
return "TypeProjects"
2019-04-22 23:40:51 +03:00
}
2021-11-09 22:57:58 +03:00
return fmt . Sprintf ( "Unknown Type %d" , u )
2019-04-22 23:40:51 +03:00
}
2021-11-09 22:57:58 +03:00
// ColorFormat provides a ColorFormatted version of this Type
func ( u Type ) ColorFormat ( s fmt . State ) {
2019-04-22 23:40:51 +03:00
log . ColorFprintf ( s , "%d:%s" ,
log . NewColoredIDValue ( u ) ,
u )
}
2017-05-18 17:54:24 +03:00
var (
2019-05-30 18:09:05 +03:00
// AllRepoUnitTypes contains all the unit types
2021-11-09 22:57:58 +03:00
AllRepoUnitTypes = [ ] Type {
TypeCode ,
TypeIssues ,
TypePullRequests ,
TypeReleases ,
TypeWiki ,
TypeExternalWiki ,
TypeExternalTracker ,
TypeProjects ,
2017-05-18 17:54:24 +03:00
}
2019-05-30 18:09:05 +03:00
// DefaultRepoUnits contains the default unit types
2021-11-09 22:57:58 +03:00
DefaultRepoUnits = [ ] Type {
TypeCode ,
TypeIssues ,
TypePullRequests ,
TypeReleases ,
TypeWiki ,
TypeProjects ,
2017-05-18 17:54:24 +03:00
}
2020-01-17 10:34:37 +03:00
// NotAllowedDefaultRepoUnits contains units that can't be default
2021-11-09 22:57:58 +03:00
NotAllowedDefaultRepoUnits = [ ] Type {
TypeExternalWiki ,
TypeExternalTracker ,
2020-01-17 10:34:37 +03:00
}
2017-07-17 05:04:43 +03:00
// MustRepoUnits contains the units could not be disabled currently
2021-11-09 22:57:58 +03:00
MustRepoUnits = [ ] Type {
TypeCode ,
TypeReleases ,
2017-05-18 17:54:24 +03:00
}
2020-01-17 10:34:37 +03:00
// DisabledRepoUnits contains the units that have been globally disabled
2021-11-09 22:57:58 +03:00
DisabledRepoUnits = [ ] Type { }
2017-05-18 17:54:24 +03:00
)
2021-11-09 22:57:58 +03:00
// LoadUnitConfig load units from settings
func LoadUnitConfig ( ) {
2020-01-17 10:34:37 +03:00
setDefaultRepoUnits := FindUnitTypes ( setting . Repository . DefaultRepoUnits ... )
// Default repo units set if setting is not empty
if len ( setDefaultRepoUnits ) > 0 {
// MustRepoUnits required as default
2021-11-09 22:57:58 +03:00
DefaultRepoUnits = make ( [ ] Type , len ( MustRepoUnits ) )
2020-01-17 10:34:37 +03:00
copy ( DefaultRepoUnits , MustRepoUnits )
for _ , defaultU := range setDefaultRepoUnits {
if ! defaultU . CanBeDefault ( ) {
log . Warn ( "Not allowed as default unit: %s" , defaultU . String ( ) )
continue
}
// MustRepoUnits already added
if defaultU . CanDisable ( ) {
DefaultRepoUnits = append ( DefaultRepoUnits , defaultU )
}
}
}
DisabledRepoUnits = FindUnitTypes ( setting . Repository . DisabledRepoUnits ... )
// Check that must units are not disabled
for i , disabledU := range DisabledRepoUnits {
if ! disabledU . CanDisable ( ) {
log . Warn ( "Not allowed to global disable unit %s" , disabledU . String ( ) )
DisabledRepoUnits = append ( DisabledRepoUnits [ : i ] , DisabledRepoUnits [ i + 1 : ] ... )
}
}
// Remove disabled units from default units
for _ , disabledU := range DisabledRepoUnits {
for i , defaultU := range DefaultRepoUnits {
if defaultU == disabledU {
DefaultRepoUnits = append ( DefaultRepoUnits [ : i ] , DefaultRepoUnits [ i + 1 : ] ... )
}
}
}
}
// UnitGlobalDisabled checks if unit type is global disabled
2021-11-09 22:57:58 +03:00
func ( u Type ) UnitGlobalDisabled ( ) bool {
2020-01-17 10:34:37 +03:00
for _ , ud := range DisabledRepoUnits {
if u == ud {
return true
}
}
return false
}
// CanDisable checks if this unit type can be disabled.
2021-11-09 22:57:58 +03:00
func ( u * Type ) CanDisable ( ) bool {
2020-01-17 10:34:37 +03:00
for _ , mu := range MustRepoUnits {
if * u == mu {
return false
}
}
return true
}
// CanBeDefault checks if the unit type can be a default repo unit
2021-11-09 22:57:58 +03:00
func ( u * Type ) CanBeDefault ( ) bool {
2020-01-17 10:34:37 +03:00
for _ , nadU := range NotAllowedDefaultRepoUnits {
if * u == nadU {
return false
}
}
return true
}
2017-07-17 05:04:43 +03:00
// Unit is a section of one repository
2017-02-04 18:53:46 +03:00
type Unit struct {
2022-01-05 06:37:00 +03:00
Type Type
NameKey string
URI string
DescKey string
Idx int
MaxAccessMode perm . AccessMode // The max access mode of the unit. i.e. Read means this unit can only be read.
2017-02-04 18:53:46 +03:00
}
2017-05-18 17:54:24 +03:00
// CanDisable returns if this unit could be disabled.
func ( u * Unit ) CanDisable ( ) bool {
2020-01-17 10:34:37 +03:00
return u . Type . CanDisable ( )
2017-05-18 17:54:24 +03:00
}
2017-10-01 16:50:56 +03:00
// IsLessThan compares order of two units
func ( u Unit ) IsLessThan ( unit Unit ) bool {
2021-11-09 22:57:58 +03:00
if ( u . Type == TypeExternalTracker || u . Type == TypeExternalWiki ) && unit . Type != TypeExternalTracker && unit . Type != TypeExternalWiki {
2017-10-01 16:50:56 +03:00
return false
}
return u . Idx < unit . Idx
}
2022-01-08 18:19:36 +03:00
// MaxPerm returns the max perms of this unit
func ( u Unit ) MaxPerm ( ) perm . AccessMode {
if u . Type == TypeExternalTracker || u . Type == TypeExternalWiki {
return perm . AccessModeRead
}
return perm . AccessModeAdmin
}
2017-02-04 18:53:46 +03:00
// Enumerate all the units
var (
UnitCode = Unit {
2021-11-09 22:57:58 +03:00
TypeCode ,
2017-02-04 18:53:46 +03:00
"repo.code" ,
"/" ,
2017-05-18 17:54:24 +03:00
"repo.code.desc" ,
2017-02-04 18:53:46 +03:00
0 ,
2022-01-05 06:37:00 +03:00
perm . AccessModeOwner ,
2017-02-04 18:53:46 +03:00
}
UnitIssues = Unit {
2021-11-09 22:57:58 +03:00
TypeIssues ,
2017-02-04 18:53:46 +03:00
"repo.issues" ,
"/issues" ,
2017-05-18 17:54:24 +03:00
"repo.issues.desc" ,
2017-02-04 18:53:46 +03:00
1 ,
2022-01-05 06:37:00 +03:00
perm . AccessModeOwner ,
2017-02-04 18:53:46 +03:00
}
UnitExternalTracker = Unit {
2021-11-09 22:57:58 +03:00
TypeExternalTracker ,
2017-05-18 17:54:24 +03:00
"repo.ext_issues" ,
2017-02-04 18:53:46 +03:00
"/issues" ,
2017-05-18 17:54:24 +03:00
"repo.ext_issues.desc" ,
2017-02-04 18:53:46 +03:00
1 ,
2022-01-05 06:37:00 +03:00
perm . AccessModeRead ,
2017-02-04 18:53:46 +03:00
}
UnitPullRequests = Unit {
2021-11-09 22:57:58 +03:00
TypePullRequests ,
2017-02-04 18:53:46 +03:00
"repo.pulls" ,
"/pulls" ,
2017-05-18 17:54:24 +03:00
"repo.pulls.desc" ,
2017-02-04 18:53:46 +03:00
2 ,
2022-01-05 06:37:00 +03:00
perm . AccessModeOwner ,
2017-02-04 18:53:46 +03:00
}
UnitReleases = Unit {
2021-11-09 22:57:58 +03:00
TypeReleases ,
2017-02-04 18:53:46 +03:00
"repo.releases" ,
"/releases" ,
2017-05-18 17:54:24 +03:00
"repo.releases.desc" ,
2017-07-17 05:04:43 +03:00
3 ,
2022-01-05 06:37:00 +03:00
perm . AccessModeOwner ,
2017-02-04 18:53:46 +03:00
}
UnitWiki = Unit {
2021-11-09 22:57:58 +03:00
TypeWiki ,
2017-02-04 18:53:46 +03:00
"repo.wiki" ,
"/wiki" ,
2017-05-18 17:54:24 +03:00
"repo.wiki.desc" ,
2017-07-17 05:04:43 +03:00
4 ,
2022-01-05 06:37:00 +03:00
perm . AccessModeOwner ,
2017-02-04 18:53:46 +03:00
}
UnitExternalWiki = Unit {
2021-11-09 22:57:58 +03:00
TypeExternalWiki ,
2017-05-18 17:54:24 +03:00
"repo.ext_wiki" ,
2017-02-04 18:53:46 +03:00
"/wiki" ,
2017-05-18 17:54:24 +03:00
"repo.ext_wiki.desc" ,
2017-07-17 05:04:43 +03:00
4 ,
2022-01-05 06:37:00 +03:00
perm . AccessModeRead ,
2017-02-04 18:53:46 +03:00
}
2020-08-17 06:07:38 +03:00
UnitProjects = Unit {
2021-11-09 22:57:58 +03:00
TypeProjects ,
2020-08-17 06:07:38 +03:00
"repo.projects" ,
"/projects" ,
"repo.projects.desc" ,
5 ,
2022-01-05 06:37:00 +03:00
perm . AccessModeOwner ,
2020-08-17 06:07:38 +03:00
}
2017-02-04 18:53:46 +03:00
// Units contains all the units
2021-11-09 22:57:58 +03:00
Units = map [ Type ] Unit {
TypeCode : UnitCode ,
TypeIssues : UnitIssues ,
TypeExternalTracker : UnitExternalTracker ,
TypePullRequests : UnitPullRequests ,
TypeReleases : UnitReleases ,
TypeWiki : UnitWiki ,
TypeExternalWiki : UnitExternalWiki ,
TypeProjects : UnitProjects ,
2017-02-04 18:53:46 +03:00
}
)
2018-11-10 22:45:32 +03:00
2022-01-05 06:37:00 +03:00
// FindUnitTypes give the unit key names and return unit
2021-11-09 22:57:58 +03:00
func FindUnitTypes ( nameKeys ... string ) ( res [ ] Type ) {
2018-11-10 22:45:32 +03:00
for _ , key := range nameKeys {
2022-01-05 06:37:00 +03:00
var found bool
2018-11-10 22:45:32 +03:00
for t , u := range Units {
if strings . EqualFold ( key , u . NameKey ) {
res = append ( res , t )
2022-01-05 06:37:00 +03:00
found = true
2018-11-10 22:45:32 +03:00
break
}
}
2022-01-05 06:37:00 +03:00
if ! found {
res = append ( res , TypeInvalid )
}
2018-11-10 22:45:32 +03:00
}
return
}
2022-01-05 06:37:00 +03:00
// TypeFromKey give the unit key name and return unit
func TypeFromKey ( nameKey string ) Type {
for t , u := range Units {
if strings . EqualFold ( nameKey , u . NameKey ) {
return t
}
}
return TypeInvalid
}
// AllUnitKeyNames returns all unit key names
func AllUnitKeyNames ( ) [ ] string {
res := make ( [ ] string , 0 , len ( Units ) )
for _ , u := range Units {
res = append ( res , u . NameKey )
}
return res
}
// MinUnitAccessMode returns the minial permission of the permission map
func MinUnitAccessMode ( unitsMap map [ Type ] perm . AccessMode ) perm . AccessMode {
res := perm . AccessModeNone
for _ , mode := range unitsMap {
// get the minial permission great than AccessModeNone except all are AccessModeNone
if mode > perm . AccessModeNone && ( res == perm . AccessModeNone || mode < res ) {
res = mode
}
}
return res
}