Login: allow basic users to reset password when LDAP or Auth Proxy is enabled (#52331)

This commit is contained in:
Krzysztof Dąbrowski 2022-08-08 07:12:39 +02:00 committed by GitHub
parent 62b4dbf52f
commit 2dab7ad890
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 51 additions and 43 deletions

View File

@ -19,9 +19,6 @@ func (hs *HTTPServer) SendResetPasswordEmail(c *models.ReqContext) response.Resp
if err := web.Bind(c.Req, &form); err != nil { if err := web.Bind(c.Req, &form); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err) return response.Error(http.StatusBadRequest, "bad request data", err)
} }
if setting.LDAPEnabled || setting.AuthProxyEnabled {
return response.Error(401, "Not allowed to reset password when LDAP or Auth Proxy is enabled", nil)
}
if setting.DisableLoginForm { if setting.DisableLoginForm {
return response.Error(401, "Not allowed to reset password when login form is disabled", nil) return response.Error(401, "Not allowed to reset password when login form is disabled", nil)
} }
@ -34,6 +31,19 @@ func (hs *HTTPServer) SendResetPasswordEmail(c *models.ReqContext) response.Resp
return response.Error(http.StatusOK, "Email sent", err) return response.Error(http.StatusOK, "Email sent", err)
} }
if usr.IsDisabled {
c.Logger.Info("Requested password reset for disabled user", "user", userQuery.LoginOrEmail)
return response.Error(http.StatusOK, "Email sent", nil)
}
getAuthQuery := models.GetAuthInfoQuery{UserId: usr.ID}
if err := hs.authInfoService.GetAuthInfo(c.Req.Context(), &getAuthQuery); err == nil {
authModule := getAuthQuery.Result.AuthModule
if authModule == models.AuthModuleLDAP || authModule == models.AuthModuleProxy {
return response.Error(401, "Not allowed to reset password for LDAP or Auth Proxy user", nil)
}
}
emailCmd := models.SendResetPasswordEmailCommand{User: usr} emailCmd := models.SendResetPasswordEmailCommand{User: usr}
if err := hs.NotificationService.SendResetPasswordEmail(c.Req.Context(), &emailCmd); err != nil { if err := hs.NotificationService.SendResetPasswordEmail(c.Req.Context(), &emailCmd); err != nil {
return response.Error(500, "Failed to send email", err) return response.Error(500, "Failed to send email", err)

View File

@ -383,9 +383,6 @@ func (hs *HTTPServer) ChangeUserPassword(c *models.ReqContext) response.Response
if err := web.Bind(c.Req, &cmd); err != nil { if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err) return response.Error(http.StatusBadRequest, "bad request data", err)
} }
if setting.LDAPEnabled || setting.AuthProxyEnabled {
return response.Error(400, "Not allowed to change password when LDAP or Auth Proxy is enabled", nil)
}
userQuery := user.GetUserByIDQuery{ID: c.UserId} userQuery := user.GetUserByIDQuery{ID: c.UserId}
@ -394,6 +391,14 @@ func (hs *HTTPServer) ChangeUserPassword(c *models.ReqContext) response.Response
return response.Error(500, "Could not read user from database", err) return response.Error(500, "Could not read user from database", err)
} }
getAuthQuery := models.GetAuthInfoQuery{UserId: user.ID}
if err := hs.authInfoService.GetAuthInfo(c.Req.Context(), &getAuthQuery); err == nil {
authModule := getAuthQuery.Result.AuthModule
if authModule == models.AuthModuleLDAP || authModule == models.AuthModuleProxy {
return response.Error(400, "Not allowed to reset password for LDAP or Auth Proxy user", nil)
}
}
passwordHashed, err := util.EncodePassword(cmd.OldPassword, user.Salt) passwordHashed, err := util.EncodePassword(cmd.OldPassword, user.Salt)
if err != nil { if err != nil {
return response.Error(500, "Failed to encode password", err) return response.Error(500, "Failed to encode password", err)
@ -491,6 +496,8 @@ func GetAuthProviderLabel(authModule string) string {
return "grafana.com" return "grafana.com"
case "auth.saml": case "auth.saml":
return "SAML" return "SAML"
case "authproxy":
return "Auth Proxy"
case "ldap", "": case "ldap", "":
return "LDAP" return "LDAP"
default: default:

View File

@ -11,6 +11,7 @@ import (
const ( const (
AuthModuleLDAP = "ldap" AuthModuleLDAP = "ldap"
AuthModuleProxy = "authproxy"
) )
type UserAuth struct { type UserAuth struct {

View File

@ -25,8 +25,6 @@ interface Props {
skipPasswordChange: Function; skipPasswordChange: Function;
login: (data: FormModel) => void; login: (data: FormModel) => void;
disableLoginForm: boolean; disableLoginForm: boolean;
ldapEnabled: boolean;
authProxyEnabled: boolean;
disableUserSignUp: boolean; disableUserSignUp: boolean;
isOauthEnabled: boolean; isOauthEnabled: boolean;
loginHint: string; loginHint: string;
@ -129,7 +127,7 @@ export class LoginCtrl extends PureComponent<Props, State> {
const { children } = this.props; const { children } = this.props;
const { isLoggingIn, isChangingPassword } = this.state; const { isLoggingIn, isChangingPassword } = this.state;
const { login, toGrafana, changePassword } = this; const { login, toGrafana, changePassword } = this;
const { loginHint, passwordHint, disableLoginForm, ldapEnabled, authProxyEnabled, disableUserSignUp } = config; const { loginHint, passwordHint, disableLoginForm, disableUserSignUp } = config;
return ( return (
<> <>
@ -138,8 +136,6 @@ export class LoginCtrl extends PureComponent<Props, State> {
loginHint, loginHint,
passwordHint, passwordHint,
disableLoginForm, disableLoginForm,
ldapEnabled,
authProxyEnabled,
disableUserSignUp, disableUserSignUp,
login, login,
isLoggingIn, isLoggingIn,

View File

@ -28,8 +28,6 @@ export const LoginPage: FC = () => {
{({ {({
loginHint, loginHint,
passwordHint, passwordHint,
ldapEnabled,
authProxyEnabled,
disableLoginForm, disableLoginForm,
disableUserSignUp, disableUserSignUp,
login, login,
@ -48,7 +46,6 @@ export const LoginPage: FC = () => {
passwordHint={passwordHint} passwordHint={passwordHint}
isLoggingIn={isLoggingIn} isLoggingIn={isLoggingIn}
> >
{!(ldapEnabled || authProxyEnabled) ? (
<HorizontalGroup justify="flex-end"> <HorizontalGroup justify="flex-end">
<LinkButton <LinkButton
className={forgottenPasswordStyles} className={forgottenPasswordStyles}
@ -58,9 +55,6 @@ export const LoginPage: FC = () => {
Forgot your password? Forgot your password?
</LinkButton> </LinkButton>
</HorizontalGroup> </HorizontalGroup>
) : (
<></>
)}
</LoginForm> </LoginForm>
)} )}
<LoginServiceButtons /> <LoginServiceButtons />

View File

@ -16,11 +16,11 @@ export interface Props {
} }
export const ChangePasswordForm: FC<Props> = ({ user, onChangePassword, isSaving }) => { export const ChangePasswordForm: FC<Props> = ({ user, onChangePassword, isSaving }) => {
const { ldapEnabled, authProxyEnabled, disableLoginForm } = config; const { disableLoginForm } = config;
const authSource = user.authLabels?.length && user.authLabels[0]; const authSource = user.authLabels?.length && user.authLabels[0];
if (ldapEnabled || authProxyEnabled) { if (authSource === 'LDAP' || authSource === 'Auth Proxy') {
return <p>You cannot change password when LDAP or auth proxy authentication is enabled.</p>; return <p>You cannot change password when signed in with LDAP or auth proxy.</p>;
} }
if (authSource && disableLoginForm) { if (authSource && disableLoginForm) {
return <p>Password cannot be changed here.</p>; return <p>Password cannot be changed here.</p>;

View File

@ -84,19 +84,19 @@ describe('ChangePasswordPage', () => {
); );
}); });
}); });
it('should cannot change password form if ldap or authProxy enabled', async () => { it('should cannot change password form if user signed in with LDAP', async () => {
config.ldapEnabled = true; await getTestContext({
const { rerender } = await getTestContext(); user: { ...defaultProps.user!, authLabels: ['LDAP'] },
expect( });
screen.getByText('You cannot change password when LDAP or auth proxy authentication is enabled.')
).toBeInTheDocument(); expect(screen.getByText('You cannot change password when signed in with LDAP or auth proxy.')).toBeInTheDocument();
config.ldapEnabled = false; });
config.authProxyEnabled = true; it('should cannot change password form if user signed in with auth proxy', async () => {
rerender(<ChangePasswordPage {...defaultProps} />); await getTestContext({
expect( user: { ...defaultProps.user!, authLabels: ['Auth Proxy'] },
screen.getByText('You cannot change password when LDAP or auth proxy authentication is enabled.') });
).toBeInTheDocument();
config.authProxyEnabled = false; expect(screen.getByText('You cannot change password when signed in with LDAP or auth proxy.')).toBeInTheDocument();
}); });
it('should show cannot change password if disableLoginForm is true and auth', async () => { it('should show cannot change password if disableLoginForm is true and auth', async () => {
config.disableLoginForm = true; config.disableLoginForm = true;