Merge branch 'main' of ssh://gitea.apps.sustainabledelivery.com:3022/QTIL/basic_signup_allowlist
This commit is contained in:
commit
73d41c0c9a
4
.mise.toml
Normal file
4
.mise.toml
Normal file
@ -0,0 +1,4 @@
|
||||
[tools]
|
||||
elixir = "1.18.3-otp-27"
|
||||
erlang = "27"
|
||||
node = "24"
|
||||
33
CLAUDE.md
Normal file
33
CLAUDE.md
Normal file
@ -0,0 +1,33 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Commands
|
||||
|
||||
- `mix compile` - Compile source files
|
||||
- `mix test` - Run all tests
|
||||
- `mix test test/path/to/test.exs` - Run a specific test file
|
||||
- `mix test test/path/to/test.exs:LINE` - Run a specific test at a line number
|
||||
- `mix deps.get` - Install dependencies
|
||||
- `mix clean` - Clean build artifacts
|
||||
|
||||
## Architecture
|
||||
|
||||
This is an Elixir library that provides email allowlist functionality for restricting account creation. The library consists of two main modules:
|
||||
|
||||
1. **BasicSignupAllowlist** (lib/basic_signup_allowlist.ex) - Public API module that reads the `SIGNUP_ALLOWLIST_EMAILS` environment variable and delegates to the functional core
|
||||
2. **FunCore.BasicSignupAllowlist** (lib/fun_core/basic_signup_allowlist.ex) - Pure functional core that handles the allowlist logic without side effects
|
||||
|
||||
The architecture follows a functional core/imperative shell pattern where:
|
||||
- The functional core contains pure functions for email normalization and allowlist checking
|
||||
- The outer module handles environment variable reading and provides the public interface
|
||||
|
||||
## Environment Variables
|
||||
|
||||
- `SIGNUP_ALLOWLIST_EMAILS` - Comma-separated list of allowed email addresses, or "*" to allow all emails
|
||||
|
||||
## Project Configuration
|
||||
|
||||
- Elixir version: ~> 1.18 (managed via mise)
|
||||
- No external dependencies currently
|
||||
- Test framework: ExUnit with async: false for integration tests that modify environment variables
|
||||
12
README.md
12
README.md
@ -1,21 +1,23 @@
|
||||
# BasicSignupWhitelist
|
||||
# BasicSignupAllowlist
|
||||
|
||||
**TODO: Add description**
|
||||
Minimal function to restrict account creation for the first few accounts. Useful for deploying architectural spikes and bootstrapping.
|
||||
|
||||
Why? Phx Auth offers easy account creation, but no UI to manage created accounts, allowing spammers to create accounts. When putting demoes live, you don't necessarily want to create elaborate account management and invite systems first.
|
||||
|
||||
## Installation
|
||||
|
||||
If [available in Hex](https://hex.pm/docs/publish), the package can be installed
|
||||
by adding `basic_signup_whitelist` to your list of dependencies in `mix.exs`:
|
||||
by adding `basic_signup_allow` to your list of dependencies in `mix.exs`:
|
||||
|
||||
```elixir
|
||||
def deps do
|
||||
[
|
||||
{:basic_signup_whitelist, "~> 0.1.0"}
|
||||
{:basic_signup_allowlist, "~> 0.1.0"}
|
||||
]
|
||||
end
|
||||
```
|
||||
|
||||
Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
|
||||
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
|
||||
be found at <https://hexdocs.pm/basic_signup_whitelist>.
|
||||
be found at <https://hexdocs.pm/basic_signup_allowlist>.
|
||||
|
||||
|
||||
51
lib/basic_signup_allowlist.ex
Normal file
51
lib/basic_signup_allowlist.ex
Normal file
@ -0,0 +1,51 @@
|
||||
defmodule BasicSignupAllowlist do
|
||||
import FunCore.BasicSignupAllowlist
|
||||
|
||||
@signup_allowlist_emails "SIGNUP_ALLOWLIST_EMAILS"
|
||||
|
||||
@moduledoc """
|
||||
Checks if an email address is allowed based on the SIGNUP_ALLOWLIST_EMAILS env variable.
|
||||
"""
|
||||
|
||||
@doc """
|
||||
Returns the name of the environment variable used for the signup allowlist.
|
||||
"""
|
||||
@spec signup_allowlist_emails() :: String.t()
|
||||
def signup_allowlist_emails, do: @signup_allowlist_emails
|
||||
|
||||
|
||||
@doc """
|
||||
Checks if an email address is allowed based on the SIGNUP_ALLOWLIST_EMAILS env variable.
|
||||
|
||||
Rules:
|
||||
- Returns true if ALLOWED_EMAILS == "*" (all emails allowed)
|
||||
- Returns true if email matches any entry in the comma-separated list
|
||||
- Returns false if:
|
||||
* Environment variable doesn't exist
|
||||
* Environment variable is empty string
|
||||
* Email not found in allowlist
|
||||
|
||||
## Examples
|
||||
|
||||
iex> BasicSignupAllowlist.forbid_signup_with_any_email()
|
||||
iex> BasicSignupAllowlist.signup_allowed?("joe@example.com")
|
||||
false
|
||||
iex> BasicSignupAllowlist.allow_signup_with_all_emails()
|
||||
iex> BasicSignupAllowlist.signup_allowed?("joe@example.com")
|
||||
true
|
||||
|
||||
"""
|
||||
@spec signup_allowed?(String.t()) :: boolean()
|
||||
def signup_allowed?(email) do
|
||||
env_value = System.get_env(@signup_allowlist_emails)
|
||||
signup_allowed_fun(env_value, email)
|
||||
end
|
||||
|
||||
def allow_signup_with_all_emails() do
|
||||
System.put_env(signup_allowlist_emails(), "*")
|
||||
end
|
||||
|
||||
def forbid_signup_with_any_email() do
|
||||
System.delete_env(signup_allowlist_emails())
|
||||
end
|
||||
end
|
||||
@ -1,33 +0,0 @@
|
||||
defmodule BasicSignupWhitelist do
|
||||
import FunCore.BasicSignupWhitelist
|
||||
|
||||
@moduledoc """
|
||||
Checks if an email address is allowed based on the SIGNUP_ALLOWED_EMAILS env variable.
|
||||
"""
|
||||
|
||||
@doc """
|
||||
Checks if an email address is allowed based on the SIGNUP_ALLOWED_EMAILS env variable.
|
||||
|
||||
Rules:
|
||||
- Returns true if ALLOWED_EMAILS == "*" (all emails allowed)
|
||||
- Returns true if email matches any entry in the comma-separated list
|
||||
- Returns false if:
|
||||
* Environment variable doesn't exist
|
||||
* Environment variable is empty string
|
||||
* Email not found in whitelist
|
||||
|
||||
## Examples
|
||||
|
||||
iex> System.delete_env("SIGNUP_ALLOWED_EMAILS")
|
||||
iex> BasicSignupWhitelist.mail_whitelisted("joe@example.com")
|
||||
false
|
||||
iex> System.put_env("SIGNUP_ALLOWED_EMAILS","*")
|
||||
iex> BasicSignupWhitelist.mail_whitelisted("joe@example.com")
|
||||
true
|
||||
|
||||
"""
|
||||
def mail_whitelisted(email) do
|
||||
env_value = System.get_env("SIGNUP_ALLOWED_EMAILS")
|
||||
mail_whitelisted_fun(env_value, email)
|
||||
end
|
||||
end
|
||||
35
lib/fun_core/basic_signup_allowlist.ex
Normal file
35
lib/fun_core/basic_signup_allowlist.ex
Normal file
@ -0,0 +1,35 @@
|
||||
defmodule FunCore.BasicSignupAllowlist do
|
||||
@moduledoc """
|
||||
Functional core for email allowlist checking logic.
|
||||
"""
|
||||
|
||||
@doc """
|
||||
Normalizes an email address by trimming whitespace and converting to lowercase.
|
||||
"""
|
||||
@spec normalize(String.t()) :: String.t()
|
||||
def normalize(email) do
|
||||
email |> String.trim() |> String.downcase()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Converts a comma-separated string of email addresses into a normalized list.
|
||||
"""
|
||||
@spec addresses_as_list(String.t()) :: [String.t()]
|
||||
def addresses_as_list(addresses_str) do
|
||||
addresses_str
|
||||
|> String.split(",")
|
||||
|> Enum.map(&normalize/1)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Checks if an email is allowed based on the allowlist configuration.
|
||||
"""
|
||||
@spec signup_allowed_fun(String.t() | nil, String.t()) :: boolean()
|
||||
def signup_allowed_fun(signups_allowed, email_received) do
|
||||
case signups_allowed do
|
||||
nil -> false
|
||||
"*" -> true
|
||||
list_str -> normalize(email_received) in addresses_as_list(list_str)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,19 +0,0 @@
|
||||
defmodule FunCore.BasicSignupWhitelist do
|
||||
def normalize(email) do
|
||||
email |> String.trim() |> String.downcase()
|
||||
end
|
||||
|
||||
def addresses_as_list(addresses_str) do
|
||||
addresses_str
|
||||
|> String.split(",")
|
||||
|> Enum.map(&normalize/1)
|
||||
end
|
||||
|
||||
def mail_whitelisted_fun(signups_allowed, email_received) do
|
||||
case signups_allowed do
|
||||
nil -> false
|
||||
"*" -> true
|
||||
list_str -> normalize(email_received) in addresses_as_list(list_str)
|
||||
end
|
||||
end
|
||||
end
|
||||
4
mix.exs
4
mix.exs
@ -1,9 +1,9 @@
|
||||
defmodule BasicSignupWhitelist.MixProject do
|
||||
defmodule BasicSignupAllowlist.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :basic_signup_whitelist,
|
||||
app: :basic_signup_allowlist,
|
||||
version: "0.1.0",
|
||||
elixir: "~> 1.18",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
|
||||
110
plan.md
110
plan.md
@ -1,17 +1,17 @@
|
||||
# whitelist sketch
|
||||
# allowlist sketch
|
||||
|
||||
Here's a complete Mix project structure with the email whitelist functionality and tests:
|
||||
Here's a complete Mix project structure with the email allowlist functionality and tests:
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
email_whitelist_test/
|
||||
email_allowlist_test/
|
||||
├── config
|
||||
│ └── config.exs
|
||||
├── lib
|
||||
│ └── email_whitelist.ex
|
||||
│ └── email_allowlist.ex
|
||||
├── test
|
||||
│ ├── email_whitelist_test.exs
|
||||
│ ├── email_allowlist_test.exs
|
||||
│ └── test_helper.exs
|
||||
├── mix.exs
|
||||
└── README.md
|
||||
@ -25,7 +25,7 @@ defmodule EmailWhitelistTest.MixProject do
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :email_whitelist_test,
|
||||
app: :email_allowlist_test,
|
||||
version: "0.1.0",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
@ -47,11 +47,11 @@ end
|
||||
import Config
|
||||
|
||||
# Configure your application
|
||||
config :email_whitelist_test, :allowed_emails,
|
||||
config :email_allowlist_test, :allowed_emails,
|
||||
["user@domain.com", "admin@example.org"]
|
||||
```
|
||||
|
||||
## 3. `lib/email_whitelist.ex` - Main Implementation
|
||||
## 3. `lib/email_allowlist.ex` - Main Implementation
|
||||
|
||||
```elixir
|
||||
defmodule EmailWhitelist do
|
||||
@ -64,10 +64,10 @@ defmodule EmailWhitelist do
|
||||
- Returns false if:
|
||||
* Environment variable doesn't exist
|
||||
* Environment variable is empty string
|
||||
* Email not found in whitelist
|
||||
* Email not found in allowlist
|
||||
"""
|
||||
|
||||
def mail_whitelisted(email) do
|
||||
def mail_allowlisted(email) do
|
||||
normalized_email = String.downcase(email)
|
||||
env_var = System.get_env("ALLOWED_EMAILS")
|
||||
|
||||
@ -94,13 +94,13 @@ end
|
||||
ExUnit.start()
|
||||
```
|
||||
|
||||
## 5. `test/email_whitelist_test.exs` - Test Cases
|
||||
## 5. `test/email_allowlist_test.exs` - Test Cases
|
||||
|
||||
```elixir
|
||||
defmodule EmailWhitelistTest do
|
||||
use ExUnit.Case, async: true
|
||||
|
||||
describe "mail_whitelisted/1" do
|
||||
describe "mail_allowlisted/1" do
|
||||
setup do
|
||||
# Save original env var
|
||||
original_env = System.get_env("ALLOWED_EMAILS")
|
||||
@ -119,59 +119,59 @@ defmodule EmailWhitelistTest do
|
||||
test "allows all emails when ALLOWED_EMAILS is '*'" do
|
||||
System.put_env("ALLOWED_EMAILS", "*")
|
||||
|
||||
assert EmailWhitelist.mail_whitelisted("any@example.com") == true
|
||||
assert EmailWhitelist.mail_whitelisted("user@domain.com") == true
|
||||
assert EmailWhitelist.mail_whitelisted("test@test.co.uk") == true
|
||||
assert EmailWhitelist.mail_allowlisted("any@example.com") == true
|
||||
assert EmailWhitelist.mail_allowlisted("user@domain.com") == true
|
||||
assert EmailWhitelist.mail_allowlisted("test@test.co.uk") == true
|
||||
end
|
||||
|
||||
test "allows whitelisted emails" do
|
||||
test "allows allowlisted emails" do
|
||||
System.put_env("ALLOWED_EMAILS", "user@domain.com,admin@example.org")
|
||||
|
||||
assert EmailWhitelist.mail_whitelisted("user@domain.com") == true
|
||||
assert EmailWhitelist.mail_whitelisted("ADMIN@EXAMPLE.ORG") == true
|
||||
assert EmailWhitelist.mail_whitelisted("User@Domain.Com") == true
|
||||
assert EmailWhitelist.mail_allowlisted("user@domain.com") == true
|
||||
assert EmailWhitelist.mail_allowlisted("ADMIN@EXAMPLE.ORG") == true
|
||||
assert EmailWhitelist.mail_allowlisted("User@Domain.Com") == true
|
||||
end
|
||||
|
||||
test "rejects non-whitelisted emails" do
|
||||
test "rejects non-allowlisted emails" do
|
||||
System.put_env("ALLOWED_EMAILS", "user@domain.com,admin@example.org")
|
||||
|
||||
assert EmailWhitelist.mail_whitelisted("invalid@example.com") == false
|
||||
assert EmailWhitelist.mail_whitelisted("test@test.co.uk") == false
|
||||
assert EmailWhitelist.mail_allowlisted("invalid@example.com") == false
|
||||
assert EmailWhitelist.mail_allowlisted("test@test.co.uk") == false
|
||||
end
|
||||
|
||||
test "rejects when ALLOWED_EMAILS is nil" do
|
||||
System.delete_env("ALLOWED_EMAILS")
|
||||
|
||||
assert EmailWhitelist.mail_whitelisted("any@example.com") == false
|
||||
assert EmailWhitelist.mail_allowlisted("any@example.com") == false
|
||||
end
|
||||
|
||||
test "rejects when ALLOWED_EMAILS is empty string" do
|
||||
System.put_env("ALLOWED_EMAILS", "")
|
||||
|
||||
assert EmailWhitelist.mail_whitelisted("any@example.com") == false
|
||||
assert EmailWhitelist.mail_allowlisted("any@example.com") == false
|
||||
end
|
||||
|
||||
test "handles whitespace in email list" do
|
||||
test "handles allowspace in email list" do
|
||||
System.put_env("ALLOWED_EMAILS", " user@domain.com , admin@example.org , test@test.co.uk ")
|
||||
|
||||
assert EmailWhitelist.mail_whitelisted("user@domain.com") == true
|
||||
assert EmailWhitelist.mail_whitelisted("ADMIN@EXAMPLE.ORG") == true
|
||||
assert EmailWhitelist.mail_whitelisted("test@test.co.uk") == true
|
||||
assert EmailWhitelist.mail_whitelisted("invalid@example.com") == false
|
||||
assert EmailWhitelist.mail_allowlisted("user@domain.com") == true
|
||||
assert EmailWhitelist.mail_allowlisted("ADMIN@EXAMPLE.ORG") == true
|
||||
assert EmailWhitelist.mail_allowlisted("test@test.co.uk") == true
|
||||
assert EmailWhitelist.mail_allowlisted("invalid@example.com") == false
|
||||
end
|
||||
|
||||
test "case insensitive matching works" do
|
||||
System.put_env("ALLOWED_EMAILS", "User@Domain.Com,ADMIN@EXAMPLE.ORG")
|
||||
|
||||
assert EmailWhitelist.mail_whitelisted("user@domain.com") == true
|
||||
assert EmailWhitelist.mail_whitelisted("USER@DOMAIN.COM") == true
|
||||
assert EmailWhitelist.mail_whitelisted("admin@example.org") == true
|
||||
assert EmailWhitelist.mail_allowlisted("user@domain.com") == true
|
||||
assert EmailWhitelist.mail_allowlisted("USER@DOMAIN.COM") == true
|
||||
assert EmailWhitelist.mail_allowlisted("admin@example.org") == true
|
||||
end
|
||||
|
||||
test "empty email returns false" do
|
||||
System.put_env("ALLOWED_EMAILS", "user@domain.com")
|
||||
|
||||
assert EmailWhitelist.mail_whitelisted("") == false
|
||||
assert EmailWhitelist.mail_allowlisted("") == false
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -182,24 +182,24 @@ end
|
||||
```markdown
|
||||
# EmailWhitelistTest
|
||||
|
||||
A simple Mix project demonstrating email whitelist functionality.
|
||||
A simple Mix project demonstrating email allowlist functionality.
|
||||
|
||||
## Installation
|
||||
|
||||
If [available in Hex](https://hex.pm/docs/publish), the package can be installed
|
||||
by adding `email_whitelist_test` to your list of dependencies in `mix.exs`:
|
||||
by adding `email_allowlist_test` to your list of dependencies in `mix.exs`:
|
||||
|
||||
```elixir
|
||||
def deps do
|
||||
[
|
||||
{:email_whitelist_test, "~> 0.1.0"}
|
||||
{:email_allowlist_test, "~> 0.1.0"}
|
||||
]
|
||||
end
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
The main function is `EmailWhitelist.mail_whitelisted/1` which checks if an email address is allowed.
|
||||
The main function is `EmailWhitelist.mail_allowlisted/1` which checks if an email address is allowed.
|
||||
|
||||
Environment variable configuration:
|
||||
- `ALLOWED_EMAILS="*"` - Allow all emails
|
||||
@ -221,8 +221,8 @@ MIT
|
||||
|
||||
1. **Create the project structure:**
|
||||
```bash
|
||||
mkdir email_whitelist_test
|
||||
cd email_whitelist_test
|
||||
mkdir email_allowlist_test
|
||||
cd email_allowlist_test
|
||||
```
|
||||
|
||||
2. **Create all files with the content above**
|
||||
@ -251,7 +251,7 @@ Finished in 0.05 seconds (0.04s async, 0.01s sync)
|
||||
The tests cover all your specified requirements:
|
||||
- ✅ All emails allowed when `ALLOWED_EMAILS="*"`
|
||||
- ✅ Specific emails allowed when in list
|
||||
- ✅ Non-whitelisted emails rejected
|
||||
- ✅ Non-allowlisted emails rejected
|
||||
- ✅ Missing environment variable handled properly
|
||||
- ✅ Empty environment variable handled properly
|
||||
- ✅ Whitespace trimming in email lists
|
||||
@ -272,7 +272,7 @@ You can easily switch from a local path dependency to a git dependency by simply
|
||||
```elixir
|
||||
def deps do
|
||||
[
|
||||
{:email_whitelist_test, path: "../email_whitelist_test"}
|
||||
{:email_allowlist_test, path: "../email_allowlist_test"}
|
||||
]
|
||||
end
|
||||
```
|
||||
@ -281,7 +281,7 @@ end
|
||||
```elixir
|
||||
def deps do
|
||||
[
|
||||
{:email_whitelist_test, git: "https://github.com/yourusername/email_whitelist_test.git"}
|
||||
{:email_allowlist_test, git: "https://github.com/yourusername/email_allowlist_test.git"}
|
||||
]
|
||||
end
|
||||
```
|
||||
@ -292,7 +292,7 @@ After changing the dependency specification:
|
||||
|
||||
```bash
|
||||
# Remove the old dependency
|
||||
mix deps.clean email_whitelist_test
|
||||
mix deps.clean email_allowlist_test
|
||||
|
||||
# Fetch the new git dependency
|
||||
mix deps.get
|
||||
@ -302,21 +302,21 @@ mix deps.get
|
||||
|
||||
### Specify a Branch or Tag:
|
||||
```elixir
|
||||
{:email_whitelist_test,
|
||||
git: "https://github.com/yourusername/email_whitelist_test.git",
|
||||
{:email_allowlist_test,
|
||||
git: "https://github.com/yourusername/email_allowlist_test.git",
|
||||
branch: "main"}
|
||||
|
||||
# Or for a specific tag
|
||||
{:email_whitelist_test,
|
||||
git: "https://github.com/yourusername/email_whitelist_test.git",
|
||||
{:email_allowlist_test,
|
||||
git: "https://github.com/yourusername/email_allowlist_test.git",
|
||||
tag: "v1.0.0"}
|
||||
```
|
||||
|
||||
### For Private Repositories:
|
||||
```elixir
|
||||
{:email_whitelist_test,
|
||||
git: "https://github.com/yourusername/email_whitelist_test.git",
|
||||
github: "yourusername/email_whitelist_test",
|
||||
{:email_allowlist_test,
|
||||
git: "https://github.com/yourusername/email_allowlist_test.git",
|
||||
github: "yourusername/email_allowlist_test",
|
||||
branch: "main"}
|
||||
```
|
||||
|
||||
@ -326,7 +326,7 @@ mix deps.get
|
||||
```elixir
|
||||
def deps do
|
||||
[
|
||||
{:email_whitelist_test, path: "../email_whitelist_test"}
|
||||
{:email_allowlist_test, path: "../email_allowlist_test"}
|
||||
]
|
||||
end
|
||||
```
|
||||
@ -335,8 +335,8 @@ end
|
||||
```elixir
|
||||
def deps do
|
||||
[
|
||||
{:email_whitelist_test,
|
||||
git: "https://github.com/yourusername/email_whitelist_test.git",
|
||||
{:email_allowlist_test,
|
||||
git: "https://github.com/yourusername/email_allowlist_test.git",
|
||||
branch: "main"}
|
||||
]
|
||||
end
|
||||
@ -352,7 +352,7 @@ end
|
||||
## Important Notes:
|
||||
|
||||
- **No code changes needed** - your existing imports and usage remain identical
|
||||
- **Same module names** - `EmailWhitelist.mail_whitelisted/1` works the same
|
||||
- **Same module names** - `EmailWhitelist.mail_allowlisted/1` works the same
|
||||
- **Same function signatures** - no API changes required
|
||||
- **Cache cleared** - you'll need to run `mix deps.get` to fetch the new version
|
||||
|
||||
@ -360,7 +360,7 @@ end
|
||||
|
||||
```bash
|
||||
# Edit your mix.exs file, then:
|
||||
mix deps.clean email_whitelist_test
|
||||
mix deps.clean email_allowlist_test
|
||||
mix deps.get
|
||||
```
|
||||
|
||||
|
||||
102
rename_module.sh
Executable file
102
rename_module.sh
Executable file
@ -0,0 +1,102 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script to rename BasicSignupWhitelist module to BasicSignupAllowlist
|
||||
# This includes renaming files, module names, function names, and all references
|
||||
# Works recursively through all subdirectories
|
||||
|
||||
echo "Starting module rename from Whitelist to Allowlist..."
|
||||
echo ""
|
||||
|
||||
# Counter for renamed files
|
||||
renamed_count=0
|
||||
|
||||
# 1. Find and rename ALL files containing "whitelist" recursively
|
||||
echo "Finding and renaming files recursively..."
|
||||
echo "----------------------------------------"
|
||||
|
||||
# Use find to locate all files with whitelist in the name
|
||||
# Process deepest files first to avoid path issues
|
||||
while IFS= read -r -d '' file; do
|
||||
dir=$(dirname "$file")
|
||||
filename=$(basename "$file")
|
||||
newname="${filename//whitelist/allowlist}"
|
||||
newname="${newname//Whitelist/Allowlist}"
|
||||
|
||||
if [ "$filename" != "$newname" ]; then
|
||||
mv "$file" "$dir/$newname"
|
||||
echo " ✓ Renamed: $file → $dir/$newname"
|
||||
((renamed_count++))
|
||||
fi
|
||||
done < <(find . -type f \( -name "*whitelist*" -o -name "*Whitelist*" \) \( -name "*.ex" -o -name "*.exs" \) -print0 | sort -zr)
|
||||
|
||||
if [ $renamed_count -eq 0 ]; then
|
||||
echo " No files needed renaming"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# 2. Replace all occurrences of BasicSignupWhitelist with BasicSignupAllowlist
|
||||
echo "Updating module names in all .ex and .exs files..."
|
||||
echo "---------------------------------------------------"
|
||||
find . -type f \( -name "*.ex" -o -name "*.exs" \) ! -path "./_build/*" ! -path "./deps/*" -exec sed -i 's/BasicSignupWhitelist/BasicSignupAllowlist/g' {} +
|
||||
echo " ✓ Updated module names from BasicSignupWhitelist to BasicSignupAllowlist"
|
||||
|
||||
# 3. Replace function names (mail_whitelisted -> mail_allowlisted)
|
||||
echo ""
|
||||
echo "Updating function names..."
|
||||
echo "--------------------------"
|
||||
find . -type f \( -name "*.ex" -o -name "*.exs" \) ! -path "./_build/*" ! -path "./deps/*" -exec sed -i 's/mail_whitelisted/mail_allowlisted/g' {} +
|
||||
echo " ✓ Updated function names from mail_whitelisted to mail_allowlisted"
|
||||
|
||||
# 4. Replace case-sensitive variations of whitelist/allowlist
|
||||
echo ""
|
||||
echo "Updating all whitelist references (case-sensitive)..."
|
||||
echo "-----------------------------------------------------"
|
||||
find . -type f \( -name "*.ex" -o -name "*.exs" \) ! -path "./_build/*" ! -path "./deps/*" -exec sed -i 's/whitelist/allowlist/g' {} +
|
||||
find . -type f \( -name "*.ex" -o -name "*.exs" \) ! -path "./_build/*" ! -path "./deps/*" -exec sed -i 's/Whitelist/Allowlist/g' {} +
|
||||
find . -type f \( -name "*.ex" -o -name "*.exs" \) ! -path "./_build/*" ! -path "./deps/*" -exec sed -i 's/WHITELIST/ALLOWLIST/g' {} +
|
||||
echo " ✓ Updated all case variations of whitelist to allowlist"
|
||||
|
||||
# 5. Update references in config files (mix.exs, README.md, etc.)
|
||||
echo ""
|
||||
echo "Updating references in configuration and documentation files..."
|
||||
echo "--------------------------------------------------------------"
|
||||
for file in mix.exs README.md CLAUDE.md .formatter.exs; do
|
||||
if [ -f "$file" ]; then
|
||||
sed -i 's/whitelist/allowlist/g' "$file"
|
||||
sed -i 's/Whitelist/Allowlist/g' "$file"
|
||||
sed -i 's/WHITELIST/ALLOWLIST/g' "$file"
|
||||
echo " ✓ Updated references in $file"
|
||||
fi
|
||||
done
|
||||
|
||||
# 6. Clean up old build artifacts
|
||||
echo ""
|
||||
echo "Cleaning up old build artifacts..."
|
||||
echo "----------------------------------"
|
||||
if [ -d "_build" ]; then
|
||||
# Find and remove directories with whitelist in the name
|
||||
find _build -type d -name "*whitelist*" -exec rm -rf {} + 2>/dev/null
|
||||
echo " ✓ Removed old build directories containing 'whitelist'"
|
||||
echo " Note: Run 'mix clean' and 'mix compile' to rebuild completely"
|
||||
else
|
||||
echo " No _build directory found"
|
||||
fi
|
||||
|
||||
# 7. Show summary of changes
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo "Module rename complete!"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
echo "Summary:"
|
||||
echo " - Renamed $renamed_count file(s)"
|
||||
echo " - Updated all module and function references"
|
||||
echo " - Cleaned build artifacts"
|
||||
echo ""
|
||||
echo "Recommended next steps:"
|
||||
echo " 1. Run 'mix clean' to clean all build artifacts"
|
||||
echo " 2. Run 'mix deps.get' if you have dependencies"
|
||||
echo " 3. Run 'mix compile --force' to recompile with new module names"
|
||||
echo " 4. Run 'mix test' to ensure all tests still pass"
|
||||
echo " 5. Commit these changes to version control"
|
||||
29
test/basic_signup_allowlist_test.exs
Normal file
29
test/basic_signup_allowlist_test.exs
Normal file
@ -0,0 +1,29 @@
|
||||
defmodule BasicSignupAllowlistTest do
|
||||
use ExUnit.Case, async: false
|
||||
doctest BasicSignupAllowlist
|
||||
|
||||
defp allow_signups_for(allowlist) do
|
||||
System.put_env(BasicSignupAllowlist.signup_allowlist_emails(), allowlist)
|
||||
end
|
||||
|
||||
describe "setup in describe block" do
|
||||
setup do
|
||||
on_exit(fn ->
|
||||
# resetting values did not work, so 'just' set it to the effect without this module configured.
|
||||
System.put_env(BasicSignupAllowlist.signup_allowlist_emails(), "*")
|
||||
end)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
test "When not set, not allowlisted" do
|
||||
System.delete_env(BasicSignupAllowlist.signup_allowlist_emails())
|
||||
refute BasicSignupAllowlist.signup_allowed?("joe@example.com")
|
||||
end
|
||||
|
||||
test "When set to star, allowlisted" do
|
||||
allow_signups_for("*")
|
||||
assert BasicSignupAllowlist.signup_allowed?("joe@example.com")
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,29 +0,0 @@
|
||||
defmodule BasicSignupWhitelistTest do
|
||||
use ExUnit.Case, async: false
|
||||
doctest BasicSignupWhitelist
|
||||
|
||||
defp allow_signups_for(whitelist) do
|
||||
System.put_env("SIGNUP_ALLOWED_EMAILS", whitelist)
|
||||
end
|
||||
|
||||
describe "setup in describe block" do
|
||||
setup do
|
||||
on_exit(fn ->
|
||||
# resetting values did not work, so 'just' set it to the effect without this module configured.
|
||||
System.put_env("SIGNUP_ALLOWED_EMAILS", "*")
|
||||
end)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
test "When not set, not whitelisted" do
|
||||
System.delete_env("SIGNUP_ALLOWED_EMAILS")
|
||||
refute BasicSignupWhitelist.mail_whitelisted("joe@example.com")
|
||||
end
|
||||
|
||||
test "When set to star, whitelisted" do
|
||||
allow_signups_for("*")
|
||||
assert BasicSignupWhitelist.mail_whitelisted("joe@example.com")
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,6 +1,6 @@
|
||||
defmodule FunCore.BasicSignupWhitelistTest do
|
||||
defmodule FunCore.BasicSignupAllowlistTest do
|
||||
use ExUnit.Case
|
||||
import FunCore.BasicSignupWhitelist
|
||||
import FunCore.BasicSignupAllowlist
|
||||
|
||||
test "addresses_as_list" do
|
||||
assert addresses_as_list("joe@example.com, jane@example.com") == [
|
||||
@ -14,27 +14,27 @@ defmodule FunCore.BasicSignupWhitelistTest do
|
||||
assert "jane@example.com" in lst
|
||||
end
|
||||
|
||||
describe "Not whitelisted when allowed list is" do
|
||||
describe "Not allowlisted when allowed list is" do
|
||||
test "not set" do
|
||||
refute(mail_whitelisted_fun(nil, "joe@example.com"))
|
||||
refute(signup_allowed_fun(nil, "joe@example.com"))
|
||||
end
|
||||
|
||||
test "empty" do
|
||||
refute(mail_whitelisted_fun("j", "joe@example.com"))
|
||||
refute(signup_allowed_fun("j", "joe@example.com"))
|
||||
end
|
||||
end
|
||||
|
||||
describe "Whitelisted when" do
|
||||
describe "Allowlisted when" do
|
||||
test "*" do
|
||||
assert(mail_whitelisted_fun("*", "jane@example.com"))
|
||||
assert(signup_allowed_fun("*", "jane@example.com"))
|
||||
end
|
||||
|
||||
test "Multiple set and one match" do
|
||||
assert(mail_whitelisted_fun("joe@example.com, jane@example.com", "jane@example.com"))
|
||||
assert(signup_allowed_fun("joe@example.com, jane@example.com", "jane@example.com"))
|
||||
end
|
||||
|
||||
test "Matches with different casings" do
|
||||
assert(mail_whitelisted_fun("joe@Example.com, jane@example.com", "Joe@example.com"))
|
||||
assert(signup_allowed_fun("joe@Example.com, jane@example.com", "Joe@example.com"))
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
x
Reference in New Issue
Block a user