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

feat: Optionally disable username and password login #487

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
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
Loading