mirror of
				https://github.com/home-assistant/supervisor.git
				synced 2025-11-04 08:29:40 +00:00 
			
		
		
		
	Compare commits
	
		
			2 Commits
		
	
	
		
			2023.11.4
			...
			remove-pas
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					de7ef86f52 | ||
| 
						 | 
					6f614c91d7 | 
@@ -358,7 +358,8 @@ class CIFSMount(NetworkMount):
 | 
			
		||||
    def options(self) -> list[str]:
 | 
			
		||||
        """Options to use to mount."""
 | 
			
		||||
        return (
 | 
			
		||||
            super().options + [f"username={self.username}", f"password={self.password}"]
 | 
			
		||||
            super().options
 | 
			
		||||
            + [f"username={self.username}", f"password='{self.password}'"]
 | 
			
		||||
            if self.username
 | 
			
		||||
            else []
 | 
			
		||||
        )
 | 
			
		||||
 
 | 
			
		||||
@@ -21,13 +21,12 @@ from .const import (
 | 
			
		||||
 | 
			
		||||
RE_MOUNT_NAME = re.compile(r"^\w+$")
 | 
			
		||||
RE_PATH_PART = re.compile(r"^[^\\\/]+")
 | 
			
		||||
RE_MOUNT_OPTION = re.compile(r"^[^,=]+$")
 | 
			
		||||
RE_MOUNT_OPTION = re.compile(r"^[^']+$")
 | 
			
		||||
 | 
			
		||||
VALIDATE_NAME = vol.Match(RE_MOUNT_NAME)
 | 
			
		||||
VALIDATE_SERVER = vol.Match(RE_PATH_PART)
 | 
			
		||||
VALIDATE_SHARE = vol.Match(RE_PATH_PART)
 | 
			
		||||
VALIDATE_USERNAME = vol.Match(RE_MOUNT_OPTION)
 | 
			
		||||
VALIDATE_PASSWORD = vol.Match(RE_MOUNT_OPTION)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
_SCHEMA_BASE_MOUNT_CONFIG = vol.Schema(
 | 
			
		||||
    {
 | 
			
		||||
@@ -49,8 +48,8 @@ SCHEMA_MOUNT_CIFS = _SCHEMA_MOUNT_NETWORK.extend(
 | 
			
		||||
    {
 | 
			
		||||
        vol.Required(ATTR_TYPE): MountType.CIFS.value,
 | 
			
		||||
        vol.Required(ATTR_SHARE): VALIDATE_SHARE,
 | 
			
		||||
        vol.Inclusive(ATTR_USERNAME, "basic_auth"): VALIDATE_USERNAME,
 | 
			
		||||
        vol.Inclusive(ATTR_PASSWORD, "basic_auth"): VALIDATE_PASSWORD,
 | 
			
		||||
        vol.Inclusive(ATTR_USERNAME, "basic_auth"): vol.Match(RE_MOUNT_OPTION),
 | 
			
		||||
        vol.Inclusive(ATTR_PASSWORD, "basic_auth"): vol.Match(RE_MOUNT_OPTION),
 | 
			
		||||
    }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@ async def test_cifs_mount(
 | 
			
		||||
        "server": "test.local",
 | 
			
		||||
        "share": "camera",
 | 
			
		||||
        "username": "admin",
 | 
			
		||||
        "password": "password",
 | 
			
		||||
        "password": "p@assword!,=",
 | 
			
		||||
    }
 | 
			
		||||
    mount: CIFSMount = Mount.from_dict(coresys, mount_data)
 | 
			
		||||
 | 
			
		||||
@@ -54,7 +54,7 @@ async def test_cifs_mount(
 | 
			
		||||
    assert mount.what == "//test.local/camera"
 | 
			
		||||
    assert mount.where == Path("/mnt/data/supervisor/mounts/test")
 | 
			
		||||
    assert mount.local_where == tmp_supervisor_data / "mounts" / "test"
 | 
			
		||||
    assert mount.options == ["username=admin", "password=password"]
 | 
			
		||||
    assert mount.options == ["username=admin", "password='p@assword!,='"]
 | 
			
		||||
 | 
			
		||||
    assert not mount.local_where.exists()
 | 
			
		||||
    assert mount.to_dict(skip_secrets=False) == mount_data
 | 
			
		||||
@@ -73,7 +73,7 @@ async def test_cifs_mount(
 | 
			
		||||
            "mnt-data-supervisor-mounts-test.mount",
 | 
			
		||||
            "fail",
 | 
			
		||||
            [
 | 
			
		||||
                ["Options", Variant("s", "username=admin,password=password")],
 | 
			
		||||
                ["Options", Variant("s", "username=admin,password='p@assword!,='")],
 | 
			
		||||
                ["Type", Variant("s", "cifs")],
 | 
			
		||||
                ["Description", Variant("s", "Supervisor cifs mount: test")],
 | 
			
		||||
                ["What", Variant("s", "//test.local/camera")],
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
"""Tests for mount manager validation."""
 | 
			
		||||
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
import pytest
 | 
			
		||||
from voluptuous import Invalid
 | 
			
		||||
 | 
			
		||||
@@ -15,6 +17,8 @@ async def test_valid_mounts():
 | 
			
		||||
            "type": "cifs",
 | 
			
		||||
            "server": "test.local",
 | 
			
		||||
            "share": "test",
 | 
			
		||||
            "username": "admin",
 | 
			
		||||
            "password": "p@assword!,=",
 | 
			
		||||
        }
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
@@ -77,12 +81,39 @@ async def test_invalid_cifs():
 | 
			
		||||
        SCHEMA_MOUNT_CONFIG(base)
 | 
			
		||||
 | 
			
		||||
    # Path is for NFS
 | 
			
		||||
    with pytest.raises(Invalid):
 | 
			
		||||
        SCHEMA_MOUNT_CONFIG({"path": "backups"})
 | 
			
		||||
    with pytest.raises(
 | 
			
		||||
        Invalid, match=re.escape("required key not provided @ data['share']")
 | 
			
		||||
    ):
 | 
			
		||||
        SCHEMA_MOUNT_CONFIG({**base, "path": "backups"})
 | 
			
		||||
 | 
			
		||||
    # Username and password must be together
 | 
			
		||||
    with pytest.raises(Invalid):
 | 
			
		||||
        SCHEMA_MOUNT_CONFIG({"username": "admin"})
 | 
			
		||||
    with pytest.raises(
 | 
			
		||||
        Invalid,
 | 
			
		||||
        match=re.escape(
 | 
			
		||||
            "some but not all values in the same group of inclusion 'basic_auth' @ data[<basic_auth>]"
 | 
			
		||||
        ),
 | 
			
		||||
    ):
 | 
			
		||||
        SCHEMA_MOUNT_CONFIG({**base, "share": "test", "username": "admin"})
 | 
			
		||||
 | 
			
		||||
    # Username and password must be together
 | 
			
		||||
    with pytest.raises(
 | 
			
		||||
        Invalid,
 | 
			
		||||
        match=re.escape(
 | 
			
		||||
            "some but not all values in the same group of inclusion 'basic_auth' @ data[<basic_auth>]"
 | 
			
		||||
        ),
 | 
			
		||||
    ):
 | 
			
		||||
        SCHEMA_MOUNT_CONFIG({**base, "share": "test", "password": "my=!pass"})
 | 
			
		||||
 | 
			
		||||
    # Invalid password
 | 
			
		||||
    with pytest.raises(
 | 
			
		||||
        Invalid,
 | 
			
		||||
        match=re.escape(
 | 
			
		||||
            "does not match regular expression ^[^']+$ for dictionary value @ data['password']"
 | 
			
		||||
        ),
 | 
			
		||||
    ):
 | 
			
		||||
        SCHEMA_MOUNT_CONFIG(
 | 
			
		||||
            {**base, "share": "test", "username": "admin", "password": "my=!pa'ss,"}
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_invalid_nfs():
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user