Skip to content

Commit

Permalink
feat: Optionally disable username and password login (#487)
Browse files Browse the repository at this point in the history
  • Loading branch information
TomBursch authored Aug 5, 2024
1 parent c38cf4d commit 2bc0aa7
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 58 deletions.
1 change: 1 addition & 0 deletions backend/app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@

PRIVACY_POLICY_URL = os.getenv("PRIVACY_POLICY_URL")
OPEN_REGISTRATION = os.getenv("OPEN_REGISTRATION", "False").lower() == "true"
DISABLE_USERNAME_PASSWORD_LOGIN = os.getenv("DISABLE_USERNAME_PASSWORD_LOGIN", "False").lower() == "true"
EMAIL_MANDATORY = os.getenv("EMAIL_MANDATORY", "False").lower() == "true"

COLLECT_METRICS = os.getenv("COLLECT_METRICS", "False").lower() == "true"
Expand Down
54 changes: 28 additions & 26 deletions backend/app/controller/auth/auth_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from app.errors import NotFoundRequest, UnauthorizedRequest, InvalidUsage
from app.service import mail
from .schemas import Login, Signup, CreateLongLivedToken, GetOIDCLoginUrl, LoginOIDC
from app.config import EMAIL_MANDATORY, FRONT_URL, jwt, OPEN_REGISTRATION, oidc_clients
from app.config import EMAIL_MANDATORY, FRONT_URL, jwt, OPEN_REGISTRATION, DISABLE_USERNAME_PASSWORD_LOGIN, oidc_clients

auth = Blueprint("auth", __name__)

Expand Down Expand Up @@ -46,37 +46,39 @@ def user_lookup_callback(_jwt_header, jwt_data) -> User:
return User.find_by_id(identity)


@auth.route("", methods=["POST"])
@validate_args(Login)
def login(args):
username = args["username"].lower().replace(" ", "")
user = User.find_by_username(username)
if not user or not user.check_password(args["password"]):
raise UnauthorizedRequest(
message="Unauthorized: IP {} login attemp with wrong username or password".format(
request.remote_addr
if not DISABLE_USERNAME_PASSWORD_LOGIN:

@auth.route("", methods=["POST"])
@validate_args(Login)
def login(args):
username = args["username"].lower().replace(" ", "")
user = User.find_by_username(username)
if not user or not user.check_password(args["password"]):
raise UnauthorizedRequest(
message="Unauthorized: IP {} login attemp with wrong username or password".format(
request.remote_addr
)
)
)
device = "Unkown"
if "device" in args:
device = args["device"]
device = "Unkown"
if "device" in args:
device = args["device"]

# Create refresh token
refreshToken, refreshModel = Token.create_refresh_token(user, device)
# Create refresh token
refreshToken, refreshModel = Token.create_refresh_token(user, device)

# Create first access token
accesssToken, _ = Token.create_access_token(user, refreshModel)
# Create first access token
accesssToken, _ = Token.create_access_token(user, refreshModel)

return jsonify(
{
"access_token": accesssToken,
"refresh_token": refreshToken,
"user": user.obj_to_dict(),
}
)
return jsonify(
{
"access_token": accesssToken,
"refresh_token": refreshToken,
"user": user.obj_to_dict(),
}
)


if OPEN_REGISTRATION:
if OPEN_REGISTRATION and not DISABLE_USERNAME_PASSWORD_LOGIN:

@auth.route("signup", methods=["POST"])
@validate_args(Signup)
Expand Down
67 changes: 35 additions & 32 deletions docs/docs/self-hosting/advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,42 +8,44 @@ There are three tags available: `latest`, `beta` and `dev`. `latest` is the most
Additionally, the releases are tagged, so you can always choose a specific version with `vX.X.X`.

### Backend

- Set up with OpenID Connect: [OIDC](./oidc.md)
- Set up with a PostgreSQL database: [docker-compose.yml](https://github.com/TomBursch/kitchenowl/blob/main/docker-compose-postgres.yml)

Environment variables for `tombursch/kitchenowl` and `tombursch/kitchenowl-backend`:

| Variable | Default | Description |
| ---------------------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `JWT_SECRET_KEY` | | |
| `FRONT_URL` | | Adds allow origin CORS header for the URL. If set, should exactly match KitchenOwl's URL including the schema (e.g. `https://app.kitchenowl.org`) |
| `PRIVACY_POLICY_URL` | | Allows to set a custom privacy policy for your server instance |
| `OPEN_REGISTRATION` | `false` | If set allows anyone to create an account on your server |
| `EMAIL_MANDATORY` | `false` | Makes the email a mandatory field when registering (Only relevant if `OPEN_REGISTRATION` is set) |
| `COLLECT_METRICS` | `false` | Enables a Prometheus metrics endpoint at `/metrics/`. If enabled can be reached over the frontend container on port 9100 (e.g. `front:9100/metrics/`) |
| `METRICS_USER` | `kitchenowl` | Metrics basic auth username |
| `METRICS_PASSWORD` | `ZqQtidgC5n3YXb` | Metrics basic auth password |
| `SKIP_UPGRADE_DEFAULT_ITEMS` | `false` | On every restart all default items are imported and updated in every household |
| `STORAGE_PATH` | `/data` | Images are stored in `STORAGE_PATH/upload` |
| `DB_DRIVER` | `sqlite` | Supported: `sqlite` and `postgresql` |
| `DB_HOST` | | |
| `DB_PORT` | | |
| `DB_NAME` | `STORAGE_PATH/database.db` | When the driver is `sqlite` this decides where to store the DB |
| `DB_USER` | | |
| `DB_PASSWORD` | | |
| `SMTP_HOST` | | You can connect to an SMTP server for sending password resets and verifying user emails. This not required. |
| `SMTP_PORT` | `465` | |
| `SMTP_USER` | | |
| `SMTP_PASS` | | |
| `SMTP_FROM` | | |
| `SMTP_REPLY_TO` | | |
| `OIDC_ISSUER` | | More about [OIDC](./oidc.md) |
| `OIDC_CLIENT_ID` | | |
| `OIDC_CLIENT_SECRET` | | |
| `APPLE_CLIENT_ID` | | |
| `APPLE_CLIENT_SECRET` | | |
| `GOOGLE_CLIENT_ID` | | |
| `GOOGLE_CLIENT_SECRET` | | |
| Variable | Default | Description |
| --------------------------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `JWT_SECRET_KEY` | | |
| `FRONT_URL` | | Adds allow origin CORS header for the URL. If set, should exactly match KitchenOwl's URL including the schema (e.g. `https://app.kitchenowl.org`) |
| `PRIVACY_POLICY_URL` | | Allows to set a custom privacy policy for your server instance |
| `DISABLE_USERNAME_PASSWORD_LOGIN` | `false` | If set, allows login only through OpenID Connect (OIDC). Be aware: this won't change the UI and automatically disables `OPEN_REGISTRATION` |
| `OPEN_REGISTRATION` | `false` | If set, allows anyone to create an account on your server |
| `EMAIL_MANDATORY` | `false` | Makes the email a mandatory field when registering (Only relevant if `OPEN_REGISTRATION` is set) |
| `COLLECT_METRICS` | `false` | Enables a Prometheus metrics endpoint at `/metrics/`. If enabled can be reached over the frontend container on port 9100 (e.g. `front:9100/metrics/`) |
| `METRICS_USER` | `kitchenowl` | Metrics basic auth username |
| `METRICS_PASSWORD` | `ZqQtidgC5n3YXb` | Metrics basic auth password |
| `SKIP_UPGRADE_DEFAULT_ITEMS` | `false` | On every restart all default items are imported and updated in every household |
| `STORAGE_PATH` | `/data` | Images are stored in `STORAGE_PATH/upload` |
| `DB_DRIVER` | `sqlite` | Supported: `sqlite` and `postgresql` |
| `DB_HOST` | | |
| `DB_PORT` | | |
| `DB_NAME` | `STORAGE_PATH/database.db` | When the driver is `sqlite` this decides where to store the DB |
| `DB_USER` | | |
| `DB_PASSWORD` | | |
| `SMTP_HOST` | | You can connect to an SMTP server for sending password resets and verifying user emails. This not required. |
| `SMTP_PORT` | `465` | |
| `SMTP_USER` | | |
| `SMTP_PASS` | | |
| `SMTP_FROM` | | |
| `SMTP_REPLY_TO` | | |
| `OIDC_ISSUER` | | More about [OIDC](./oidc.md) |
| `OIDC_CLIENT_ID` | | |
| `OIDC_CLIENT_SECRET` | | |
| `APPLE_CLIENT_ID` | | |
| `APPLE_CLIENT_SECRET` | | |
| `GOOGLE_CLIENT_ID` | | |
| `GOOGLE_CLIENT_SECRET` | | |

Additionally, to setting these environment variables you can also override the start command to scale the backend up.
Add the following line or take a look at this exemplary [docker-compose.yml](https://github.com/TomBursch/kitchenowl/blob/main/docker-compose-postgres.yml) file:
Expand All @@ -66,10 +68,11 @@ Environment variables for `tombursch/kitchenowl-web`:
| `BACK_URL` | `back:5000` | Allows to set a custom address for the backend. Needs to be an uWSGI protocol endpoint. Should correspond to the name or IP of the backend container and port `5000` |

## Multiservice Setup
All provided examples can be turned into a multiservice setup with just a few changes. This means separating frontend and backend into multiple docker containers.

All provided examples can be turned into a multiservice setup with just a few changes. This means separating frontend and backend into multiple docker containers.

See [docker-compose.yml](https://github.com/TomBursch/kitchenowl/blob/main/docker-compose.yml)

```yml
version: "3"
services:
Expand Down

0 comments on commit 2bc0aa7

Please sign in to comment.