Auth support (#25)

* initial auth implementation

* add create user parser

* add tests

* update dependencies list

* add login annd logout to index also improve auth

* realworld fixes

* add method set_option to Configuration and also use it everywhere
* split CreateUser handler to additional read method
* check user duplicate on auth mapping read
* generate salt by using passlib instead of random.choice
* case-insensetive usernames
* update dependencies
* update configuration reference
* improve tests

* fix codefactor errors

* hide fields if authorization is enabled, but no auth supplied

* add settings object for auth provider

* readme update
This commit is contained in:
2021-09-02 23:36:00 +03:00
committed by GitHub
parent 60b94b9ac0
commit b7cff0a19d
63 changed files with 2200 additions and 184 deletions

View File

@ -0,0 +1,36 @@
import pytest
from ahriman.core.exceptions import InvalidOption
from ahriman.models.auth_settings import AuthSettings
def test_from_option_invalid() -> None:
"""
must raise exception on invalid option
"""
with pytest.raises(InvalidOption, match=".* `invalid`$"):
AuthSettings.from_option("invalid")
def test_from_option_valid() -> None:
"""
must return value from valid options
"""
assert AuthSettings.from_option("disabled") == AuthSettings.Disabled
assert AuthSettings.from_option("DISABLED") == AuthSettings.Disabled
assert AuthSettings.from_option("no") == AuthSettings.Disabled
assert AuthSettings.from_option("NO") == AuthSettings.Disabled
assert AuthSettings.from_option("configuration") == AuthSettings.Configuration
assert AuthSettings.from_option("ConFigUration") == AuthSettings.Configuration
assert AuthSettings.from_option("mapping") == AuthSettings.Configuration
assert AuthSettings.from_option("MAPPing") == AuthSettings.Configuration
def test_is_enabled() -> None:
"""
must mark as disabled authorization for disabled and enabled otherwise
"""
assert not AuthSettings.Disabled.is_enabled
for option in filter(lambda o: o != AuthSettings.Disabled, AuthSettings):
assert option.is_enabled

View File

@ -0,0 +1,75 @@
from ahriman.models.user import User
from ahriman.models.user_access import UserAccess
def test_from_option(user: User) -> None:
"""
must generate user from options
"""
assert User.from_option(user.username, user.password) == user
# default is status access
user.access = UserAccess.Write
assert User.from_option(user.username, user.password) != user
def test_from_option_empty() -> None:
"""
must return nothing if settings are missed
"""
assert User.from_option(None, "") is None
assert User.from_option("", None) is None
assert User.from_option(None, None) is None
def test_check_credentials_hash_password(user: User) -> None:
"""
must generate and validate user password
"""
current_password = user.password
user.password = user.hash_password(current_password, "salt")
assert user.check_credentials(current_password, "salt")
assert not user.check_credentials(current_password, "salt1")
assert not user.check_credentials(user.password, "salt")
def test_generate_password() -> None:
"""
must generate password with specified length
"""
password = User.generate_password(16)
assert password
assert len(password) == 16
password = User.generate_password(42)
assert password
assert len(password) == 42
def test_verify_access_read(user: User) -> None:
"""
user with read access must be able to only request read
"""
user.access = UserAccess.Read
assert user.verify_access(UserAccess.Read)
assert not user.verify_access(UserAccess.Write)
assert not user.verify_access(UserAccess.Status)
def test_verify_access_status(user: User) -> None:
"""
user with status access must be able to only request status
"""
user.access = UserAccess.Status
assert not user.verify_access(UserAccess.Read)
assert not user.verify_access(UserAccess.Write)
assert user.verify_access(UserAccess.Status)
def test_verify_access_write(user: User) -> None:
"""
user with write access must be able to do anything
"""
user.access = UserAccess.Write
assert user.verify_access(UserAccess.Read)
assert user.verify_access(UserAccess.Write)
assert user.verify_access(UserAccess.Status)

View File