2023-09-19 02:59:33 +00:00
|
|
|
import copy
|
|
|
|
|
2023-07-24 03:52:25 +00:00
|
|
|
from django.utils.translation import gettext_lazy as _
|
2023-01-16 11:02:09 +00:00
|
|
|
from rest_framework import serializers
|
|
|
|
|
2023-07-31 09:39:30 +00:00
|
|
|
from accounts.const import SecretType, DEFAULT_PASSWORD_RULES
|
2023-07-18 07:01:47 +00:00
|
|
|
from common.utils import ssh_key_gen, random_string
|
2023-01-16 11:02:09 +00:00
|
|
|
from common.utils import validate_ssh_private_key, parse_ssh_private_key_str
|
|
|
|
|
|
|
|
|
|
|
|
class SecretGenerator:
|
|
|
|
def __init__(self, secret_strategy, secret_type, password_rules=None):
|
|
|
|
self.secret_strategy = secret_strategy
|
|
|
|
self.secret_type = secret_type
|
|
|
|
self.password_rules = password_rules
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def generate_ssh_key():
|
2023-10-09 08:05:42 +00:00
|
|
|
private_key, __ = ssh_key_gen()
|
2023-01-16 11:02:09 +00:00
|
|
|
return private_key
|
|
|
|
|
|
|
|
def generate_password(self):
|
2023-09-19 02:59:33 +00:00
|
|
|
password_rules = self.password_rules
|
|
|
|
if not password_rules or not isinstance(password_rules, dict):
|
|
|
|
password_rules = {}
|
|
|
|
rules = copy.deepcopy(DEFAULT_PASSWORD_RULES)
|
|
|
|
rules.update(password_rules)
|
|
|
|
rules = {
|
|
|
|
'length': rules['length'],
|
|
|
|
'lower': rules['lowercase'],
|
|
|
|
'upper': rules['uppercase'],
|
|
|
|
'digit': rules['digit'],
|
2023-11-28 06:46:51 +00:00
|
|
|
'special_char': rules['symbol'],
|
|
|
|
'exclude_chars': rules['exclude_symbols']
|
2023-09-19 02:59:33 +00:00
|
|
|
}
|
|
|
|
return random_string(**rules)
|
2023-01-16 11:02:09 +00:00
|
|
|
|
|
|
|
def get_secret(self):
|
|
|
|
if self.secret_type == SecretType.SSH_KEY:
|
|
|
|
secret = self.generate_ssh_key()
|
|
|
|
elif self.secret_type == SecretType.PASSWORD:
|
|
|
|
secret = self.generate_password()
|
|
|
|
else:
|
|
|
|
raise ValueError("Secret must be set")
|
|
|
|
return secret
|
|
|
|
|
|
|
|
|
|
|
|
def validate_password_for_ansible(password):
|
|
|
|
""" 校验 Ansible 不支持的特殊字符 """
|
|
|
|
# validate password contains left double curly bracket
|
|
|
|
# check password not contains `{{`
|
|
|
|
# Ansible 推送的时候不支持
|
2023-11-03 07:20:19 +00:00
|
|
|
if '{{' in password or '}}' in password:
|
|
|
|
raise serializers.ValidationError(_('Password can not contains `{{` or `}}`'))
|
|
|
|
if '{%' in password or '%}' in password:
|
|
|
|
raise serializers.ValidationError(_('Password can not contains `{%` or `%}`'))
|
2023-01-16 11:02:09 +00:00
|
|
|
# Ansible Windows 推送的时候不支持
|
2023-11-03 07:20:19 +00:00
|
|
|
# if "'" in password:
|
|
|
|
# raise serializers.ValidationError(_("Password can not contains `'` "))
|
|
|
|
# if '"' in password:
|
|
|
|
# raise serializers.ValidationError(_('Password can not contains `"` '))
|
2023-01-16 11:02:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
def validate_ssh_key(ssh_key, passphrase=None):
|
|
|
|
valid = validate_ssh_private_key(ssh_key, password=passphrase)
|
|
|
|
if not valid:
|
|
|
|
raise serializers.ValidationError(_("private key invalid or passphrase error"))
|
|
|
|
return parse_ssh_private_key_str(ssh_key, passphrase)
|