From c1b862394dff97327c8e95640d074889bbc79bb7 Mon Sep 17 00:00:00 2001 From: Nicola Murino Date: Sat, 19 Jun 2021 13:06:01 +0200 Subject: [PATCH] move other errors to utils package --- common/defender.go | 3 +-- dataprovider/bolt.go | 24 ++++++++++----------- dataprovider/dataprovider.go | 42 ++++++------------------------------ dataprovider/memory.go | 8 +++---- dataprovider/sqlcommon.go | 6 +++--- dataprovider/user.go | 2 +- ftpd/server.go | 2 +- httpd/api_utils.go | 6 +++--- httpd/internal_test.go | 2 +- httpd/webadmin.go | 18 ++++++++-------- sftpd/server.go | 2 +- utils/errors.go | 35 ++++++++++++++++++++++++++++++ webdavd/server.go | 2 +- 13 files changed, 79 insertions(+), 73 deletions(-) diff --git a/common/defender.go b/common/defender.go index c1252664..3a5889fa 100644 --- a/common/defender.go +++ b/common/defender.go @@ -12,7 +12,6 @@ import ( "github.com/yl2chen/cidranger" - "github.com/drakkan/sftpgo/dataprovider" "github.com/drakkan/sftpgo/logger" "github.com/drakkan/sftpgo/utils" ) @@ -280,7 +279,7 @@ func (d *memoryDefender) GetHost(ip string) (*DefenderEntry, error) { }, nil } - return nil, dataprovider.NewRecordNotFoundError("host not found") + return nil, utils.NewRecordNotFoundError("host not found") } // IsBanned returns true if the specified IP is banned diff --git a/dataprovider/bolt.go b/dataprovider/bolt.go index f68f9b24..8c60a697 100644 --- a/dataprovider/bolt.go +++ b/dataprovider/bolt.go @@ -160,7 +160,7 @@ func (p *BoltProvider) updateLastLogin(username string) error { } var u []byte if u = bucket.Get([]byte(username)); u == nil { - return &RecordNotFoundError{err: fmt.Sprintf("username %#v does not exist, unable to update last login", username)} + return utils.NewRecordNotFoundError(fmt.Sprintf("username %#v does not exist, unable to update last login", username)) } var user User err = json.Unmarshal(u, &user) @@ -190,7 +190,7 @@ func (p *BoltProvider) updateQuota(username string, filesAdd int, sizeAdd int64, } var u []byte if u = bucket.Get([]byte(username)); u == nil { - return &RecordNotFoundError{err: fmt.Sprintf("username %#v does not exist, unable to update quota", username)} + return utils.NewRecordNotFoundError(fmt.Sprintf("username %#v does not exist, unable to update quota", username)) } var user User err = json.Unmarshal(u, &user) @@ -235,7 +235,7 @@ func (p *BoltProvider) adminExists(username string) (Admin, error) { } a := bucket.Get([]byte(username)) if a == nil { - return &RecordNotFoundError{err: fmt.Sprintf("admin %v does not exist", username)} + return utils.NewRecordNotFoundError(fmt.Sprintf("admin %v does not exist", username)) } return json.Unmarshal(a, &admin) }) @@ -282,7 +282,7 @@ func (p *BoltProvider) updateAdmin(admin *Admin) error { var a []byte if a = bucket.Get([]byte(admin.Username)); a == nil { - return &RecordNotFoundError{err: fmt.Sprintf("admin %v does not exist", admin.Username)} + return utils.NewRecordNotFoundError(fmt.Sprintf("admin %v does not exist", admin.Username)) } var oldAdmin Admin err = json.Unmarshal(a, &oldAdmin) @@ -307,7 +307,7 @@ func (p *BoltProvider) deleteAdmin(admin *Admin) error { } if bucket.Get([]byte(admin.Username)) == nil { - return &RecordNotFoundError{err: fmt.Sprintf("admin %v does not exist", admin.Username)} + return utils.NewRecordNotFoundError(fmt.Sprintf("admin %v does not exist", admin.Username)) } return bucket.Delete([]byte(admin.Username)) @@ -397,7 +397,7 @@ func (p *BoltProvider) userExists(username string) (User, error) { } u := bucket.Get([]byte(username)) if u == nil { - return &RecordNotFoundError{err: fmt.Sprintf("username %#v does not exist", username)} + return utils.NewRecordNotFoundError(fmt.Sprintf("username %#v does not exist", username)) } folderBucket, err := getFoldersBucket(tx) if err != nil { @@ -465,7 +465,7 @@ func (p *BoltProvider) updateUser(user *User) error { } var u []byte if u = bucket.Get([]byte(user.Username)); u == nil { - return &RecordNotFoundError{err: fmt.Sprintf("username %#v does not exist", user.Username)} + return utils.NewRecordNotFoundError(fmt.Sprintf("username %#v does not exist", user.Username)) } var oldUser User err = json.Unmarshal(u, &oldUser) @@ -517,7 +517,7 @@ func (p *BoltProvider) deleteUser(user *User) error { } exists := bucket.Get([]byte(user.Username)) if exists == nil { - return &RecordNotFoundError{err: fmt.Sprintf("user %#v does not exist", user.Username)} + return utils.NewRecordNotFoundError(fmt.Sprintf("user %#v does not exist", user.Username)) } return bucket.Delete([]byte(user.Username)) }) @@ -722,7 +722,7 @@ func (p *BoltProvider) updateFolder(folder *vfs.BaseVirtualFolder) error { var f []byte if f = bucket.Get([]byte(folder.Name)); f == nil { - return &RecordNotFoundError{err: fmt.Sprintf("folder %v does not exist", folder.Name)} + return utils.NewRecordNotFoundError(fmt.Sprintf("folder %v does not exist", folder.Name)) } var oldFolder vfs.BaseVirtualFolder err = json.Unmarshal(f, &oldFolder) @@ -755,7 +755,7 @@ func (p *BoltProvider) deleteFolder(folder *vfs.BaseVirtualFolder) error { } var f []byte if f = bucket.Get([]byte(folder.Name)); f == nil { - return &RecordNotFoundError{err: fmt.Sprintf("folder %v does not exist", folder.Name)} + return utils.NewRecordNotFoundError(fmt.Sprintf("folder %v does not exist", folder.Name)) } var folder vfs.BaseVirtualFolder err = json.Unmarshal(f, &folder) @@ -801,7 +801,7 @@ func (p *BoltProvider) updateFolderQuota(name string, filesAdd int, sizeAdd int6 } var f []byte if f = bucket.Get([]byte(name)); f == nil { - return &RecordNotFoundError{err: fmt.Sprintf("folder %#v does not exist, unable to update quota", name)} + return utils.NewRecordNotFoundError(fmt.Sprintf("folder %#v does not exist, unable to update quota", name)) } var folder vfs.BaseVirtualFolder err = json.Unmarshal(f, &folder) @@ -910,7 +910,7 @@ func folderExistsInternal(name string, bucket *bolt.Bucket) (vfs.BaseVirtualFold var folder vfs.BaseVirtualFolder f := bucket.Get([]byte(name)) if f == nil { - err := &RecordNotFoundError{err: fmt.Sprintf("folder %v does not exist", name)} + err := utils.NewRecordNotFoundError(fmt.Sprintf("folder %v does not exist", name)) return folder, err } err := json.Unmarshal(f, &folder) diff --git a/dataprovider/dataprovider.go b/dataprovider/dataprovider.go index f7ba7917..9c820f04 100644 --- a/dataprovider/dataprovider.go +++ b/dataprovider/dataprovider.go @@ -366,34 +366,6 @@ type checkPasswordResponse struct { ToVerify string `json:"to_verify"` } -// MethodDisabledError raised if a method is disabled in config file. -// For example, if user management is disabled, this error is raised -// every time a user operation is done using the REST API -type MethodDisabledError struct { - err string -} - -// Method disabled error details -func (e *MethodDisabledError) Error() string { - return fmt.Sprintf("Method disabled error: %s", e.err) -} - -// RecordNotFoundError raised if a requested user is not found -type RecordNotFoundError struct { - err string -} - -func (e *RecordNotFoundError) Error() string { - return fmt.Sprintf("not found: %s", e.err) -} - -// NewRecordNotFoundError returns a not found error -func NewRecordNotFoundError(error string) *RecordNotFoundError { - return &RecordNotFoundError{ - err: error, - } -} - // GetQuotaTracking returns the configured mode for user's quota tracking func GetQuotaTracking() int { return config.TrackQuota @@ -808,7 +780,7 @@ func UpdateLastLogin(user *User) error { // If reset is true filesAdd and sizeAdd indicates the total files and the total size instead of the difference. func UpdateUserQuota(user *User, filesAdd int, sizeAdd int64, reset bool) error { if config.TrackQuota == 0 { - return &MethodDisabledError{err: trackQuotaDisabledError} + return utils.NewMethodDisabledError(trackQuotaDisabledError) } else if config.TrackQuota == 2 && !reset && !user.HasQuotaRestrictions() { return nil } @@ -829,7 +801,7 @@ func UpdateUserQuota(user *User, filesAdd int, sizeAdd int64, reset bool) error // If reset is true filesAdd and sizeAdd indicates the total files and the total size instead of the difference. func UpdateVirtualFolderQuota(vfolder *vfs.BaseVirtualFolder, filesAdd int, sizeAdd int64, reset bool) error { if config.TrackQuota == 0 { - return &MethodDisabledError{err: trackQuotaDisabledError} + return utils.NewMethodDisabledError(trackQuotaDisabledError) } if filesAdd == 0 && sizeAdd == 0 && !reset { return nil @@ -847,7 +819,7 @@ func UpdateVirtualFolderQuota(vfolder *vfs.BaseVirtualFolder, filesAdd int, size // GetUsedQuota returns the used quota for the given SFTP user. func GetUsedQuota(username string) (int, int64, error) { if config.TrackQuota == 0 { - return 0, 0, &MethodDisabledError{err: trackQuotaDisabledError} + return 0, 0, utils.NewMethodDisabledError(trackQuotaDisabledError) } files, size, err := provider.getUsedQuota(username) if err != nil { @@ -860,7 +832,7 @@ func GetUsedQuota(username string) (int, int64, error) { // GetUsedVirtualFolderQuota returns the used quota for the given virtual folder. func GetUsedVirtualFolderQuota(name string) (int, int64, error) { if config.TrackQuota == 0 { - return 0, 0, &MethodDisabledError{err: trackQuotaDisabledError} + return 0, 0, utils.NewMethodDisabledError(trackQuotaDisabledError) } files, size, err := provider.getUsedFolderQuota(name) if err != nil { @@ -2149,7 +2121,7 @@ func executePreLoginHook(username, loginMethod, ip, protocol string) (User, erro providerLog(logger.LevelDebug, "empty response from pre-login hook, no modification requested for user %#v id: %v", username, u.ID) if u.ID == 0 { - return u, &RecordNotFoundError{err: fmt.Sprintf("username %#v does not exist", username)} + return u, utils.NewRecordNotFoundError(fmt.Sprintf("username %#v does not exist", username)) } return u, nil } @@ -2345,7 +2317,7 @@ func doExternalAuth(username, password string, pubKey []byte, keyboardInteractiv providerLog(logger.LevelDebug, "empty response from external hook, no modification requested for user %#v id: %v", username, u.ID) if u.ID == 0 { - return u, &RecordNotFoundError{err: fmt.Sprintf("username %#v does not exist", username)} + return u, utils.NewRecordNotFoundError(fmt.Sprintf("username %#v does not exist", username)) } return u, nil } @@ -2389,7 +2361,7 @@ func getUserAndJSONForHook(username string) (User, []byte, error) { var userAsJSON []byte u, err := provider.userExists(username) if err != nil { - if _, ok := err.(*RecordNotFoundError); !ok { + if _, ok := err.(*utils.RecordNotFoundError); !ok { return u, userAsJSON, err } u = User{ diff --git a/dataprovider/memory.go b/dataprovider/memory.go index e611d2f1..c54235b6 100644 --- a/dataprovider/memory.go +++ b/dataprovider/memory.go @@ -367,7 +367,7 @@ func (p *MemoryProvider) userExistsInternal(username string) (User, error) { if val, ok := p.dbHandle.users[username]; ok { return val.getACopy(), nil } - return User{}, &RecordNotFoundError{err: fmt.Sprintf("username %#v does not exist", username)} + return User{}, utils.NewRecordNotFoundError(fmt.Sprintf("username %#v does not exist", username)) } func (p *MemoryProvider) addAdmin(admin *Admin) error { @@ -444,7 +444,7 @@ func (p *MemoryProvider) adminExistsInternal(username string) (Admin, error) { if val, ok := p.dbHandle.admins[username]; ok { return val.getACopy(), nil } - return Admin{}, &RecordNotFoundError{err: fmt.Sprintf("admin %#v does not exist", username)} + return Admin{}, utils.NewRecordNotFoundError(fmt.Sprintf("admin %#v does not exist", username)) } func (p *MemoryProvider) dumpAdmins() ([]Admin, error) { @@ -594,7 +594,7 @@ func (p *MemoryProvider) addOrUpdateFolderInternal(baseFolder *vfs.BaseVirtualFo p.updateFoldersMappingInternal(folder) return folder, nil } - if _, ok := err.(*RecordNotFoundError); ok { + if _, ok := err.(*utils.RecordNotFoundError); ok { folder = baseFolder.GetACopy() folder.ID = p.getNextFolderID() folder.UsedQuotaSize = usedQuotaSize @@ -611,7 +611,7 @@ func (p *MemoryProvider) folderExistsInternal(name string) (vfs.BaseVirtualFolde if val, ok := p.dbHandle.vfolders[name]; ok { return val, nil } - return vfs.BaseVirtualFolder{}, &RecordNotFoundError{err: fmt.Sprintf("folder %#v does not exist", name)} + return vfs.BaseVirtualFolder{}, utils.NewRecordNotFoundError(fmt.Sprintf("folder %#v does not exist", name)) } func (p *MemoryProvider) getFolders(limit, offset int, order string) ([]vfs.BaseVirtualFolder, error) { diff --git a/dataprovider/sqlcommon.go b/dataprovider/sqlcommon.go index b5f085b5..22d7ec73 100644 --- a/dataprovider/sqlcommon.go +++ b/dataprovider/sqlcommon.go @@ -494,7 +494,7 @@ func getAdminFromDbRow(row sqlScanner) (Admin, error) { if err != nil { if err == sql.ErrNoRows { - return admin, &RecordNotFoundError{err: err.Error()} + return admin, utils.NewRecordNotFoundError(err.Error()) } return admin, err } @@ -543,7 +543,7 @@ func getUserFromDbRow(row sqlScanner) (User, error) { &additionalInfo, &description) if err != nil { if err == sql.ErrNoRows { - return user, &RecordNotFoundError{err: err.Error()} + return user, utils.NewRecordNotFoundError(err.Error()) } return user, err } @@ -620,7 +620,7 @@ func sqlCommonGetFolder(ctx context.Context, name string, dbHandle sqlQuerier) ( err = row.Scan(&folder.ID, &mappedPath, &folder.UsedQuotaSize, &folder.UsedQuotaFiles, &folder.LastQuotaUpdate, &folder.Name, &description, &fsConfig) if err == sql.ErrNoRows { - return folder, &RecordNotFoundError{err: err.Error()} + return folder, utils.NewRecordNotFoundError(err.Error()) } if mappedPath.Valid { folder.MappedPath = mappedPath.String diff --git a/dataprovider/user.go b/dataprovider/user.go index eb85b15c..ee21dc3b 100644 --- a/dataprovider/user.go +++ b/dataprovider/user.go @@ -477,7 +477,7 @@ func (u *User) getForbiddenSFTPSelfUsers(username string) ([]string, error) { } return forbiddens, nil } - if _, ok := err.(*RecordNotFoundError); !ok { + if _, ok := err.(*utils.RecordNotFoundError); !ok { return nil, err } diff --git a/ftpd/server.go b/ftpd/server.go index 081bfaff..57b4ed7f 100644 --- a/ftpd/server.go +++ b/ftpd/server.go @@ -353,7 +353,7 @@ func updateLoginMetrics(user *dataprovider.User, ip, loginMethod string, err err logger.ConnectionFailedLog(user.Username, ip, loginMethod, common.ProtocolFTP, err.Error()) event := common.HostEventLoginFailed - if _, ok := err.(*dataprovider.RecordNotFoundError); ok { + if _, ok := err.(*utils.RecordNotFoundError); ok { event = common.HostEventUserNotFound } common.AddDefenderEvent(ip, event) diff --git a/httpd/api_utils.go b/httpd/api_utils.go index 50b7f52c..35407228 100644 --- a/httpd/api_utils.go +++ b/httpd/api_utils.go @@ -45,10 +45,10 @@ func getRespStatus(err error) int { if _, ok := err.(*utils.ValidationError); ok { return http.StatusBadRequest } - if _, ok := err.(*dataprovider.MethodDisabledError); ok { + if _, ok := err.(*utils.MethodDisabledError); ok { return http.StatusForbidden } - if _, ok := err.(*dataprovider.RecordNotFoundError); ok { + if _, ok := err.(*utils.RecordNotFoundError); ok { return http.StatusNotFound } if os.IsNotExist(err) { @@ -366,7 +366,7 @@ func updateLoginMetrics(user *dataprovider.User, ip string, err error) { if err != nil && err != common.ErrInternalFailure { logger.ConnectionFailedLog(user.Username, ip, dataprovider.LoginMethodPassword, common.ProtocolHTTP, err.Error()) event := common.HostEventLoginFailed - if _, ok := err.(*dataprovider.RecordNotFoundError); ok { + if _, ok := err.(*utils.RecordNotFoundError); ok { event = common.HostEventUserNotFound } common.AddDefenderEvent(ip, event) diff --git a/httpd/internal_test.go b/httpd/internal_test.go index e79cf053..daf37cbd 100644 --- a/httpd/internal_test.go +++ b/httpd/internal_test.go @@ -298,7 +298,7 @@ func TestShouldBind(t *testing.T) { func TestGetRespStatus(t *testing.T) { var err error - err = &dataprovider.MethodDisabledError{} + err = utils.NewMethodDisabledError("") respStatus := getRespStatus(err) assert.Equal(t, http.StatusForbidden, respStatus) err = fmt.Errorf("generic error") diff --git a/httpd/webadmin.go b/httpd/webadmin.go index b8a6502c..cc8deb62 100644 --- a/httpd/webadmin.go +++ b/httpd/webadmin.go @@ -1146,7 +1146,7 @@ func handleWebUpdateAdminGet(w http.ResponseWriter, r *http.Request) { admin, err := dataprovider.AdminExists(username) if err == nil { renderAddUpdateAdminPage(w, r, &admin, "", false) - } else if _, ok := err.(*dataprovider.RecordNotFoundError); ok { + } else if _, ok := err.(*utils.RecordNotFoundError); ok { renderNotFoundPage(w, r, err) } else { renderInternalServerErrorPage(w, r, err) @@ -1177,7 +1177,7 @@ func handleWebUpdateAdminPost(w http.ResponseWriter, r *http.Request) { username := getURLParam(r, "username") admin, err := dataprovider.AdminExists(username) - if _, ok := err.(*dataprovider.RecordNotFoundError); ok { + if _, ok := err.(*utils.RecordNotFoundError); ok { renderNotFoundPage(w, r, err) return } else if err != nil { @@ -1265,7 +1265,7 @@ func handleWebTemplateFolderGet(w http.ResponseWriter, r *http.Request) { folder, err := dataprovider.GetFolderByName(name) if err == nil { renderFolderPage(w, r, folder, folderPageModeTemplate, "") - } else if _, ok := err.(*dataprovider.RecordNotFoundError); ok { + } else if _, ok := err.(*utils.RecordNotFoundError); ok { renderNotFoundPage(w, r, err) } else { renderInternalServerErrorPage(w, r, err) @@ -1328,7 +1328,7 @@ func handleWebTemplateUserGet(w http.ResponseWriter, r *http.Request) { if err == nil { user.SetEmptySecrets() renderUserPage(w, r, &user, userPageModeTemplate, "") - } else if _, ok := err.(*dataprovider.RecordNotFoundError); ok { + } else if _, ok := err.(*utils.RecordNotFoundError); ok { renderNotFoundPage(w, r, err) } else { renderInternalServerErrorPage(w, r, err) @@ -1388,7 +1388,7 @@ func handleWebAddUserGet(w http.ResponseWriter, r *http.Request) { user.Password = "" user.SetEmptySecrets() renderUserPage(w, r, &user, userPageModeAdd, "") - } else if _, ok := err.(*dataprovider.RecordNotFoundError); ok { + } else if _, ok := err.(*utils.RecordNotFoundError); ok { renderNotFoundPage(w, r, err) } else { renderInternalServerErrorPage(w, r, err) @@ -1404,7 +1404,7 @@ func handleWebUpdateUserGet(w http.ResponseWriter, r *http.Request) { user, err := dataprovider.UserExists(username) if err == nil { renderUserPage(w, r, &user, userPageModeUpdate, "") - } else if _, ok := err.(*dataprovider.RecordNotFoundError); ok { + } else if _, ok := err.(*utils.RecordNotFoundError); ok { renderNotFoundPage(w, r, err) } else { renderInternalServerErrorPage(w, r, err) @@ -1434,7 +1434,7 @@ func handleWebUpdateUserPost(w http.ResponseWriter, r *http.Request) { r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize) username := getURLParam(r, "username") user, err := dataprovider.UserExists(username) - if _, ok := err.(*dataprovider.RecordNotFoundError); ok { + if _, ok := err.(*utils.RecordNotFoundError); ok { renderNotFoundPage(w, r, err) return } else if err != nil { @@ -1527,7 +1527,7 @@ func handleWebUpdateFolderGet(w http.ResponseWriter, r *http.Request) { folder, err := dataprovider.GetFolderByName(name) if err == nil { renderFolderPage(w, r, folder, folderPageModeUpdate, "") - } else if _, ok := err.(*dataprovider.RecordNotFoundError); ok { + } else if _, ok := err.(*utils.RecordNotFoundError); ok { renderNotFoundPage(w, r, err) } else { renderInternalServerErrorPage(w, r, err) @@ -1538,7 +1538,7 @@ func handleWebUpdateFolderPost(w http.ResponseWriter, r *http.Request) { r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize) name := getURLParam(r, "name") folder, err := dataprovider.GetFolderByName(name) - if _, ok := err.(*dataprovider.RecordNotFoundError); ok { + if _, ok := err.(*utils.RecordNotFoundError); ok { renderNotFoundPage(w, r, err) return } else if err != nil { diff --git a/sftpd/server.go b/sftpd/server.go index 79631892..37b078e2 100644 --- a/sftpd/server.go +++ b/sftpd/server.go @@ -845,7 +845,7 @@ func updateLoginMetrics(user *dataprovider.User, ip, method string, err error) { // record failed login key auth only once for session if the // authentication fails in checkAuthError event := common.HostEventLoginFailed - if _, ok := err.(*dataprovider.RecordNotFoundError); ok { + if _, ok := err.(*utils.RecordNotFoundError); ok { event = common.HostEventUserNotFound } common.AddDefenderEvent(ip, event) diff --git a/utils/errors.go b/utils/errors.go index 8b73bfc4..c974dbd4 100644 --- a/utils/errors.go +++ b/utils/errors.go @@ -18,3 +18,38 @@ func NewValidationError(error string) *ValidationError { err: error, } } + +// RecordNotFoundError raised if a requested user is not found +type RecordNotFoundError struct { + err string +} + +func (e *RecordNotFoundError) Error() string { + return fmt.Sprintf("not found: %s", e.err) +} + +// NewRecordNotFoundError returns a not found error +func NewRecordNotFoundError(error string) *RecordNotFoundError { + return &RecordNotFoundError{ + err: error, + } +} + +// MethodDisabledError raised if a method is disabled in config file. +// For example, if user management is disabled, this error is raised +// every time a user operation is done using the REST API +type MethodDisabledError struct { + err string +} + +// Method disabled error details +func (e *MethodDisabledError) Error() string { + return fmt.Sprintf("Method disabled error: %s", e.err) +} + +// NewMethodDisabledError returns a method disabled error +func NewMethodDisabledError(error string) *MethodDisabledError { + return &MethodDisabledError{ + err: error, + } +} diff --git a/webdavd/server.go b/webdavd/server.go index 163d06ef..20a54dfc 100644 --- a/webdavd/server.go +++ b/webdavd/server.go @@ -370,7 +370,7 @@ func updateLoginMetrics(user *dataprovider.User, ip, loginMethod string, err err if err != nil && err != common.ErrInternalFailure { logger.ConnectionFailedLog(user.Username, ip, loginMethod, common.ProtocolWebDAV, err.Error()) event := common.HostEventLoginFailed - if _, ok := err.(*dataprovider.RecordNotFoundError); ok { + if _, ok := err.(*utils.RecordNotFoundError); ok { event = common.HostEventUserNotFound } common.AddDefenderEvent(ip, event)