Reuse code in modules/util

This commit is contained in:
harryzcy 2022-10-30 16:26:04 -04:00
parent 37c59c9136
commit f13904ade8
No known key found for this signature in database
GPG key ID: CC2953E050C19686
3 changed files with 87 additions and 39 deletions

View file

@ -7,6 +7,8 @@ package auth
import (
"fmt"
"strings"
"code.gitea.io/gitea/modules/util"
)
// AccessTokenScope represents the scope for an access token.
@ -90,7 +92,7 @@ func (s AccessTokenScope) Parse() (AccessTokenScopeBitmap, error) {
continue
}
idx := sliceIndex(AllAccessTokenScopes, v)
idx := util.FindStringInSlice(v, AllAccessTokenScopes)
if idx < 0 {
return 0, fmt.Errorf("invalid access token scope: %s", v)
}
@ -99,32 +101,32 @@ func (s AccessTokenScope) Parse() (AccessTokenScopeBitmap, error) {
// take care of child scopes
switch v {
case AccessTokenScopeRepo:
bitmap |= 1 << uint(sliceIndex(AllAccessTokenScopes, AccessTokenScopeRepoStatus))
bitmap |= 1 << uint(sliceIndex(AllAccessTokenScopes, AccessTokenScopePublicRepo))
bitmap |= 1 << uint(util.FindStringInSlice(AccessTokenScopeRepoStatus, AllAccessTokenScopes))
bitmap |= 1 << uint(util.FindStringInSlice(AccessTokenScopePublicRepo, AllAccessTokenScopes))
// admin:repo_hook, write:repo_hook, read:repo_hook
bitmap |= 1 << uint(sliceIndex(AllAccessTokenScopes, AccessTokenScopeAdminRepoHook))
bitmap |= 1 << uint(sliceIndex(AllAccessTokenScopes, AccessTokenScopeWriteRepoHook))
bitmap |= 1 << uint(sliceIndex(AllAccessTokenScopes, AccessTokenScopeReadRepoHook))
bitmap |= 1 << uint(util.FindStringInSlice(AccessTokenScopeAdminRepoHook, AllAccessTokenScopes))
bitmap |= 1 << uint(util.FindStringInSlice(AccessTokenScopeWriteRepoHook, AllAccessTokenScopes))
bitmap |= 1 << uint(util.FindStringInSlice(AccessTokenScopeReadRepoHook, AllAccessTokenScopes))
case AccessTokenScopeAdminOrg:
bitmap |= 1 << uint(sliceIndex(AllAccessTokenScopes, AccessTokenScopeWriteOrg))
bitmap |= 1 << uint(sliceIndex(AllAccessTokenScopes, AccessTokenScopeReadOrg))
bitmap |= 1 << uint(util.FindStringInSlice(AccessTokenScopeWriteOrg, AllAccessTokenScopes))
bitmap |= 1 << uint(util.FindStringInSlice(AccessTokenScopeReadOrg, AllAccessTokenScopes))
case AccessTokenScopeAdminPublicKey:
bitmap |= 1 << uint(sliceIndex(AllAccessTokenScopes, AccessTokenScopeWritePublicKey))
bitmap |= 1 << uint(sliceIndex(AllAccessTokenScopes, AccessTokenScopeReadPublicKey))
bitmap |= 1 << uint(util.FindStringInSlice(AccessTokenScopeWritePublicKey, AllAccessTokenScopes))
bitmap |= 1 << uint(util.FindStringInSlice(AccessTokenScopeReadPublicKey, AllAccessTokenScopes))
case AccessTokenScopeAdminRepoHook:
bitmap |= 1 << uint(sliceIndex(AllAccessTokenScopes, AccessTokenScopeWriteRepoHook))
bitmap |= 1 << uint(sliceIndex(AllAccessTokenScopes, AccessTokenScopeReadRepoHook))
bitmap |= 1 << uint(util.FindStringInSlice(AccessTokenScopeWriteRepoHook, AllAccessTokenScopes))
bitmap |= 1 << uint(util.FindStringInSlice(AccessTokenScopeReadRepoHook, AllAccessTokenScopes))
case AccessTokenScopeUser:
bitmap |= 1 << uint(sliceIndex(AllAccessTokenScopes, AccessTokenScopeReadUser))
bitmap |= 1 << uint(sliceIndex(AllAccessTokenScopes, AccessTokenScopeUserEmail))
bitmap |= 1 << uint(sliceIndex(AllAccessTokenScopes, AccessTokenScopeUserFollow))
bitmap |= 1 << uint(util.FindStringInSlice(AccessTokenScopeReadUser, AllAccessTokenScopes))
bitmap |= 1 << uint(util.FindStringInSlice(AccessTokenScopeUserEmail, AllAccessTokenScopes))
bitmap |= 1 << uint(util.FindStringInSlice(AccessTokenScopeUserFollow, AllAccessTokenScopes))
case AccessTokenScopePackage:
bitmap |= 1 << uint(sliceIndex(AllAccessTokenScopes, AccessTokenScopeWritePackage))
bitmap |= 1 << uint(sliceIndex(AllAccessTokenScopes, AccessTokenScopeReadPackage))
bitmap |= 1 << uint(sliceIndex(AllAccessTokenScopes, AccessTokenScopeDeletePackage))
bitmap |= 1 << uint(util.FindStringInSlice(AccessTokenScopeWritePackage, AllAccessTokenScopes))
bitmap |= 1 << uint(util.FindStringInSlice(AccessTokenScopeReadPackage, AllAccessTokenScopes))
bitmap |= 1 << uint(util.FindStringInSlice(AccessTokenScopeDeletePackage, AllAccessTokenScopes))
case AccessTokenScopeAdminGPGKey:
bitmap |= 1 << uint(sliceIndex(AllAccessTokenScopes, AccessTokenScopeWriteGPGKey))
bitmap |= 1 << uint(sliceIndex(AllAccessTokenScopes, AccessTokenScopeReadGPGKey))
bitmap |= 1 << uint(util.FindStringInSlice(AccessTokenScopeWriteGPGKey, AllAccessTokenScopes))
bitmap |= 1 << uint(util.FindStringInSlice(AccessTokenScopeReadGPGKey, AllAccessTokenScopes))
}
}
return bitmap, nil
@ -142,7 +144,7 @@ func (s AccessTokenScope) Normalize() (AccessTokenScope, error) {
// HasScope returns true if the string has the given scope
func (s AccessTokenScope) HasScope(scope string) (bool, error) {
index := sliceIndex(AllAccessTokenScopes, scope)
index := util.FindStringInSlice(scope, AllAccessTokenScopes)
if index == -1 {
return false, fmt.Errorf("invalid access token scope: %s", scope)
}
@ -218,13 +220,3 @@ func (bitmap AccessTokenScopeBitmap) ToScope() AccessTokenScope {
))
return scope
}
// sliceIndex returns the index of the first instance of str in slice, or -1 if str is not present in slice.
func sliceIndex(slice []string, element string) int {
for i, v := range slice {
if v == element {
return i
}
}
return -1
}

