Skip to content

Commit

Permalink
Merge branch 'develop' into 'main'
Browse files Browse the repository at this point in the history
chore: Update password history

See merge request locker/api-core!468
  • Loading branch information
khaitranquang committed Jul 5, 2024
2 parents 240d656 + 0c9a032 commit e31e973
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 38 deletions.
18 changes: 12 additions & 6 deletions locker_server/api/v1_0/sharing/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from locker_server.shared.constants.members import MEMBER_ROLE_ADMIN, MEMBER_ROLE_MEMBER
from locker_server.api.v1_0.ciphers.serializers import ItemFieldSerializer, LoginVaultSerializer, \
SecurityNoteVaultSerializer, CardVaultSerializer, IdentityVaultSerializer, CryptoAccountSerializer, \
CryptoWalletSerializer
CryptoWalletSerializer, PasswordHistorySerializer
from locker_server.shared.utils.app import get_cipher_detail_data


Expand Down Expand Up @@ -88,6 +88,7 @@ class CipherShareSerializer(serializers.Serializer):
identity = IdentityVaultSerializer(required=False, many=False, allow_null=True)
cryptoAccount = CryptoAccountSerializer(required=False, many=False, allow_null=True)
cryptoWallet = CryptoWalletSerializer(required=False, many=False, allow_null=True)
passwordHistory = PasswordHistorySerializer(many=True, required=False)


class FolderShareSerializer(serializers.Serializer):
Expand Down Expand Up @@ -128,7 +129,8 @@ def __get_shared_cipher_data(cipher):
"attachments": None,
"fields": cipher.get("fields"),
"collection_ids": [],
"data": get_cipher_detail_data(cipher)
"data": get_cipher_detail_data(cipher),
"password_history": cipher.get("password_history") or cipher.get("passwordHistory")
}
return shared_cipher_data

Expand Down Expand Up @@ -227,7 +229,8 @@ def __get_shared_cipher_data(cipher):
"attachments": None,
"fields": cipher.get("fields"),
"collection_ids": [],
"data": get_cipher_detail_data(cipher)
"data": get_cipher_detail_data(cipher),
"password_history": cipher.get("password_history") or cipher.get("passwordHistory")
}
return shared_cipher_data

Expand Down Expand Up @@ -293,7 +296,8 @@ def __get_personal_cipher_data(cipher):
"score": cipher.get("score", 0),
"reprompt": cipher.get("reprompt", 0),
"fields": cipher.get("fields"),
"data": get_cipher_detail_data(cipher)
"data": get_cipher_detail_data(cipher),
"password_history": cipher.get("password_history") or cipher.get("passwordHistory")
}
return shared_cipher_data

Expand Down Expand Up @@ -337,7 +341,8 @@ def __get_personal_cipher_data(cipher):
"score": cipher.get("score", 0),
"reprompt": cipher.get("reprompt", 0),
"fields": cipher.get("fields"),
"data": get_cipher_detail_data(cipher)
"data": get_cipher_detail_data(cipher),
"password_history": cipher.get("password_history") or cipher.get("passwordHistory")
}
return shared_cipher_data

Expand Down Expand Up @@ -365,7 +370,8 @@ def __get_share_cipher_data(cipher):
"score": cipher.get("score", 0),
"reprompt": cipher.get("reprompt", 0),
"fields": cipher.get("fields"),
"data": get_cipher_detail_data(cipher)
"data": get_cipher_detail_data(cipher),
"password_history": cipher.get("password_history") or cipher.get("passwordHistory")
}
return shared_cipher_data

Expand Down
2 changes: 1 addition & 1 deletion locker_server/api/v1_0/sync/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def to_representation(self, instance):
"notes": data.get("notes"),
"organization_id": instance.team.team_id if instance.team else None,
"organization_use_totp": True if login else False,
"password_history": instance.history,
"password_history": instance.password_history,
"reprompt": instance.reprompt,
"revision_date": convert_readable_date(instance.revision_date),
"creation_date": convert_readable_date(instance.creation_date),
Expand Down
6 changes: 6 additions & 0 deletions locker_server/api_orm/abstracts/ciphers/ciphers.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class AbstractCipherORM(models.Model):
data = models.TextField(blank=True, null=True)
favorites = models.TextField(blank=True, null=True)
folders = models.TextField(blank=True, null=True, default="")
password_history = models.TextField(blank=True, null=True, default="")

