mirror of
https://github.com/go-gitea/gitea.git
synced 2024-11-15 09:58:28 -07:00
Update docs and comments to remove macaron (#14491)
This commit is contained in:
parent
25b6255b92
commit
0cd87d64ff
@ -863,8 +863,6 @@ ROOT_PATH =
|
||||
MODE = console
|
||||
; Buffer length of the channel, keep it as it is if you don't know what it is.
|
||||
BUFFER_LEN = 10000
|
||||
REDIRECT_MACARON_LOG = false
|
||||
MACARON = file
|
||||
; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Info"
|
||||
ROUTER_LOG_LEVEL = Info
|
||||
ROUTER = console
|
||||
|
@ -47,8 +47,6 @@ PATH = /data/gitea/attachments
|
||||
[log]
|
||||
MODE = console
|
||||
LEVEL = info
|
||||
REDIRECT_MACARON_LOG = true
|
||||
MACARON = console
|
||||
ROUTER = console
|
||||
ROOT_PATH = /data/gitea/log
|
||||
|
||||
|
@ -611,7 +611,7 @@ Default templates for project boards:
|
||||
- `STACKTRACE_LEVEL`: **None**: Default log level at which to log create stack traces. \[Trace, Debug, Info, Warn, Error, Critical, Fatal, None\]
|
||||
- `ROUTER_LOG_LEVEL`: **Info**: The log level that the router should log at. (If you are setting the access log, its recommended to place this at Debug.)
|
||||
- `ROUTER`: **console**: The mode or name of the log the router should log to. (If you set this to `,` it will log to default gitea logger.)
|
||||
NB: You must `REDIRECT_MACARON_LOG` and have `DISABLE_ROUTER_LOG` set to `false` for this option to take effect. Configure each mode in per mode log subsections `\[log.modename.router\]`.
|
||||
NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take effect. Configure each mode in per mode log subsections `\[log.modename.router\]`.
|
||||
- `ENABLE_ACCESS_LOG`: **false**: Creates an access.log in NCSA common log format, or as per the following template
|
||||
- `ACCESS`: **file**: Logging mode for the access logger, use a comma to separate values. Configure each mode in per mode log subsections `\[log.modename.access\]`. By default the file mode will log to `$ROOT_PATH/access.log`. (If you set this to `,` it will log to the default gitea logger.)
|
||||
- `ACCESS_LOG_TEMPLATE`: **`{{.Ctx.RemoteAddr}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}"`**: Sets the template used to create the access log.
|
||||
|
@ -58,15 +58,6 @@ For documentation about each of the variables available, refer to the
|
||||
- `HOMEDRIVE`: Main drive path used to access the home directory (C:)
|
||||
- `HOMEPATH`: Home relative path in the given home drive path
|
||||
|
||||
## Macaron (framework used by Gitea)
|
||||
|
||||
- `HOST`: Host Macaron will listen on
|
||||
- `PORT`: Port Macaron will listen on
|
||||
- `MACARON_ENV`: global variable to provide special functionality for development environments
|
||||
vs. production environments. If MACARON_ENV is set to "" or "development", then templates will
|
||||
be recompiled on every request. For more performance, set the MACARON_ENV environment variable
|
||||
to "production".
|
||||
|
||||
## Miscellaneous
|
||||
|
||||
- `SKIP_MINWINSVC`: If set to 1, do not run as a service on Windows.
|
||||
|
@ -50,13 +50,6 @@ GITEA_CUSTOM=/home/gitea/custom ./gitea web
|
||||
* `HOMEDRIVE`: 用于访问 home 目录的主驱动器路径(C盘)
|
||||
* `HOMEPATH`:在指定主驱动器下的 home 目录相对路径
|
||||
|
||||
## Macaron(Gitea 使用的 web 框架)
|
||||
|
||||
* `HOST`:Macaron 监听的主机地址
|
||||
* `PORT`:Macaron 监听的端口地址
|
||||
* `MACARON_ENV`:为开发环境和生产环境提供特殊功能性配置的全局变量,当 MACARON_ENV 设置为 "" 或 "development"
|
||||
时,每次请求都会重编译页面模板。为了提高性能表现,可将它设置为 "production"。
|
||||
|
||||
## Miscellaneous
|
||||
|
||||
* `SKIP_MINWINSVC`:如果设置为 1,在 Windows 上不会以 service 的形式运行。
|
||||
|
@ -27,7 +27,6 @@ The fundamental thing to be aware of in Gitea is that there are several
|
||||
log groups:
|
||||
|
||||
- The "Default" logger
|
||||
- The Macaron logger
|
||||
- The Router logger
|
||||
- The Access logger
|
||||
- The XORM logger
|
||||
@ -74,8 +73,7 @@ You can disable Router log by setting `DISABLE_ROUTER_LOG`.
|
||||
You can configure the outputs of this
|
||||
router log by setting the `ROUTER` value in the `[log]` section of the
|
||||
configuration. `ROUTER` will default to `console` if unset. The Gitea
|
||||
Router logs the same data as the Macaron log but has slightly different
|
||||
coloring. It logs at the `Info` level by default, but this can be
|
||||
Router logs at the `Info` level by default, but this can be
|
||||
changed if desired by setting the `ROUTER_LOG_LEVEL` value.
|
||||
|
||||
Please note, setting the `LEVEL` of this logger to a level above
|
||||
@ -182,7 +180,7 @@ Certain configuration is common to all modes of log output:
|
||||
- `STACKTRACE_LEVEL` is the lowest level that this output will print
|
||||
a stacktrace. This value is inherited.
|
||||
- `MODE` is the mode of the log output. It will default to the sublogger
|
||||
name. Thus `[log.console.macaron]` will default to `MODE = console`.
|
||||
name. Thus `[log.console.router]` will default to `MODE = console`.
|
||||
- `COLORIZE` will default to `true` for `console` as
|
||||
described, otherwise it will default to `false`.
|
||||
|
||||
@ -280,8 +278,6 @@ LOG_SQL = false ; SQL logs are rarely helpful unless we specifically ask for the
|
||||
[log]
|
||||
MODE = console
|
||||
LEVEL = debug ; please set the level to debug when we are debugging a problem
|
||||
REDIRECT_MACARON_LOG = true
|
||||
MACARON = console
|
||||
ROUTER = console
|
||||
COLORIZE = false ; this can be true if you can strip out the ansi coloring
|
||||
```
|
||||
@ -314,7 +310,6 @@ ROOT_PATH = %(GITEA_WORK_DIR)/log
|
||||
MODE = console
|
||||
LEVEL = Info
|
||||
STACKTRACE_LEVEL = None
|
||||
REDIRECT_MACARON_LOG = false
|
||||
ENABLE_ACCESS_LOG = false
|
||||
ENABLE_XORM_LOG = true
|
||||
XORM = ,
|
||||
@ -345,7 +340,7 @@ recommended that pausing only done for a very short period of time.
|
||||
## Adding and removing logging whilst Gitea is running
|
||||
|
||||
It is possible to add and remove logging whilst Gitea is running using the `gitea manager logging add` and `remove` subcommands.
|
||||
This functionality can only adjust running log systems and cannot be used to start the access, macaron or router loggers if they
|
||||
This functionality can only adjust running log systems and cannot be used to start the access or router loggers if they
|
||||
were not already initialised. If you wish to start these systems you are advised to adjust the app.ini and (gracefully) restart
|
||||
the Gitea service.
|
||||
|
||||
|
@ -78,9 +78,7 @@ PROVIDER_CONFIG = integrations/gitea-integration-mssql/data/sessions
|
||||
[log]
|
||||
MODE = test,file
|
||||
ROOT_PATH = mssql-log
|
||||
REDIRECT_MACARON_LOG = true
|
||||
ROUTER = ,
|
||||
MACARON = ,
|
||||
XORM = file
|
||||
|
||||
[log.test]
|
||||
|
@ -97,9 +97,7 @@ PROVIDER_CONFIG = integrations/gitea-integration-mysql/data/sessions
|
||||
[log]
|
||||
MODE = test,file
|
||||
ROOT_PATH = mysql-log
|
||||
REDIRECT_MACARON_LOG = true
|
||||
ROUTER = ,
|
||||
MACARON = ,
|
||||
XORM = file
|
||||
|
||||
[log.test]
|
||||
|
@ -70,9 +70,7 @@ PROVIDER_CONFIG = data/sessions-mysql8
|
||||
[log]
|
||||
MODE = test,file
|
||||
ROOT_PATH = mysql8-log
|
||||
REDIRECT_MACARON_LOG = true
|
||||
ROUTER = ,
|
||||
MACARON = ,
|
||||
XORM = file
|
||||
|
||||
[log.test]
|
||||
|
@ -235,7 +235,7 @@ func TestRefreshTokenInvalidation(t *testing.T) {
|
||||
"redirect_uri": "a",
|
||||
"refresh_token": parsed.RefreshToken,
|
||||
})
|
||||
// tip: Why this changed, because macaron will set req.Body back when consume the req but chi will not.
|
||||
|
||||
bs, err := ioutil.ReadAll(refreshReq.Body)
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
@ -79,9 +79,7 @@ PROVIDER_CONFIG = integrations/gitea-integration-pgsql/data/sessions
|
||||
[log]
|
||||
MODE = test,file
|
||||
ROOT_PATH = pgsql-log
|
||||
REDIRECT_MACARON_LOG = true
|
||||
ROUTER = ,
|
||||
MACARON = ,
|
||||
XORM = file
|
||||
|
||||
[log.test]
|
||||
|
@ -75,9 +75,7 @@ PROVIDER_CONFIG = integrations/gitea-integration-sqlite/data/sessions
|
||||
[log]
|
||||
MODE = test,file
|
||||
ROOT_PATH = sqlite-log
|
||||
REDIRECT_MACARON_LOG = true
|
||||
ROUTER = ,
|
||||
MACARON = ,
|
||||
XORM = file
|
||||
|
||||
[log.test]
|
||||
|
@ -23,7 +23,7 @@ import (
|
||||
"gitea.com/go-chi/session"
|
||||
)
|
||||
|
||||
// APIContext is a specific macaron context for API service
|
||||
// APIContext is a specific context for API service
|
||||
type APIContext struct {
|
||||
*Context
|
||||
Org *APIOrganization
|
||||
@ -217,7 +217,7 @@ func (ctx *APIContext) CheckForOTP() {
|
||||
}
|
||||
}
|
||||
|
||||
// APIContexter returns apicontext as macaron middleware
|
||||
// APIContexter returns apicontext as middleware
|
||||
func APIContexter() func(http.Handler) http.Handler {
|
||||
var csrfOpts = getCsrfOpts()
|
||||
|
||||
|
@ -170,7 +170,7 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
|
||||
}
|
||||
}
|
||||
|
||||
// OrgAssignment returns a macaron middleware to handle organization assignment
|
||||
// OrgAssignment returns a middleware to handle organization assignment
|
||||
func OrgAssignment(args ...bool) func(ctx *Context) {
|
||||
return func(ctx *Context) {
|
||||
HandleOrgAssignment(ctx, args...)
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
)
|
||||
|
||||
// RequireRepoAdmin returns a macaron middleware for requiring repository admin permission
|
||||
// RequireRepoAdmin returns a middleware for requiring repository admin permission
|
||||
func RequireRepoAdmin() func(ctx *Context) {
|
||||
return func(ctx *Context) {
|
||||
if !ctx.IsSigned || !ctx.Repo.IsAdmin() {
|
||||
@ -19,7 +19,7 @@ func RequireRepoAdmin() func(ctx *Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// RequireRepoWriter returns a macaron middleware for requiring repository write to the specify unitType
|
||||
// RequireRepoWriter returns a middleware for requiring repository write to the specify unitType
|
||||
func RequireRepoWriter(unitType models.UnitType) func(ctx *Context) {
|
||||
return func(ctx *Context) {
|
||||
if !ctx.Repo.CanWrite(unitType) {
|
||||
@ -29,7 +29,7 @@ func RequireRepoWriter(unitType models.UnitType) func(ctx *Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// RequireRepoWriterOr returns a macaron middleware for requiring repository write to one of the unit permission
|
||||
// RequireRepoWriterOr returns a middleware for requiring repository write to one of the unit permission
|
||||
func RequireRepoWriterOr(unitTypes ...models.UnitType) func(ctx *Context) {
|
||||
return func(ctx *Context) {
|
||||
for _, unitType := range unitTypes {
|
||||
@ -41,7 +41,7 @@ func RequireRepoWriterOr(unitTypes ...models.UnitType) func(ctx *Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// RequireRepoReader returns a macaron middleware for requiring repository read to the specify unitType
|
||||
// RequireRepoReader returns a middleware for requiring repository read to the specify unitType
|
||||
func RequireRepoReader(unitType models.UnitType) func(ctx *Context) {
|
||||
return func(ctx *Context) {
|
||||
if !ctx.Repo.CanRead(unitType) {
|
||||
@ -67,7 +67,7 @@ func RequireRepoReader(unitType models.UnitType) func(ctx *Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// RequireRepoReaderOr returns a macaron middleware for requiring repository write to one of the unit permission
|
||||
// RequireRepoReaderOr returns a middleware for requiring repository write to one of the unit permission
|
||||
func RequireRepoReaderOr(unitTypes ...models.UnitType) func(ctx *Context) {
|
||||
return func(ctx *Context) {
|
||||
for _, unitType := range unitTypes {
|
||||
|
@ -28,7 +28,7 @@ func GetPrivateContext(req *http.Request) *PrivateContext {
|
||||
return req.Context().Value(privateContextKey).(*PrivateContext)
|
||||
}
|
||||
|
||||
// PrivateContexter returns apicontext as macaron middleware
|
||||
// PrivateContexter returns apicontext as middleware
|
||||
func PrivateContexter() func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
|
@ -373,7 +373,7 @@ func repoAssignment(ctx *Context, repo *models.Repository) {
|
||||
ctx.Data["IsEmptyRepo"] = ctx.Repo.Repository.IsEmpty
|
||||
}
|
||||
|
||||
// RepoIDAssignment returns a macaron handler which assigns the repo to the context.
|
||||
// RepoIDAssignment returns a handler which assigns the repo to the context.
|
||||
func RepoIDAssignment() func(ctx *Context) {
|
||||
return func(ctx *Context) {
|
||||
repoID := ctx.ParamsInt64(":repoid")
|
||||
@ -393,7 +393,7 @@ func RepoIDAssignment() func(ctx *Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// RepoAssignment returns a macaron to handle repository assignment
|
||||
// RepoAssignment returns a middleware to handle repository assignment
|
||||
func RepoAssignment() func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
@ -849,7 +849,7 @@ func GitHookService() func(ctx *Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// UnitTypes returns a macaron middleware to set unit types to context variables.
|
||||
// UnitTypes returns a middleware to set unit types to context variables.
|
||||
func UnitTypes() func(ctx *Context) {
|
||||
return func(ctx *Context) {
|
||||
ctx.Data["UnitTypeCode"] = models.UnitTypeCode
|
||||
|
@ -267,7 +267,7 @@ func NewLoggerAsWriter(level string, ourLoggers ...*MultiChannelledLogger) *Logg
|
||||
return l
|
||||
}
|
||||
|
||||
// Write implements the io.Writer interface to allow spoofing of macaron
|
||||
// Write implements the io.Writer interface to allow spoofing of chi
|
||||
func (l *LoggerAsWriter) Write(p []byte) (int, error) {
|
||||
for _, logger := range l.ourLoggers {
|
||||
// Skip = 3 because this presumes that we have been called by log.Println()
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Static implements the macaron static handler for serving assets.
|
||||
// Static implements the static handler for serving assets.
|
||||
func Static(opts *Options) func(next http.Handler) http.Handler {
|
||||
return opts.staticHandler(opts.Directory)
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
// Options represents the available options to configure the macaron handler.
|
||||
// Options represents the available options to configure the handler.
|
||||
type Options struct {
|
||||
Directory string
|
||||
IndexFile string
|
||||
@ -34,7 +34,7 @@ var KnownPublicEntries = []string{
|
||||
"favicon.ico",
|
||||
}
|
||||
|
||||
// Custom implements the macaron static handler for serving custom assets.
|
||||
// Custom implements the static handler for serving custom assets.
|
||||
func Custom(opts *Options) func(next http.Handler) http.Handler {
|
||||
return opts.staticHandler(path.Join(setting.CustomPath, "public"))
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
)
|
||||
|
||||
// Static implements the macaron static handler for serving assets.
|
||||
// Static implements the static handler for serving assets.
|
||||
func Static(opts *Options) func(next http.Handler) http.Handler {
|
||||
opts.FileSystem = Assets
|
||||
// we don't need to pass the directory, because the directory var is only
|
||||
|
@ -273,7 +273,7 @@ func newRouterLogService() {
|
||||
// Allow [log] DISABLE_ROUTER_LOG to override [server] DISABLE_ROUTER_LOG
|
||||
DisableRouterLog = Cfg.Section("log").Key("DISABLE_ROUTER_LOG").MustBool(DisableRouterLog)
|
||||
|
||||
if !DisableRouterLog && RedirectMacaronLog {
|
||||
if !DisableRouterLog {
|
||||
options := newDefaultLogOptions()
|
||||
options.filename = filepath.Join(LogRootPath, "router.log")
|
||||
options.flags = "date,time" // For the router we don't want any prefixed flags
|
||||
|
@ -288,7 +288,6 @@ var (
|
||||
LogLevel string
|
||||
StacktraceLogLevel string
|
||||
LogRootPath string
|
||||
RedirectMacaronLog bool
|
||||
DisableRouterLog bool
|
||||
RouterLogLevel log.Level
|
||||
RouterLogMode string
|
||||
@ -539,7 +538,6 @@ func NewContext() {
|
||||
StacktraceLogLevel = getStacktraceLogLevel(Cfg.Section("log"), "STACKTRACE_LEVEL", "None")
|
||||
LogRootPath = Cfg.Section("log").Key("ROOT_PATH").MustString(path.Join(AppWorkPath, "log"))
|
||||
forcePathSeparator(LogRootPath)
|
||||
RedirectMacaronLog = Cfg.Section("log").Key("REDIRECT_MACARON_LOG").MustBool(false)
|
||||
RouterLogLevel = log.FromString(Cfg.Section("log").Key("ROUTER_LOG_LEVEL").MustString("Info"))
|
||||
|
||||
sec := Cfg.Section("server")
|
||||
|
@ -49,7 +49,6 @@ func InitLocales() {
|
||||
}
|
||||
}
|
||||
|
||||
// These codes will be used once macaron removed
|
||||
tags := make([]language.Tag, len(setting.Langs))
|
||||
for i, lang := range setting.Langs {
|
||||
tags[i] = language.Raw.Make(lang)
|
||||
|
@ -2402,7 +2402,6 @@ config.git_gc_timeout = GC Operation Timeout
|
||||
|
||||
config.log_config = Log Configuration
|
||||
config.log_mode = Log Mode
|
||||
config.macaron_log_mode = Macaron Log Mode
|
||||
config.own_named_logger = Named Logger
|
||||
config.routes_to_default_logger = Routes To Default Logger
|
||||
config.go_log = Uses Go Log (redirected to default)
|
||||
|
@ -308,7 +308,6 @@ func Config(ctx *context.Context) {
|
||||
|
||||
ctx.Data["EnvVars"] = envVars
|
||||
ctx.Data["Loggers"] = setting.GetLogDescriptions()
|
||||
ctx.Data["RedirectMacaronLog"] = setting.RedirectMacaronLog
|
||||
ctx.Data["EnableAccessLog"] = setting.EnableAccessLog
|
||||
ctx.Data["AccessLogTemplate"] = setting.AccessLogTemplate
|
||||
ctx.Data["DisableRouterLog"] = setting.DisableRouterLog
|
||||
|
@ -371,8 +371,6 @@ func InstallPost(ctx *context.Context) {
|
||||
cfg.Section("log").Key("MODE").SetValue("console")
|
||||
cfg.Section("log").Key("LEVEL").SetValue(setting.LogLevel)
|
||||
cfg.Section("log").Key("ROOT_PATH").SetValue(form.LogRootPath)
|
||||
cfg.Section("log").Key("REDIRECT_MACARON_LOG").SetValue("true")
|
||||
cfg.Section("log").Key("MACARON").SetValue("console")
|
||||
cfg.Section("log").Key("ROUTER").SetValue("console")
|
||||
|
||||
cfg.Section("security").Key("INSTALL_LOCK").SetValue("true")
|
||||
|
@ -215,7 +215,7 @@ func WebRoutes() *web.Route {
|
||||
return r
|
||||
}
|
||||
|
||||
// RegisterRoutes routes routes to Macaron
|
||||
// RegisterRoutes register routes
|
||||
func RegisterRoutes(m *web.Route) {
|
||||
reqSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: true})
|
||||
ignSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: setting.Service.RequireSignInView})
|
||||
|
@ -344,20 +344,16 @@
|
||||
{{if .DisableRouterLog}}
|
||||
<dd>{{$.i18n.Tr "admin.config.disabled_logger"}}</dd>
|
||||
{{else}}
|
||||
{{if .RedirectMacaronLog}}
|
||||
{{if .Loggers.router.SubLogDescriptions}}
|
||||
<dd>{{$.i18n.Tr "admin.config.own_named_logger"}}</dd>
|
||||
{{range .Loggers.router.SubLogDescriptions}}
|
||||
<dt>{{$.i18n.Tr "admin.config.log_mode"}}</dt>
|
||||
<dd>{{.Name}} ({{.Provider}})</dd>
|
||||
<dt>{{$.i18n.Tr "admin.config.log_config"}}</dt>
|
||||
<dd><pre>{{.Config | JsonPrettyPrint}}</pre></dd>
|
||||
{{end}}
|
||||
{{else}}
|
||||
<dd>{{$.i18n.Tr "admin.config.routes_to_default_logger"}}</dd>
|
||||
{{if .Loggers.router.SubLogDescriptions}}
|
||||
<dd>{{$.i18n.Tr "admin.config.own_named_logger"}}</dd>
|
||||
{{range .Loggers.router.SubLogDescriptions}}
|
||||
<dt>{{$.i18n.Tr "admin.config.log_mode"}}</dt>
|
||||
<dd>{{.Name}} ({{.Provider}})</dd>
|
||||
<dt>{{$.i18n.Tr "admin.config.log_config"}}</dt>
|
||||
<dd><pre>{{.Config | JsonPrettyPrint}}</pre></dd>
|
||||
{{end}}
|
||||
{{else}}
|
||||
<dd>{{$.i18n.Tr "admin.config.go_log"}}</dd>
|
||||
<dd>{{$.i18n.Tr "admin.config.routes_to_default_logger"}}</dd>
|
||||
{{end}}
|
||||
{{end}}
|
||||
<div class="ui divider"></div>
|
||||
|
Loading…
Reference in New Issue
Block a user