From 52edda02e6fee2c8122fac71c49ea711672b4d92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonah=20Br=C3=BCchert?= Date: Tue, 2 Apr 2024 23:46:00 +0200 Subject: Remove service passwords feature --- accounts/__init__.py | 6 ------ accounts/app.py | 2 -- accounts/backend/user/ldap.py | 37 +++----------------------------- accounts/forms.py | 27 ------------------------ accounts/models.py | 36 +++---------------------------- accounts/static/layout.css | 34 ------------------------------ accounts/templates/about.html | 5 ----- accounts/templates/index.html | 43 -------------------------------------- accounts/views/admin/__init__.py | 2 -- accounts/views/default/__init__.py | 21 +------------------ 10 files changed, 7 insertions(+), 206 deletions(-) diff --git a/accounts/__init__.py b/accounts/__init__.py index c290c3a..2824da7 100644 --- a/accounts/__init__.py +++ b/accounts/__init__.py @@ -2,7 +2,6 @@ import os from flask import Flask -from .models import Service from .utils import get_backend from .utils.confirmation import Confirmation from .utils.sessions import EncryptedSessionInterface @@ -40,11 +39,6 @@ def create_app(config=None) -> Flask: app.register_blueprint(admin.bp, url_prefix="/admin") app.session_interface = EncryptedSessionInterface() - app.all_services = list() - for name, url in app.config.get("SERVICES", list()): - cn = name.lower() - app.all_services.append(Service(cn, name, url)) - app.username_blacklist = list() if app.config.get("USERNAME_BLACKLIST_FILE"): with open(app.config["USERNAME_BLACKLIST_FILE"]) as f: diff --git a/accounts/app.py b/accounts/app.py index d39ce03..e222788 100644 --- a/accounts/app.py +++ b/accounts/app.py @@ -4,11 +4,9 @@ from typing import TYPE_CHECKING, cast if TYPE_CHECKING: from .backend import user, mail - from .models import Service class AccountsFlask(Flask): - all_services: "list[Service]" username_blacklist: list[str] user_backend: "user.Backend" mail_backend: "mail.Backend" diff --git a/accounts/backend/user/ldap.py b/accounts/backend/user/ldap.py index a1ed904..fc16270 100644 --- a/accounts/backend/user/ldap.py +++ b/accounts/backend/user/ldap.py @@ -14,7 +14,7 @@ from ldap3.abstract.entry import Entry from ldap3 import Connection from . import Backend, InvalidPasswordError, NoSuchUserError, ShouldNotHappen -from accounts.models import Account, Service +from accounts.models import Account from accounts import AccountsFlask from typing import Optional @@ -54,7 +54,6 @@ class LdapBackend(Backend): self.base_dn: list[tuple[str, str]] = self.app.config["LDAP_BASE_DN"] self.admin_user: str = self.app.config["LDAP_ADMIN_USER"] self.admin_pass: str = self.app.config["LDAP_ADMIN_PASS"] - self.services: list[Service] = self.app.all_services self.admin = False self.binded = False @@ -70,7 +69,6 @@ class LdapBackend(Backend): uid = None mail = None uidNumber = None - services = [] conn.search( user_dn, "(objectClass=*)", @@ -82,13 +80,11 @@ class LdapBackend(Backend): uid = entry.uid.value mail = entry.mail.value uidNumber = entry.uidNumber.value - elif "servicePassword" in entry.objectClass.value: - services.append(entry.cn.value) if uid is None or mail is None or uidNumber is None: raise NoSuchUserError("User not found") - return Account(uid, mail, services, password, uidNumber=uidNumber) + return Account(uid, mail, password, uidNumber=uidNumber) def find(self, filters: Optional[dict[str, str]] = None, wildcard=False): """ @@ -173,10 +169,7 @@ class LdapBackend(Backend): else: conn = self._connect(account.uid, account.password) - dns = [ - [("cn", service), ("uid", account.uid), ("ou", "users")] - for service in account.services - ] + [[("uid", account.uid), ("ou", "users")]] + dns = [[("uid", account.uid), ("ou", "users")]] for dn in dns: conn.delete(self._format_dn(dn)) @@ -219,30 +212,6 @@ class LdapBackend(Backend): _, account.password = account.new_password_root account.new_password_root = None - for service, passwords in list(account.new_password_services.items()): - service_id = service.lower() - service_dn = self._format_dn( - [("cn", service_id), ("uid", account.uid), ("ou", "users")] - ) - _, new = passwords - - if new is not None: - if service_id not in account.services: - attrs = { - "objectClass": ["top", "servicePassword"], - "cn": _escape(service_id), - } - conn.add(service_dn, attributes=attrs) - account.services.append(service_id) - - _change_password(conn, service_dn, passwords, as_admin) - else: - if service_id in account.services: - conn.delete(service_dn) - account.services.remove(service_id) - - del account.new_password_services[service] - def _get_last_uidNumber(self, conn: Connection): uidNumber_dn = self._format_dn([("cn", "uidMax"), ("ou", "other")]) conn.search( diff --git a/accounts/forms.py b/accounts/forms.py index 01713ad..8c9da03 100644 --- a/accounts/forms.py +++ b/accounts/forms.py @@ -7,7 +7,6 @@ from wtforms import ( StringField, PasswordField, ValidationError, - BooleanField, validators, ) from wtforms.form import FormMeta @@ -129,32 +128,6 @@ class LostPasswordForm(Form): class SettingsMeta(FormMeta): def __call__(cls, *args, **kwargs): - for service in accounts_app.all_services: - setattr( - cls, - "password_%s" % service.id, - PasswordField( - "Passwort für %s" % service.name, - [ - validators.Optional(), - validators.EqualTo( - "password_confirm_%s" % service.id, - message="Passwörter stimmen nicht überein", - ), - ], - ), - ) - setattr( - cls, - "password_confirm_%s" % service.id, - PasswordField("Passwort für %s (Bestätigung)" % service.name), - ) - setattr( - cls, - "delete_%s" % service.id, - BooleanField("Passwort für %s löschen" % service.name), - ) - return super(SettingsMeta, cls).__call__(*args, **kwargs) diff --git a/accounts/models.py b/accounts/models.py index 8b34fab..ac5ce78 100644 --- a/accounts/models.py +++ b/accounts/models.py @@ -5,23 +5,6 @@ from typing import Any, Optional from accounts.utils.login import create_userid -class Service(object): - id: str - name: str - url: str - - def __init__(self, service_id: str, name: str, url: str) -> None: - self.id = service_id - self.name = name - self.url = url - - #: Wether the user has a separate password for this service. - self.changed = False - - def __repr__(self): - return "" % self.id - - class Account(UserMixin): """ An Account represents a complex ldap tree entry for spline users. @@ -31,9 +14,7 @@ class Account(UserMixin): _ready = False uid: str - services: list[str] password: Optional[str] - new_password_services: dict[str, tuple[Optional[str], Optional[str]]] attributes: dict[Any, Any] new_password_root: Optional[tuple[Optional[str], Optional[str]]] @@ -41,15 +22,12 @@ class Account(UserMixin): self, uid: str, mail: str, - services=None, password: Optional[str] = None, uidNumber=None, ): self.uid = uid - self.services = list() if services is None else services self.password = password self.new_password_root = None - self.new_password_services = {} self.attributes = {} self.uidNumber = uidNumber @@ -59,22 +37,14 @@ class Account(UserMixin): def __repr__(self): return "" % self.uid - def reset_password(self, service: str): - self.new_password_services[service] = (None, None) - def change_password( - self, new_password: str, old_password="", service=None + self, new_password: str, old_password="" ): """ - Changes a password for a given service. You have to use the - UserBackend to make the changes permanent. If no service is given, - the root password will be changed. + Changes the password of the account """ - if not service: - self.new_password_root = (old_password, new_password) - else: - self.new_password_services[service] = (old_password, new_password) + self.new_password_root = (old_password, new_password) def _set_attribute(self, key: str, value: Any) -> None: self.attributes[key] = value diff --git a/accounts/static/layout.css b/accounts/static/layout.css index 1d6a3bf..c22c3ea 100644 --- a/accounts/static/layout.css +++ b/accounts/static/layout.css @@ -165,40 +165,6 @@ form ul.errors { color: red; } -.service { - padding-top: 15px; - margin-left: 30px; - clear: both; -} - -.service h3 { - float: left; - margin: 0; - width: 33%; -} - -.service ul { - margin: 0px; -} - -.service ul li{ - float: left; - list-style: none; - margin: 0px; - width: 33%; -} - -.service .form-service { - clear: both; - padding-top: 10px; -} - -.form-submit-services { - margin-left: 30px; - padding: 10px 0px; - clear: both; -} - /* flashing */ ul.flashes { diff --git a/accounts/templates/about.html b/accounts/templates/about.html index 2ae1936..5c7143d 100644 --- a/accounts/templates/about.html +++ b/accounts/templates/about.html @@ -36,9 +36,4 @@ Mail mit!

Welche Dienste sind bisher dabei?

- {%- endblock %} diff --git a/accounts/templates/index.html b/accounts/templates/index.html index 7d9fd83..51a338c 100644 --- a/accounts/templates/index.html +++ b/accounts/templates/index.html @@ -11,49 +11,6 @@ {{ render_field(form.password_confirm) }} {{ render_field(form.csrf_token) }} {{ render_submit(value='Speichern',name='submit_main') }} - -

Dienste verwalten

-

- Standardmäßig kannst du dich auf allen teilnehmenden Diensten mit dem - oben konfigurierten allgemeinen Passwort einloggen. -

-

- Du kannst für jeden Dienst ein eigenes Passwort setzen. Das empfiehlt - sich zum Beispiel, wenn du einen der Dienste oft unterwegs an fremden - Rechnern nutzt. -

- - {%- for service in services %} -
-

- {% if service.changed %} - {{ form.get_servicedelete(service.id)(class_="form-check-input") }} - {% else %} - {{ form.get_servicedelete(service.id)(disabled=True, class_="form-check-input") }} - {% endif %} - {{ service.name }} -

- -
    - {%- if service.changed %} -
  • eigenes Passwort
  • - - {%- else %} -
  • allgemeines Passwort
  • - {%- endif %} -
- -
-

Neues Passwort setzen:

- {{ render_field(form.get_servicepassword(service.id)) }} - {{ render_field(form.get_servicepasswordconfirm(service.id)) }} - {{ render_submit(value='Speichern',name='submit_main') }} -
-
- {%- endfor %} -
- -
{%- endblock %} diff --git a/accounts/views/admin/__init__.py b/accounts/views/admin/__init__.py index 92dbf22..18b9de4 100644 --- a/accounts/views/admin/__init__.py +++ b/accounts/views/admin/__init__.py @@ -70,8 +70,6 @@ def disable_account(): if form.validate_on_submit() and form.user: random_pw = str(uuid4()) form.user.change_password(random_pw) - for service in accounts_app.all_services: - form.user.reset_password(service.id) oldmail = form.user.mail mail = ( diff --git a/accounts/views/default/__init__.py b/accounts/views/default/__init__.py index b5c9298..a007ef9 100644 --- a/accounts/views/default/__init__.py +++ b/accounts/views/default/__init__.py @@ -2,7 +2,6 @@ import sys import traceback -from copy import deepcopy from flask import Blueprint from flask import redirect, render_template, request, flash, url_for from flask_login import login_required, login_user, current_user @@ -149,14 +148,7 @@ def index() -> Union[Response, dict]: if form.validate_on_submit(): changed = False - if request.form.get("submit_services"): - for service in accounts_app.all_services: - field = form.get_servicedelete(service.id) - if field.data: - current_user.reset_password(service.id) - changed = True - - elif request.form.get("submit_main"): + if request.form.get("submit_main"): if form.mail.data and form.mail.data != current_user.mail: accounts_app.mail_backend.send( form.mail.data, @@ -179,12 +171,6 @@ def index() -> Union[Response, dict]: flash("Passwort geändert", "success") changed = True - for service in accounts_app.all_services: - field = form.get_servicepassword(service.id) - if field.data: - changed = True - current_user.change_password(field.data, None, service.id) - if changed: accounts_app.user_backend.update(current_user) login_user(current_user) @@ -192,13 +178,8 @@ def index() -> Union[Response, dict]: else: flash("Nichts geändert.") - services = deepcopy(accounts_app.all_services) - for s in services: - s.changed = s.id in current_user.services - return { "form": form, - "services": services, } -- cgit v1.2.3-1-g7c22