v0.0.21 | NHN Cloud 멀티 프로젝트 지원 추가
Some checks failed
Build And Test / build-and-push (push) Failing after 34s
Some checks failed
Build And Test / build-and-push (push) Failing after 34s
- NHNCloudProject 모델 추가 (사용자별 여러 프로젝트 관리) - 프로젝트 목록/추가/삭제/활성화 API 추가 - 프로젝트별 비밀번호 복호화 API 추가 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -142,3 +142,58 @@ class CustomUser(AbstractBaseUser, PermissionsMixin):
|
||||
self.save(update_fields=[
|
||||
'nhn_tenant_id', 'nhn_username', 'encrypted_nhn_api_password', 'nhn_storage_account'
|
||||
])
|
||||
|
||||
|
||||
# ============================================
|
||||
# NHN Cloud 프로젝트 (멀티 프로젝트 지원)
|
||||
# ============================================
|
||||
|
||||
class NHNCloudProject(models.Model):
|
||||
"""
|
||||
사용자별 NHN Cloud 프로젝트 관리 (멀티 프로젝트 지원)
|
||||
"""
|
||||
user = models.ForeignKey(
|
||||
CustomUser,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='nhn_projects',
|
||||
verbose_name="사용자"
|
||||
)
|
||||
name = models.CharField(max_length=100, verbose_name="프로젝트 별칭")
|
||||
tenant_id = models.CharField(max_length=64, verbose_name="NHN Cloud Tenant ID")
|
||||
username = models.EmailField(verbose_name="NHN Cloud Username")
|
||||
encrypted_password = models.BinaryField(verbose_name="NHN Cloud API Password (암호화)")
|
||||
storage_account = models.CharField(max_length=128, blank=True, null=True, verbose_name="Storage Account")
|
||||
is_active = models.BooleanField(default=False, verbose_name="활성 프로젝트")
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "NHN Cloud 프로젝트"
|
||||
verbose_name_plural = "NHN Cloud 프로젝트"
|
||||
unique_together = ['user', 'tenant_id'] # 동일 사용자가 같은 tenant 중복 등록 방지
|
||||
ordering = ['-is_active', '-created_at']
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.name} ({self.tenant_id})"
|
||||
|
||||
def get_encryption_key(self) -> bytes:
|
||||
"""SECRET_KEY 기반 Fernet 키 생성"""
|
||||
hashed = hashlib.sha256(settings.SECRET_KEY.encode()).digest()
|
||||
return base64.urlsafe_b64encode(hashed[:32])
|
||||
|
||||
def encrypt_password(self, password: str) -> bytes:
|
||||
"""비밀번호 암호화"""
|
||||
cipher = Fernet(self.get_encryption_key())
|
||||
return cipher.encrypt(password.encode())
|
||||
|
||||
def decrypt_password(self) -> str:
|
||||
"""비밀번호 복호화"""
|
||||
if self.encrypted_password:
|
||||
cipher = Fernet(self.get_encryption_key())
|
||||
return cipher.decrypt(self.encrypted_password).decode()
|
||||
return ""
|
||||
|
||||
def save_credentials(self, password: str):
|
||||
"""자격증명 저장 (비밀번호 암호화)"""
|
||||
self.encrypted_password = self.encrypt_password(password)
|
||||
self.save()
|
||||
|
||||
Reference in New Issue
Block a user