Repository: xanzy/go-gitlab
Pull request #1560 (2022-09-30 09:18:17)

Implement API to disable two factor authentication for user
implement api for [Disable two factor](https://docs.gitlab.com/ee/api/users.html#delete-authentication-identity-from-user)


Patch:
diff --git a/users.go b/users.go
index d03e7e1..f04acfb 100644
--- a/users.go
+++ b/users.go
@@ -26,14 +26,16 @@ import (
 
 // List a couple of standard errors.
 var (
-	ErrUserActivatePrevented   = errors.New("Cannot activate a user that is blocked by admin or by LDAP synchronization")
-	ErrUserApprovePrevented    = errors.New("Cannot approve a user that is blocked by admin or by LDAP synchronization")
-	ErrUserBlockPrevented      = errors.New("Cannot block a user that is already blocked by LDAP synchronization")
-	ErrUserConflict            = errors.New("User does not have a pending request")
-	ErrUserDeactivatePrevented = errors.New("Cannot deactivate a user that is blocked by admin or by LDAP synchronization")
-	ErrUserNotFound            = errors.New("User does not exist")
-	ErrUserRejectPrevented     = errors.New("Cannot reject a user if not authenticated as administrator")
-	ErrUserUnblockPrevented    = errors.New("Cannot unblock a user that is blocked by LDAP synchronization")
+	ErrUserActivatePrevented         = errors.New("Cannot activate a user that is blocked by admin or by LDAP synchronization")
+	ErrUserApprovePrevented          = errors.New("Cannot approve a user that is blocked by admin or by LDAP synchronization")
+	ErrUserBlockPrevented            = errors.New("Cannot block a user that is already blocked by LDAP synchronization")
+	ErrUserConflict                  = errors.New("User does not have a pending request")
+	ErrUserDeactivatePrevented       = errors.New("Cannot deactivate a user that is blocked by admin or by LDAP synchronization")
+	ErrUserDisableTwoFactorPrevented = errors.New("Cannot disable two factor authentication if not authenticated as administrator")
+	ErrUserNotFound                  = errors.New("User does not exist")
+	ErrUserRejectPrevented           = errors.New("Cannot reject a user if not authenticated as administrator")
+	ErrUserTwoFactorNotEnabled       = errors.New("Cannot disable two factor authentication if not enabled")
+	ErrUserUnblockPrevented          = errors.New("Cannot unblock a user that is blocked by LDAP synchronization")
 )
 
 // UsersService handles communication with the user related methods of
@@ -1338,3 +1340,34 @@ func (s *UsersService) GetUserMemberships(user int, opt *GetUserMembershipOption
 
 	return m, resp, err
 }
+
+// DisableTwoFactor disables two factor authentication for the specified user.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/users.html#disable-two-factor-authentication
+func (s *UsersService) DisableTwoFactor(user int, options ...RequestOptionFunc) error {
+	u := fmt.Sprintf("users/%d/disable_two_factor", user)
+
+	req, err := s.client.NewRequest(http.MethodPatch, u, nil, options)
+	if err != nil {
+		return err
+	}
+
+	resp, err := s.client.Do(req, nil)
+	if err != nil && resp == nil {
+		return err
+	}
+
+	switch resp.StatusCode {
+	case 204:
+		return nil
+	case 400:
+		return ErrUserTwoFactorNotEnabled
+	case 403:
+		return ErrUserDisableTwoFactorPrevented
+	case 404:
+		return ErrUserNotFound
+	default:
+		return fmt.Errorf("Received unexpected result code: %d", resp.StatusCode)
+	}
+}


Test patch:
diff --git a/users_test.go b/users_test.go
index 3a388e0..380255b 100644
--- a/users_test.go
+++ b/users_test.go
@@ -649,3 +649,19 @@ func TestGetSingleSSHKeyForUser(t *testing.T) {
 		t.Errorf("Users.GetSSHKeyForUser returned %+v, want %+v", sshKey, want)
 	}
 }
+
+func TestDisableUser2FA(t *testing.T) {
+	mux, server, client := setup(t)
+	defer teardown(server)
+
+	path := fmt.Sprintf("/%susers/1/disable_two_factor", apiVersionPath)
+	mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, http.MethodPatch)
+		w.WriteHeader(http.StatusNoContent)
+	})
+
+	err := client.Users.DisableTwoFactor(1)
+	if err != nil {
+		t.Errorf("Users.DisableTwoFactor returned error: %v", err)
+	}
+}