View file

@ -38,26 +38,32 @@ func ExistsInSlice(target string, slice []string) bool {
return i < len(slice)
}
// IsStringInSlice sequential searches if string exists in slice.
func IsStringInSlice(target string, slice []string, insensitive ...bool) bool {
// FindStringInSlice returns the index of the first instance of target in slice.
// If target is not present in slice, -1 is returned.
func FindStringInSlice(target string, slice []string, insensitive ...bool) int {
caseInsensitive := false
if len(insensitive) != 0 && insensitive[0] {
caseInsensitive = true
target = strings.ToLower(target)
}
for i := 0; i < len(slice); i++ {
for i, s := range slice {
if caseInsensitive {
if strings.ToLower(slice[i]) == target {
return true
if strings.ToLower(s) == target {
return i
}
} else {
if slice[i] == target {
return true
if s == target {
return i
}
}
}
return false
return -1
}
// IsStringInSlice sequential searches if string exists in slice.
func IsStringInSlice(target string, slice []string, insensitive ...bool) bool {
return FindStringInSlice(target, slice, insensitive...) >= 0
}
// IsInt64InSlice sequential searches if int64 exists in slice.

View file

@ -0,0 +1,50 @@
package util
import (
"strconv"
"testing"
"github.com/stretchr/testify/assert"
)
func TestFindStringInSlice(t *testing.T) {
tests := []struct {
target string
slice []string
caseInsensitive bool
want int
}{
{target: "a", slice: []string{"a", "b", "c"}, want: 0},
{target: "c", slice: []string{"a", "b", "c"}, want: 2},
{target: "d", slice: []string{"a", "b", "c"}, want: -1},
{target: "C", slice: []string{"a", "b", "c"}, caseInsensitive: true, want: 2},
}
for i, test := range tests {
t.Run(strconv.Itoa(i), func(t *testing.T) {
got := FindStringInSlice(test.target, test.slice, test.caseInsensitive)
assert.Equal(t, test.want, got)
})
}
}
func TestIsStringInSlice(t *testing.T) {
tests := []struct {
target string
slice []string
caseInsensitive bool
want bool
}{
{target: "a", slice: []string{"a", "b", "c"}, want: true},
{target: "c", slice: []string{"a", "b", "c"}, want: true},
{target: "d", slice: []string{"a", "b", "c"}, want: false},
{target: "C", slice: []string{"a", "b", "c"}, caseInsensitive: true, want: true},
}
for i, test := range tests {
t.Run(strconv.Itoa(i), func(t *testing.T) {
got := IsStringInSlice(test.target, test.slice, test.caseInsensitive)
assert.Equal(t, test.want, got)
})
}
}