Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

logout command to remove cached credentials #409

Merged
merged 1 commit into from
Oct 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/mopidy_spotify/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,15 @@
from mopidy_spotify.backend import SpotifyBackend

registry.add("backend", SpotifyBackend)

def get_command(self):
from .commands import SpotifyCommand

Check warning on line 55 in src/mopidy_spotify/__init__.py

View check run for this annotation

Codecov / codecov/patch

src/mopidy_spotify/__init__.py#L55

Added line #L55 was not covered by tests

return SpotifyCommand()

Check warning on line 57 in src/mopidy_spotify/__init__.py

View check run for this annotation

Codecov / codecov/patch

src/mopidy_spotify/__init__.py#L57

Added line #L57 was not covered by tests

@classmethod
def get_credentials_dir(cls, config):
data_dir = cls.get_data_dir(config)
credentials_dir = data_dir / "credentials-cache"
credentials_dir.mkdir(mode=0o700, exist_ok=True)
return credentials_dir
6 changes: 1 addition & 5 deletions src/mopidy_spotify/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,9 @@ class SpotifyPlaybackProvider(backend.PlaybackProvider):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._cache_location = Extension().get_cache_dir(self.backend._config)
self._data_location = Extension().get_data_dir(self.backend._config)
self._credentials_dir = Extension().get_credentials_dir(self.backend._config)
self._config = self.backend._config["spotify"]

self._credentials_dir = self._data_location / "credentials-cache"
if not self._credentials_dir.exists():
self._credentials_dir.mkdir(mode=0o700)

def on_source_setup(self, source):
source.set_property("bitrate", str(self._config["bitrate"]))
source.set_property("cache-credentials", self._credentials_dir)
Expand Down
38 changes: 38 additions & 0 deletions src/mopidy_spotify/commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import logging
import os
from pathlib import Path

from mopidy import commands

from mopidy_spotify import Extension

logger = logging.getLogger(__name__)


class SpotifyCommand(commands.Command):
def __init__(self):
super().__init__()
self.add_child("logout", LogoutCommand())

Check warning on line 15 in src/mopidy_spotify/commands.py

View check run for this annotation

Codecov / codecov/patch

src/mopidy_spotify/commands.py#L14-L15

Added lines #L14 - L15 were not covered by tests


class LogoutCommand(commands.Command):
help = "Logout from Spotify account."

def run(self, _args, config):
credentials_dir = Extension().get_credentials_dir(config)
try:
for root, dirs, files in os.walk(credentials_dir, topdown=False):
root_path = Path(root)
for name in files:
file_path = root_path / name
file_path.unlink()
logger.debug(f"Removed file {file_path}")
for name in dirs:
dir_path = root_path / name
dir_path.rmdir()
logger.debug(f"Removed directory {dir_path}")
credentials_dir.rmdir()
except Exception as error:
logger.warning(f"Failed to logout from Spotify: {error}")

Check warning on line 36 in src/mopidy_spotify/commands.py

View check run for this annotation

Codecov / codecov/patch

src/mopidy_spotify/commands.py#L35-L36

Added lines #L35 - L36 were not covered by tests
else:
logger.info("Logout from Spotify complete")
kingosticks marked this conversation as resolved.
Show resolved Hide resolved
16 changes: 16 additions & 0 deletions tests/test_commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from unittest.mock import sentinel

from mopidy_spotify import Extension
from mopidy_spotify.commands import LogoutCommand


def test_logout_command(tmp_path):
config = {"core": {"data_dir": tmp_path}}
credentials_dir = Extension().get_credentials_dir(config)
(credentials_dir / "foo").mkdir()
(credentials_dir / "bar").touch()

cmd = LogoutCommand()
cmd.run(sentinel.args, config)

assert not credentials_dir.is_dir()
13 changes: 13 additions & 0 deletions tests/test_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,16 @@ def test_setup():
ext.setup(registry)

registry.add.assert_called_with("backend", backend_lib.SpotifyBackend)


def test_get_credentials_dir(tmp_path):
config = {"core": {"data_dir": tmp_path}}

ext = Extension()
result = ext.get_credentials_dir(config)
assert result == tmp_path / "spotify" / "credentials-cache"
assert result.is_dir()
assert result.stat().st_mode == 0o40700

result2 = ext.get_credentials_dir(config) # check exists_ok
assert result == result2