diff --git a/pkg/routes/caldav/auth.go b/pkg/routes/caldav/auth.go index 8b9a9d4e..27391541 100644 --- a/pkg/routes/caldav/auth.go +++ b/pkg/routes/caldav/auth.go @@ -28,14 +28,15 @@ import ( ) func BasicAuth(username, password string, c echo.Context) (bool, error) { - creds := &user.Login{ + s := db.NewSession() + defer s.Close() + + credentials := &user.Login{ Username: username, Password: password, } - s := db.NewSession() - defer s.Close() - u, err := user.CheckUserCredentials(s, creds) - if err != nil && !user.IsErrWrongUsernameOrPassword(err) { + u, err := user.CheckUserCredentials(s, credentials) + if err != nil && !user.IsErrWrongUsernameOrPassword(err) && !user.IsErrAccountIsNotLocal(err) { log.Errorf("Error during basic auth for caldav: %v", err) return false, nil } diff --git a/pkg/user/error.go b/pkg/user/error.go index 089eef1b..88c4f576 100644 --- a/pkg/user/error.go +++ b/pkg/user/error.go @@ -452,3 +452,30 @@ func (err *ErrAccountDisabled) HTTPError() web.HTTPError { Message: "This account is disabled. Check your emails or ask your administrator.", } } + +// ErrAccountIsNotLocal represents a "AccountIsNotLocal" kind of error. +type ErrAccountIsNotLocal struct { + UserID int64 +} + +// IsErrAccountIsNotLocal checks if an error is a ErrAccountIsNotLocal. +func IsErrAccountIsNotLocal(err error) bool { + _, ok := err.(*ErrAccountIsNotLocal) + return ok +} + +func (err *ErrAccountIsNotLocal) Error() string { + return "Account is not local" +} + +// ErrCodeAccountIsNotLocal holds the unique world-error code of this error +const ErrCodeAccountIsNotLocal = 1021 + +// HTTPError holds the http error description +func (err *ErrAccountIsNotLocal) HTTPError() web.HTTPError { + return web.HTTPError{ + HTTPCode: http.StatusPreconditionFailed, + Code: ErrCodeAccountIsNotLocal, + Message: "This account is managed by a third-party authentication provider.", + } +} diff --git a/pkg/user/user.go b/pkg/user/user.go index 802fb27c..6224617e 100644 --- a/pkg/user/user.go +++ b/pkg/user/user.go @@ -314,6 +314,10 @@ func CheckUserCredentials(s *xorm.Session, u *Login) (*User, error) { return nil, ErrWrongUsernameOrPassword{} } + if user.Issuer != IssuerLocal { + return user, &ErrAccountIsNotLocal{UserID: user.ID} + } + // The user is invalid if they need to verify their email address if user.Status == StatusEmailConfirmationRequired { return &User{}, ErrEmailNotConfirmed{UserID: user.ID}