Skip to content

Commit

Permalink
Merge branch 'main' into fds-add-vertical-even-partitioner
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-narozniak authored Dec 19, 2024
2 parents 157db54 + 08d02f0 commit 5464407
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 2 deletions.
47 changes: 45 additions & 2 deletions src/py/flwr/cli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,53 @@ def get_sha256_hash(file_path: Path) -> str:


def get_user_auth_config_path(root_dir: Path, federation: str) -> Path:
"""Return the path to the user auth config file."""
"""Return the path to the user auth config file.
Additionally, a `.gitignore` file will be created in the Flower directory to
include the `.credentials` folder to be excluded from git. If the `.gitignore`
file already exists, a warning will be displayed if the `.credentials` entry is
not found.
"""
# Locate the credentials directory
credentials_dir = root_dir.absolute() / FLWR_DIR / CREDENTIALS_DIR
abs_flwr_dir = root_dir.absolute() / FLWR_DIR
credentials_dir = abs_flwr_dir / CREDENTIALS_DIR
credentials_dir.mkdir(parents=True, exist_ok=True)

# Determine the absolute path of the Flower directory for .gitignore
gitignore_path = abs_flwr_dir / ".gitignore"
credential_entry = CREDENTIALS_DIR

try:
if gitignore_path.exists():
with open(gitignore_path, encoding="utf-8") as gitignore_file:
lines = gitignore_file.read().splitlines()

# Warn if .credentials is not already in .gitignore
if credential_entry not in lines:
typer.secho(
f"`.gitignore` exists, but `{credential_entry}` entry not found. "
"Consider adding it to your `.gitignore` to exclude Flower "
"credentials from git.",
fg=typer.colors.YELLOW,
bold=True,
)
else:
typer.secho(
f"Creating a new `.gitignore` with `{credential_entry}` entry...",
fg=typer.colors.BLUE,
)
# Create a new .gitignore with .credentials
with open(gitignore_path, "w", encoding="utf-8") as gitignore_file:
gitignore_file.write(f"{credential_entry}\n")
except Exception as err:
typer.secho(
"❌ An error occurred while handling `.gitignore.` "
f"Please check the permissions of `{gitignore_path}` and try again.",
fg=typer.colors.RED,
bold=True,
)
raise typer.Exit(code=1) from err

return credentials_dir / f"{federation}.json"


Expand Down
1 change: 1 addition & 0 deletions src/py/flwr/server/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ def run_superlink() -> None:
server_public_key,
) = maybe_keys
state = state_factory.state()
state.clear_supernode_auth_keys_and_credentials()
state.store_node_public_keys(node_public_keys)
state.store_server_private_public_key(
private_key_to_bytes(server_private_key),
Expand Down
7 changes: 7 additions & 0 deletions src/py/flwr/server/superlink/linkstate/in_memory_linkstate.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,13 @@ def get_server_public_key(self) -> Optional[bytes]:
"""Retrieve `server_public_key` in urlsafe bytes."""
return self.server_public_key

def clear_supernode_auth_keys_and_credentials(self) -> None:
"""Clear stored `node_public_keys` and credentials in the link state if any."""
with self.lock:
self.server_private_key = None
self.server_public_key = None
self.node_public_keys.clear()

def store_node_public_keys(self, public_keys: set[bytes]) -> None:
"""Store a set of `node_public_keys` in the link state."""
with self.lock:
Expand Down
4 changes: 4 additions & 0 deletions src/py/flwr/server/superlink/linkstate/linkstate.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,10 @@ def get_server_private_key(self) -> Optional[bytes]:
def get_server_public_key(self) -> Optional[bytes]:
"""Retrieve `server_public_key` in urlsafe bytes."""

@abc.abstractmethod
def clear_supernode_auth_keys_and_credentials(self) -> None:
"""Clear stored `node_public_keys` and credentials in the link state if any."""

@abc.abstractmethod
def store_node_public_keys(self, public_keys: set[bytes]) -> None:
"""Store a set of `node_public_keys` in the link state."""
Expand Down
23 changes: 23 additions & 0 deletions src/py/flwr/server/superlink/linkstate/linkstate_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,29 @@ def test_store_server_private_public_key_twice(self) -> None:
new_private_key_bytes, new_public_key_bytes
)

def test_clear_supernode_auth_keys_and_credentials(self) -> None:
"""Test clear_supernode_auth_keys_and_credentials from linkstate."""
# Prepare
state: LinkState = self.state_factory()
key_pairs = [generate_key_pairs() for _ in range(3)]
public_keys = {public_key_to_bytes(pair[1]) for pair in key_pairs}

# Execute (store)
state.store_node_public_keys(public_keys)
private_key, public_key = generate_key_pairs()
private_key_bytes = private_key_to_bytes(private_key)
public_key_bytes = public_key_to_bytes(public_key)
state.store_server_private_public_key(private_key_bytes, public_key_bytes)

# Execute (clear)
state.clear_supernode_auth_keys_and_credentials()
node_public_keys = state.get_node_public_keys()

# Assert
assert node_public_keys == set()
assert state.get_server_private_key() is None
assert state.get_server_public_key() is None

def test_node_public_keys(self) -> None:
"""Test store_node_public_keys and get_node_public_keys from state."""
# Prepare
Expand Down
6 changes: 6 additions & 0 deletions src/py/flwr/server/superlink/linkstate/sqlite_linkstate.py
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,12 @@ def get_server_public_key(self) -> Optional[bytes]:
public_key = None
return public_key

def clear_supernode_auth_keys_and_credentials(self) -> None:
"""Clear stored `node_public_keys` and credentials in the link state if any."""
queries = ["DELETE FROM public_key;", "DELETE FROM credential;"]
for query in queries:
self.query(query)

def store_node_public_keys(self, public_keys: set[bytes]) -> None:
"""Store a set of `node_public_keys` in the link state."""
query = "INSERT INTO public_key (public_key) VALUES (?)"
Expand Down

0 comments on commit 5464407

Please sign in to comment.