mirror of
https://github.com/pgsty/minio.git
synced 2026-07-23 14:10:25 +03:00
Run modernize (#21546)
`go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest -fix -test ./...` executed. `go generate ./...` ran afterwards to keep generated.
This commit is contained in:
@@ -22,6 +22,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -224,10 +225,8 @@ func LookupConfig(kvs config.KVS) (cfg Config, err error) {
|
||||
corsAllowOrigin = []string{"*"} // defaults to '*'
|
||||
} else {
|
||||
corsAllowOrigin = strings.Split(corsList, ",")
|
||||
for _, cors := range corsAllowOrigin {
|
||||
if cors == "" {
|
||||
return cfg, errors.New("invalid cors value")
|
||||
}
|
||||
if slices.Contains(corsAllowOrigin, "") {
|
||||
return cfg, errors.New("invalid cors value")
|
||||
}
|
||||
}
|
||||
cfg.CorsAllowOrigin = corsAllowOrigin
|
||||
|
||||
@@ -41,7 +41,6 @@ func TestParseCompressIncludes(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(testCase.str, func(t *testing.T) {
|
||||
gotPatterns, err := parseCompressIncludes(testCase.str)
|
||||
if !testCase.success && err == nil {
|
||||
|
||||
+12
-27
@@ -21,7 +21,9 @@ import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"maps"
|
||||
"regexp"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -61,7 +63,7 @@ type ErrConfigNotFound struct {
|
||||
func Error[T ErrorConfig, PT interface {
|
||||
*T
|
||||
setMsg(string)
|
||||
}](format string, vals ...interface{},
|
||||
}](format string, vals ...any,
|
||||
) T {
|
||||
pt := PT(new(T))
|
||||
pt.setMsg(fmt.Sprintf(format, vals...))
|
||||
@@ -69,7 +71,7 @@ func Error[T ErrorConfig, PT interface {
|
||||
}
|
||||
|
||||
// Errorf formats an error and returns it as a generic config error
|
||||
func Errorf(format string, vals ...interface{}) ErrConfigGeneric {
|
||||
func Errorf(format string, vals ...any) ErrConfigGeneric {
|
||||
return Error[ErrConfigGeneric](format, vals...)
|
||||
}
|
||||
|
||||
@@ -238,9 +240,7 @@ var DefaultKVS = map[string]KVS{}
|
||||
// globally, this should be called only once preferably
|
||||
// during `init()`.
|
||||
func RegisterDefaultKVS(kvsMap map[string]KVS) {
|
||||
for subSys, kvs := range kvsMap {
|
||||
DefaultKVS[subSys] = kvs
|
||||
}
|
||||
maps.Copy(DefaultKVS, kvsMap)
|
||||
}
|
||||
|
||||
// HelpSubSysMap - help for all individual KVS for each sub-systems
|
||||
@@ -253,9 +253,7 @@ var HelpSubSysMap = map[string]HelpKVS{}
|
||||
// this function should be called only once
|
||||
// preferably in during `init()`.
|
||||
func RegisterHelpSubSys(helpKVSMap map[string]HelpKVS) {
|
||||
for subSys, hkvs := range helpKVSMap {
|
||||
HelpSubSysMap[subSys] = hkvs
|
||||
}
|
||||
maps.Copy(HelpSubSysMap, helpKVSMap)
|
||||
}
|
||||
|
||||
// HelpDeprecatedSubSysMap - help for all deprecated sub-systems, that may be
|
||||
@@ -265,9 +263,7 @@ var HelpDeprecatedSubSysMap = map[string]HelpKV{}
|
||||
// RegisterHelpDeprecatedSubSys - saves input help KVS for deprecated
|
||||
// sub-systems globally. Should be called only once at init.
|
||||
func RegisterHelpDeprecatedSubSys(helpDeprecatedKVMap map[string]HelpKV) {
|
||||
for k, v := range helpDeprecatedKVMap {
|
||||
HelpDeprecatedSubSysMap[k] = v
|
||||
}
|
||||
maps.Copy(HelpDeprecatedSubSysMap, helpDeprecatedKVMap)
|
||||
}
|
||||
|
||||
// KV - is a shorthand of each key value.
|
||||
@@ -353,9 +349,7 @@ func Merge(cfgKVS map[string]KVS, envname string, defaultKVS KVS) map[string]KVS
|
||||
}
|
||||
newCfgKVS[tgt] = defaultKVS
|
||||
}
|
||||
for tgt, kv := range cfgKVS {
|
||||
newCfgKVS[tgt] = kv
|
||||
}
|
||||
maps.Copy(newCfgKVS, cfgKVS)
|
||||
return newCfgKVS
|
||||
}
|
||||
|
||||
@@ -642,11 +636,8 @@ func CheckValidKeys(subSys string, kv KVS, validKVS KVS, deprecatedKeys ...strin
|
||||
continue
|
||||
}
|
||||
var skip bool
|
||||
for _, deprecatedKey := range deprecatedKeys {
|
||||
if kv.Key == deprecatedKey {
|
||||
skip = true
|
||||
break
|
||||
}
|
||||
if slices.Contains(deprecatedKeys, kv.Key) {
|
||||
skip = true
|
||||
}
|
||||
if skip {
|
||||
continue
|
||||
@@ -852,7 +843,7 @@ func (c Config) DelKVS(s string) error {
|
||||
if len(inputs) == 2 {
|
||||
currKVS := ck.Clone()
|
||||
defKVS := DefaultKVS[subSys]
|
||||
for _, delKey := range strings.Fields(inputs[1]) {
|
||||
for delKey := range strings.FieldsSeq(inputs[1]) {
|
||||
_, ok := currKVS.Lookup(delKey)
|
||||
if !ok {
|
||||
return Error[ErrConfigNotFound]("key %s doesn't exist", delKey)
|
||||
@@ -1407,13 +1398,7 @@ func (c Config) GetSubsysInfo(subSys, target string, redactSecrets bool) ([]Subs
|
||||
}
|
||||
|
||||
if target != "" {
|
||||
found := false
|
||||
for _, t := range targets {
|
||||
if t == target {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
found := slices.Contains(targets, target)
|
||||
if !found {
|
||||
return nil, Errorf("there is no target `%s` for subsystem `%s`", target, subSys)
|
||||
}
|
||||
|
||||
@@ -88,7 +88,6 @@ func TestKVFields(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
t.Run("", func(t *testing.T) {
|
||||
gotFields := kvFields(test.input, test.keys)
|
||||
if len(gotFields) != len(test.expectedFields) {
|
||||
|
||||
@@ -100,7 +100,7 @@ func BenchmarkEncrypt(b *testing.B) {
|
||||
context = kms.Context{"key": "value"}
|
||||
)
|
||||
b.SetBytes(int64(size))
|
||||
for i := 0; i < b.N; i++ {
|
||||
for b.Loop() {
|
||||
ciphertext, err := Encrypt(KMS, plaintext, context)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
|
||||
@@ -65,7 +65,7 @@ func (u Err) Msg(m string) Err {
|
||||
}
|
||||
|
||||
// Msgf - Replace the current error's message
|
||||
func (u Err) Msgf(m string, args ...interface{}) Err {
|
||||
func (u Err) Msgf(m string, args ...any) Err {
|
||||
e := u.Clone()
|
||||
if len(args) == 0 {
|
||||
e.msg = m
|
||||
@@ -76,7 +76,7 @@ func (u Err) Msgf(m string, args ...interface{}) Err {
|
||||
}
|
||||
|
||||
// Hint - Replace the current error's message
|
||||
func (u Err) Hint(m string, args ...interface{}) Err {
|
||||
func (u Err) Hint(m string, args ...any) Err {
|
||||
e := u.Clone()
|
||||
e.hint = fmt.Sprintf(m, args...)
|
||||
return e
|
||||
|
||||
@@ -49,7 +49,6 @@ func TestParseEndpoints(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(testCase.s, func(t *testing.T) {
|
||||
endpoints, secure, err := parseEndpoints(testCase.s)
|
||||
if err != nil && testCase.success {
|
||||
|
||||
@@ -38,7 +38,7 @@ type publicKeys struct {
|
||||
*sync.RWMutex
|
||||
|
||||
// map of kid to public key
|
||||
pkMap map[string]interface{}
|
||||
pkMap map[string]any
|
||||
}
|
||||
|
||||
func (pk *publicKeys) parseAndAdd(b io.Reader) error {
|
||||
@@ -59,14 +59,14 @@ func (pk *publicKeys) parseAndAdd(b io.Reader) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pk *publicKeys) add(keyID string, key interface{}) {
|
||||
func (pk *publicKeys) add(keyID string, key any) {
|
||||
pk.Lock()
|
||||
defer pk.Unlock()
|
||||
|
||||
pk.pkMap[keyID] = key
|
||||
}
|
||||
|
||||
func (pk *publicKeys) get(kid string) interface{} {
|
||||
func (pk *publicKeys) get(kid string) any {
|
||||
pk.RLock()
|
||||
defer pk.RUnlock()
|
||||
return pk.pkMap[kid]
|
||||
@@ -103,7 +103,7 @@ var (
|
||||
ErrTokenExpired = errors.New("token expired")
|
||||
)
|
||||
|
||||
func updateClaimsExpiry(dsecs string, claims map[string]interface{}) error {
|
||||
func updateClaimsExpiry(dsecs string, claims map[string]any) error {
|
||||
expStr := claims["exp"]
|
||||
if expStr == "" {
|
||||
return ErrTokenExpired
|
||||
@@ -133,7 +133,7 @@ const (
|
||||
)
|
||||
|
||||
// Validate - validates the id_token.
|
||||
func (r *Config) Validate(ctx context.Context, arn arn.ARN, token, accessToken, dsecs string, claims map[string]interface{}) error {
|
||||
func (r *Config) Validate(ctx context.Context, arn arn.ARN, token, accessToken, dsecs string, claims map[string]any) error {
|
||||
jp := new(jwtgo.Parser)
|
||||
jp.ValidMethods = []string{
|
||||
"RS256", "RS384", "RS512",
|
||||
@@ -143,7 +143,7 @@ func (r *Config) Validate(ctx context.Context, arn arn.ARN, token, accessToken,
|
||||
"ES3256", "ES3384", "ES3512",
|
||||
}
|
||||
|
||||
keyFuncCallback := func(jwtToken *jwtgo.Token) (interface{}, error) {
|
||||
keyFuncCallback := func(jwtToken *jwtgo.Token) (any, error) {
|
||||
kid, ok := jwtToken.Header["kid"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("Invalid kid value %v", jwtToken.Header["kid"])
|
||||
@@ -221,7 +221,7 @@ func (r *Config) Validate(ctx context.Context, arn arn.ARN, token, accessToken,
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Config) updateUserinfoClaims(ctx context.Context, arn arn.ARN, accessToken string, claims map[string]interface{}) error {
|
||||
func (r *Config) updateUserinfoClaims(ctx context.Context, arn arn.ARN, accessToken string, claims map[string]any) error {
|
||||
pCfg, ok := r.arnProviderCfgsMap[arn]
|
||||
// If claim user info is enabled, get claims from userInfo
|
||||
// and overwrite them with the claims from JWT.
|
||||
|
||||
@@ -39,7 +39,7 @@ import (
|
||||
|
||||
func TestUpdateClaimsExpiry(t *testing.T) {
|
||||
testCases := []struct {
|
||||
exp interface{}
|
||||
exp any
|
||||
dsecs string
|
||||
expectedFailure bool
|
||||
}{
|
||||
@@ -58,9 +58,8 @@ func TestUpdateClaimsExpiry(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run("", func(t *testing.T) {
|
||||
claims := map[string]interface{}{}
|
||||
claims := map[string]any{}
|
||||
claims["exp"] = testCase.exp
|
||||
err := updateClaimsExpiry(testCase.dsecs, claims)
|
||||
if err != nil && !testCase.expectedFailure {
|
||||
@@ -99,7 +98,7 @@ func TestJWTHMACType(t *testing.T) {
|
||||
ExpiresAt: 253428928061,
|
||||
Audience: "76b95ae5-33ef-4283-97b7-d2a85dc2d8f4",
|
||||
},
|
||||
Header: map[string]interface{}{
|
||||
Header: map[string]any{
|
||||
"typ": "JWT",
|
||||
"alg": jwtgo.SigningMethodHS256.Alg(),
|
||||
"kid": "76b95ae5-33ef-4283-97b7-d2a85dc2d8f4",
|
||||
@@ -119,7 +118,7 @@ func TestJWTHMACType(t *testing.T) {
|
||||
|
||||
pubKeys := publicKeys{
|
||||
RWMutex: &sync.RWMutex{},
|
||||
pkMap: map[string]interface{}{},
|
||||
pkMap: map[string]any{},
|
||||
}
|
||||
pubKeys.add("76b95ae5-33ef-4283-97b7-d2a85dc2d8f4", []byte("WNGvKVyyNmXq0TraSvjaDN9CtpFgx35IXtGEffMCPR0"))
|
||||
|
||||
@@ -165,7 +164,7 @@ func TestJWT(t *testing.T) {
|
||||
|
||||
pubKeys := publicKeys{
|
||||
RWMutex: &sync.RWMutex{},
|
||||
pkMap: map[string]interface{}{},
|
||||
pkMap: map[string]any{},
|
||||
}
|
||||
err := pubKeys.parseAndAdd(bytes.NewBuffer([]byte(jsonkey)))
|
||||
if err != nil {
|
||||
|
||||
@@ -22,7 +22,9 @@ import (
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"io"
|
||||
"maps"
|
||||
"net/http"
|
||||
"slices"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -186,15 +188,9 @@ func (r *Config) Clone() Config {
|
||||
transport: r.transport,
|
||||
closeRespFn: r.closeRespFn,
|
||||
}
|
||||
for k, v := range r.arnProviderCfgsMap {
|
||||
cfg.arnProviderCfgsMap[k] = v
|
||||
}
|
||||
for k, v := range r.ProviderCfgs {
|
||||
cfg.ProviderCfgs[k] = v
|
||||
}
|
||||
for k, v := range r.roleArnPolicyMap {
|
||||
cfg.roleArnPolicyMap[k] = v
|
||||
}
|
||||
maps.Copy(cfg.arnProviderCfgsMap, r.arnProviderCfgsMap)
|
||||
maps.Copy(cfg.ProviderCfgs, r.ProviderCfgs)
|
||||
maps.Copy(cfg.roleArnPolicyMap, r.roleArnPolicyMap)
|
||||
return cfg
|
||||
}
|
||||
|
||||
@@ -210,7 +206,7 @@ func LookupConfig(s config.Config, transport http.RoundTripper, closeRespFn func
|
||||
ProviderCfgs: map[string]*providerCfg{},
|
||||
pubKeys: publicKeys{
|
||||
RWMutex: &sync.RWMutex{},
|
||||
pkMap: map[string]interface{}{},
|
||||
pkMap: map[string]any{},
|
||||
},
|
||||
roleArnPolicyMap: map[arn.ARN]string{},
|
||||
transport: openIDClientTransport,
|
||||
@@ -308,7 +304,7 @@ func LookupConfig(s config.Config, transport http.RoundTripper, closeRespFn func
|
||||
|
||||
if scopeList := getCfgVal(Scopes); scopeList != "" {
|
||||
var scopes []string
|
||||
for _, scope := range strings.Split(scopeList, ",") {
|
||||
for scope := range strings.SplitSeq(scopeList, ",") {
|
||||
scope = strings.TrimSpace(scope)
|
||||
if scope == "" {
|
||||
return c, config.Errorf("empty scope value is not allowed '%s', please refer to our documentation", scopeList)
|
||||
@@ -414,13 +410,7 @@ func (r *Config) GetConfigInfo(s config.Config, cfgName string) ([]madmin.IDPCfg
|
||||
return nil, err
|
||||
}
|
||||
|
||||
present := false
|
||||
for _, cfg := range openIDConfigs {
|
||||
if cfg == cfgName {
|
||||
present = true
|
||||
break
|
||||
}
|
||||
}
|
||||
present := slices.Contains(openIDConfigs, cfgName)
|
||||
|
||||
if !present {
|
||||
return nil, ErrProviderConfigNotFound
|
||||
|
||||
@@ -113,7 +113,7 @@ func (p *providerCfg) GetRoleArn() string {
|
||||
// claims as part of the normal oauth2 flow, instead rely
|
||||
// on service providers making calls to IDP to fetch additional
|
||||
// claims available from the UserInfo endpoint
|
||||
func (p *providerCfg) UserInfo(ctx context.Context, accessToken string, transport http.RoundTripper) (map[string]interface{}, error) {
|
||||
func (p *providerCfg) UserInfo(ctx context.Context, accessToken string, transport http.RoundTripper) (map[string]any, error) {
|
||||
if p.JWKS.URL == nil || p.JWKS.URL.String() == "" {
|
||||
return nil, errors.New("openid not configured")
|
||||
}
|
||||
@@ -147,7 +147,7 @@ func (p *providerCfg) UserInfo(ctx context.Context, accessToken string, transpor
|
||||
return nil, errors.New(resp.Status)
|
||||
}
|
||||
|
||||
claims := map[string]interface{}{}
|
||||
claims := map[string]any{}
|
||||
if err = json.NewDecoder(resp.Body).Decode(&claims); err != nil {
|
||||
// uncomment this for debugging when needed.
|
||||
// reqBytes, _ := httputil.DumpRequest(req, false)
|
||||
|
||||
@@ -333,9 +333,9 @@ func New(shutdownCtx context.Context, args Args) *AuthNPlugin {
|
||||
// AuthNSuccessResponse - represents the response from the authentication plugin
|
||||
// service.
|
||||
type AuthNSuccessResponse struct {
|
||||
User string `json:"user"`
|
||||
MaxValiditySeconds int `json:"maxValiditySeconds"`
|
||||
Claims map[string]interface{} `json:"claims"`
|
||||
User string `json:"user"`
|
||||
MaxValiditySeconds int `json:"maxValiditySeconds"`
|
||||
Claims map[string]any `json:"claims"`
|
||||
}
|
||||
|
||||
// AuthNErrorResponse - represents an error response from the authN plugin.
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
package event
|
||||
|
||||
import "maps"
|
||||
|
||||
// TargetIDSet - Set representation of TargetIDs.
|
||||
type TargetIDSet map[TargetID]struct{}
|
||||
|
||||
@@ -28,9 +30,7 @@ func (set TargetIDSet) IsEmpty() bool {
|
||||
// Clone - returns copy of this set.
|
||||
func (set TargetIDSet) Clone() TargetIDSet {
|
||||
setCopy := NewTargetIDSet()
|
||||
for k, v := range set {
|
||||
setCopy[k] = v
|
||||
}
|
||||
maps.Copy(setCopy, set)
|
||||
return setCopy
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ package event
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"maps"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -151,9 +152,7 @@ func (list *TargetList) TargetMap() map[TargetID]Target {
|
||||
defer list.RUnlock()
|
||||
|
||||
ntargets := make(map[TargetID]Target, len(list.targets))
|
||||
for k, v := range list.targets {
|
||||
ntargets[k] = v
|
||||
}
|
||||
maps.Copy(ntargets, list.targets)
|
||||
return ntargets
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ const (
|
||||
logSubsys = "notify"
|
||||
)
|
||||
|
||||
func logOnceIf(ctx context.Context, err error, id string, errKind ...interface{}) {
|
||||
func logOnceIf(ctx context.Context, err error, id string, errKind ...any) {
|
||||
logger.LogOnceIf(ctx, logSubsys, err, id, errKind...)
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ const (
|
||||
logSubsys = "notify"
|
||||
)
|
||||
|
||||
func logOnceIf(ctx context.Context, err error, id string, errKind ...interface{}) {
|
||||
func logOnceIf(ctx context.Context, err error, id string, errKind ...any) {
|
||||
logger.LogOnceIf(ctx, logSubsys, err, id, errKind...)
|
||||
}
|
||||
|
||||
@@ -412,7 +412,7 @@ func GetNotifyKafka(kafkaKVS map[string]config.KVS) (map[string]target.KafkaArgs
|
||||
if len(kafkaBrokers) == 0 {
|
||||
return nil, config.Errorf("kafka 'brokers' cannot be empty")
|
||||
}
|
||||
for _, s := range strings.Split(kafkaBrokers, config.ValueSeparator) {
|
||||
for s := range strings.SplitSeq(kafkaBrokers, config.ValueSeparator) {
|
||||
var host *xnet.Host
|
||||
host, err = xnet.ParseHost(s)
|
||||
if err != nil {
|
||||
|
||||
@@ -170,7 +170,7 @@ func (o *Opa) IsAllowed(args policy.Args) (bool, error) {
|
||||
}
|
||||
|
||||
// OPA input
|
||||
body := make(map[string]interface{})
|
||||
body := make(map[string]any)
|
||||
body["input"] = args
|
||||
|
||||
inputBytes, err := json.Marshal(body)
|
||||
|
||||
@@ -185,7 +185,7 @@ func (o *AuthZPlugin) IsAllowed(args policy.Args) (bool, error) {
|
||||
}
|
||||
|
||||
// Access Management Plugin Input
|
||||
body := make(map[string]interface{})
|
||||
body := make(map[string]any)
|
||||
body["input"] = args
|
||||
|
||||
inputBytes, err := json.Marshal(body)
|
||||
|
||||
@@ -147,7 +147,7 @@ func (sc *StorageClass) UnmarshalText(b []byte) error {
|
||||
// MarshalText - marshals storage class string.
|
||||
func (sc *StorageClass) MarshalText() ([]byte, error) {
|
||||
if sc.Parity != 0 {
|
||||
return []byte(fmt.Sprintf("%s:%d", schemePrefix, sc.Parity)), nil
|
||||
return fmt.Appendf(nil, "%s:%d", schemePrefix, sc.Parity), nil
|
||||
}
|
||||
return []byte{}, nil
|
||||
}
|
||||
@@ -430,6 +430,6 @@ func LookupConfig(kvs config.KVS, setDriveCount int) (cfg Config, err error) {
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func configLogOnceIf(ctx context.Context, err error, id string, errKind ...interface{}) {
|
||||
func configLogOnceIf(ctx context.Context, err error, id string, errKind ...any) {
|
||||
logger.LogOnceIf(ctx, "config", err, id, errKind...)
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ func (c Config) submitPost(r *http.Request) (string, error) {
|
||||
}
|
||||
|
||||
// Post submit 'payload' to specified URL
|
||||
func (c Config) Post(reqURL string, payload interface{}) (string, error) {
|
||||
func (c Config) Post(reqURL string, payload any) (string, error) {
|
||||
if !c.Registered() {
|
||||
return "", errors.New("Deployment is not registered with SUBNET. Please register the deployment via 'mc license register ALIAS'")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user