Skip to content

Commit

Permalink
Add password reset and expire methods to providers
Browse files Browse the repository at this point in the history
  • Loading branch information
spoore1 committed Sep 25, 2024
1 parent dade9e1 commit da39b9a
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 1 deletion.
62 changes: 62 additions & 0 deletions sssd_test_framework/roles/ad.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from __future__ import annotations

from datetime import datetime
from typing import Any, TypeAlias

from pytest_mh.cli import CLIBuilderArgs
Expand Down Expand Up @@ -777,6 +778,7 @@ def modify(
*,
uid: int | DeleteAttribute | None = None,
gid: int | DeleteAttribute | None = None,
password: str | DeleteAttribute | None = "Secret123",
home: str | DeleteAttribute | None = None,
gecos: str | DeleteAttribute | None = None,
shell: str | DeleteAttribute | None = None,
Expand All @@ -794,6 +796,8 @@ def modify(
:type uid: int | DeleteAttribute | None, optional
:param gid: Primary group id, defaults to None
:type gid: int | DeleteAttribute | None, optional
:param password: Password (cannot be None), defaults to 'Secret123'
:type password: str, optional
:param home: Home directory, defaults to None
:type home: str | DeleteAttribute | None, optional
:param gecos: GECOS, defaults to None
Expand Down Expand Up @@ -839,6 +843,64 @@ def modify(

self._modify(attrs)

# Password changes require a different command group so special
# handling is needed
if password is not None:
self.reset(str(password))

return self

def reset(
self,
password: str = "Secret123",
) -> ADUser:
"""
Reset user password
Parameters that are not set are ignored.
:param password: Password, defaults to 'Secret123'
:type password: str, optional
:return: Self.
:rtype: ADUser
"""
attrs: CLIBuilderArgs = {
**self._identity,
"Reset": (self.cli.option.SWITCH, True),
"NewPassword": (self.cli.option.PLAIN, f'(ConvertTo-SecureString "{password}" -AsPlainText -force)'),
}

args = " ".join(self.cli.args(attrs, quote_value=True))
self.role.host.conn.run(
f"""
Import-Module ActiveDirectory
Set-ADAccountPassword {args}
"""
)

return self

def expire(self, expiration: str = "19700101000000") -> ADUser:
"""
Set user password expiration date and time
:param expiration: Date and time for user password expiration, defaults to 19700101000000Z
:type expirataion: str, optional
:return: Self.
:rtype: ADUser
"""
expire = datetime.strptime(expiration, "%Y%m%d%H%M%S")
expire_format = expire.strftime("%m/%d/%Y %H:%M:%S")

attrs: CLIBuilderArgs = {**self._identity, "DateTime": (self.cli.option.VALUE, f"{expire_format}")}

args = " ".join(self.cli.args(attrs, quote_value=True))
self.role.host.conn.run(
f"""
Import-Module ActiveDirectory
Set-ADAccountExpiration {args}
"""
)
return self

def passkey_add(self, passkey_mapping: str) -> ADUser:
Expand Down
24 changes: 24 additions & 0 deletions sssd_test_framework/roles/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,30 @@ def modify(
"""
pass

@abstractmethod
def reset(self, password: str | None = "Secret123") -> GenericUser:
"""
Reset user password
:param password: Password, defaults to 'Secret123'
:type password: str, optional
:return: Self.
:rtype: IPAUser
"""
pass

@abstractmethod
def expire(self, expiration: str | None = "19700101000000") -> GenericUser:
"""
Set user password expiration date and time
:param expiration: Date and time for user password expiration, defaults to 19700101000000
:type expirataion: str, optional
:return: Self.
:rtype: IPAUser
"""
pass

@abstractmethod
def delete(self) -> None:
"""
Expand Down
28 changes: 28 additions & 0 deletions sssd_test_framework/roles/ipa.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,34 @@ def modify(
self._modify(attrs, input=password)
return self

def reset(self, password: str | None = "Secret123") -> IPAUser:
"""
Reset user password
:param password: Password, defaults to 'Secret123'
:type password: str, optional
:return: Self.
:rtype: IPAUser
"""
pwinput = f"{password}\n{password}"
self.role.host.conn.run(f"ipa passwd {self.name}", input=pwinput)
self.expire("20380101120000Z")

return self

def expire(self, expiration: str | None = "19700101000000Z") -> IPAUser:
"""
Set user password expiration date and time
:param expiration: Date and time for user password expiration, defaults to 19700101000000
:type expirataion: str, optional
:return: Self.
:rtype: IPAUser
"""
self.modify(password_expiration=expiration)

return self

def passkey_add(self, passkey_mapping: str) -> IPAUser:
"""
Add passkey mapping to the user.
Expand Down
40 changes: 39 additions & 1 deletion sssd_test_framework/roles/ldap.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from __future__ import annotations

import base64
from datetime import datetime
from enum import Enum
from typing import Any, Generic, TypeVar

Expand Down Expand Up @@ -630,7 +631,9 @@ class LDAPUser(LDAPObject[LDAPHost, LDAP]):
LDAP user management.
"""

def __init__(self, role: LDAP, name: str, basedn: LDAPObject | str | None = "ou=users", rdn_attr: str | None = "cn") -> None:
def __init__(
self, role: LDAP, name: str, basedn: LDAPObject | str | None = "ou=users", rdn_attr: str | None = "cn"
) -> None:
"""
:param role: LDAP role object.
:type role: LDAP
Expand Down Expand Up @@ -763,6 +766,8 @@ def modify(
:type uid: int | DeleteAttribute | None, optional
:param gid: Primary group id, defaults to None
:type gid: int | DeleteAttribute | None, optional
:param password: Password, defaults to 'Secret123'
:type password: str, optional
:param home: Home directory, defaults to None
:type home: str | DeleteAttribute | None, optional
:param gecos: GECOS, defaults to None
Expand Down Expand Up @@ -808,6 +813,39 @@ def modify(
self._set(attrs)
return self

def reset(self, password: str | None = "Secret123") -> LDAPUser:
"""
Reset user password
:param password: Password, defaults to 'Secret123'
:type password: str, optional
:return: Self.
:rtype: LDAPUser
"""
self.modify(password=password)
return self

def expire(self, expiration: str = "19700101000000") -> LDAPUser:
"""
Set user password expiration date and time
:param expiration: Date and time for user password expiration, defaults to 19700101000000
:type expirataion: str, optional
:return: Self.
:rtype: IPAUser
"""

start = datetime.now()
end = datetime.strptime(expiration, "%Y%m%d%H%M%S")
time_diff = end - start
expires_in = int(time_diff.total_seconds())
if expires_in < 0:
expires_in = 0

self.modify(shadowMax=expires_in)

return self

def passkey_add(self, passkey_mapping: str) -> LDAPUser:
"""
Add passkey mapping to the user.
Expand Down

0 comments on commit da39b9a

Please sign in to comment.