user = models.ForeignKey(
locker_server_settings.LS_USER_MODEL, on_delete=models.CASCADE, related_name="ciphers", null=True
Expand Down Expand Up @@ -60,3 +61,8 @@ def set_folder(self, user_id, folder_id=None):
folders[user_id] = folder_id
self.folders = folders
self.save()

def get_password_history(self):
if not self.password_history:
return []
return ast.literal_eval(str(self.password_history))
18 changes: 18 additions & 0 deletions locker_server/api_orm/migrations/0028_auto_20240705_1726.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.2.23 on 2024-07-05 10:26

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('api_orm', '0027_auto_20240704_1131'),
]

operations = [
migrations.AddField(
model_name='cipherorm',
name='password_history',
field=models.TextField(blank=True, default='', null=True),
)
]
19 changes: 10 additions & 9 deletions locker_server/api_orm/model_parsers/cipher_parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def parse_cipher(cls, cipher_orm: CipherORM, parse_collection_ids=False, parse_h
folders=cipher_orm.get_folders(),
favorites=cipher_orm.get_favorites(),
view_password=view_password,
password_history=cipher_orm.get_password_history(),
user=user_parser.parse_user(user_orm=cipher_orm.user) if cipher_orm.user else None,
created_by=user_parser.parse_user(user_orm=cipher_orm.created_by) if cipher_orm.created_by else None,
team=team_parser.parse_team(team_orm=cipher_orm.team) if cipher_orm.team else None,
Expand All @@ -46,15 +47,15 @@ def parse_cipher(cls, cipher_orm: CipherORM, parse_collection_ids=False, parse_h
pass
cipher.collection_ids = collection_ids

if parse_histories is True:
try:
show_history = getattr(cipher_orm, "show_history")
except AttributeError:
show_history = True
if show_history is False:
cipher.history = []
else:
cipher.history = cls.parse_password_history(cipher_orm=cipher_orm, limit_history=limit_history)
# if parse_histories is True:
# try:
# show_history = getattr(cipher_orm, "show_history")
# except AttributeError:
# show_history = True
# if show_history is False:
# cipher.history = []
# else:
# cipher.history = cls.parse_password_history(cipher_orm=cipher_orm, limit_history=limit_history)
return cipher

@classmethod
Expand Down
43 changes: 22 additions & 21 deletions locker_server/api_orm/repositories/cipher_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -529,33 +529,34 @@ def update_cipher(self, cipher_id: str, cipher_data: Dict) -> Cipher:
user_cipher_id = None

# Create new cipher history
if cipher_orm.type in SAVE_HISTORY_CIPHER_TYPES:
password_history = cipher_data.get("password_history") or []
# limit_history = cipher_data.get("limit_history")
# if limit_history and len(password_history) > limit_history:
# password_history = password_history[-limit_history:]
if cipher_orm.type == CIPHER_TYPE_LOGIN and len(password_history) > cipher_orm.cipher_histories.count():
num = len(password_history)-cipher_orm.cipher_histories.count()
password_histories_data = password_history[:num]
c_data = cipher_orm.get_data()
cipher_histories_data = []
for password_history_data in password_histories_data:
_cipher_data = c_data.copy()
_cipher_data.update({"password": password_history_data.get("password") or c_data.get("password")})
cipher_histories_data.append({
"last_use_date": password_history_data.get("last_used_date") or cipher_orm.last_use_date or now(),
"reprompt": cipher_orm.reprompt,
"score": cipher_orm.score,
"data": _cipher_data,
"cipher_id": cipher_orm.id,
})
cipher_orm.cipher_histories.model.create_multiple(cipher_histories_data)
# if cipher_orm.type in SAVE_HISTORY_CIPHER_TYPES:
# password_history = cipher_data.get("password_history") or []
# # limit_history = cipher_data.get("limit_history")
# # if limit_history and len(password_history) > limit_history:
# # password_history = password_history[-limit_history:]
# if cipher_orm.type == CIPHER_TYPE_LOGIN and len(password_history) > cipher_orm.cipher_histories.count():
# num = len(password_history)-cipher_orm.cipher_histories.count()
# password_histories_data = password_history[:num]
# c_data = cipher_orm.get_data()
# cipher_histories_data = []
# for password_history_data in password_histories_data:
# _cipher_data = c_data.copy()
# _cipher_data.update({"password": password_history_data.get("password") or c_data.get("password")})
# cipher_histories_data.append({
# "last_use_date": password_history_data.get("last_used_date") or cipher_orm.last_use_date or now(),
# "reprompt": cipher_orm.reprompt,
# "score": cipher_orm.score,
# "data": _cipher_data,
# "cipher_id": cipher_orm.id,
# })
# cipher_orm.cipher_histories.model.create_multiple(cipher_histories_data)
# Create new cipher object
cipher_orm.revision_date = now()
cipher_orm.reprompt = cipher_data.get("reprompt", cipher_orm.reprompt) or 0
cipher_orm.score = cipher_data.get("score", cipher_orm.score)
cipher_orm.type = cipher_data.get("type", cipher_orm.type)
cipher_orm.data = cipher_data.get("data", cipher_orm.get_data())
cipher_orm.password_history = cipher_data.get("password_history", cipher_orm.get_password_history())
cipher_orm.user_id = user_cipher_id
cipher_orm.team_id = team_id
cipher_orm.save()
Expand Down
2 changes: 2 additions & 0 deletions locker_server/api_orm/repositories/sharing_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ def _share_cipher_orm(cipher_orm: CipherORM, team_id: str, cipher_data) -> Ciphe
cipher_orm.score = cipher_data.get("score", cipher_orm.score)
cipher_orm.type = cipher_data.get("type", cipher_orm.type)
cipher_orm.data = cipher_data.get("data", cipher_orm.get_data())
cipher_orm.password_history = cipher_data.get("password_history", cipher_orm.get_password_history())
cipher_orm.user_id = None
cipher_orm.team_id = team_id
cipher_orm.save()
Expand All @@ -128,6 +129,7 @@ def _stop_share_cipher_orm(cipher_orm: CipherORM, user_id: int, cipher_data):
cipher_orm.score = cipher_data.get("score", cipher_orm.score)
cipher_orm.type = cipher_data.get("type", cipher_orm.type)
cipher_orm.data = cipher_data.get("data", cipher_orm.get_data())
cipher_orm.password_history = cipher_data.get("password_history", cipher_orm.get_password_history())
cipher_orm.user_id = user_id
cipher_orm.team_id = None
cipher_orm.save()
Expand Down
14 changes: 13 additions & 1 deletion locker_server/core/entities/cipher/cipher.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import List

from locker_server.core.entities.team.team import Team
from locker_server.core.entities.user.user import User
from locker_server.shared.constants.ciphers import CIPHER_TYPE_LOGIN
Expand All @@ -7,7 +9,8 @@ class Cipher(object):
def __init__(self, cipher_id: str, creation_date: float = None, revision_date: float = None,
deleted_date: float = None, last_use_date: float = None, num_use: int = 0, reprompt: int = 0,
score: float = 0, cipher_type: int = None, data=None, favorites: str = "", folders: str = "",
view_password: bool = True, user: User = None, created_by: User = None, team: Team = None):
view_password: bool = True, password_history: List = None,
user: User = None, created_by: User = None, team: Team = None):
self._cipher_id = cipher_id
self._creation_date = creation_date
self._revision_date = revision_date
Expand All @@ -21,6 +24,7 @@ def __init__(self, cipher_id: str, creation_date: float = None, revision_date: f
self._favorites = favorites
self._folders = folders
self._view_password = view_password
self._password_history = password_history
self._history = []
self._collection_ids = []
self._user = user
Expand Down Expand Up @@ -98,6 +102,14 @@ def view_password(self):
def view_password(self, view_password_value):
self._view_password = view_password_value

@property
def password_history(self):
return self._password_history or []

@password_history.setter
def password_history(self, password_history_value):
self._password_history = password_history_value

@property
def collection_ids(self):
return self._collection_ids
Expand Down

0 comments on commit e31e973

Please sign in to comment.