feat: add Share Permission & AD Group sync UI framework and customizable service template

This commit is contained in:
2026-10-20 20:05:33 +09:00
parent ccc1b47dfd
commit a44c4a42cb
7 changed files with 604 additions and 3 deletions
+242
View File
@@ -0,0 +1,242 @@
# Modules\ShareSyncService.ps1
# ==============================================================================
# Share Access & AD Security Group Sync Service
# 사용자가 직접 세부 쿼리 및 AD 그룹 규칙을 커스텀할 수 있는 비즈니스 로직 골격
# ==============================================================================
<#
.SYNOPSIS
DB에서 Share(공유) 목록 및 사용자 권한 목록을 조회하고,
Share와 동일한 이름의 AD 보안그룹에 사용자(sAMAccountName)를 추가/제거하는 서비스 골격입니다.
#>
# 1. DB에서 관리 대상 Share(공유) 목록 조회 템플릿
function Get-DbShareList {
param(
[object]$Config = $null
)
# TODO: 사용자 정의 DB 테이블/뷰 조회 쿼리로 교체하십시오.
# 예: SELECT ShareName, SvmName, Description FROM tbl_Shares WHERE IsActive = 1
$customQuery = @"
SELECT
'Finance_Share' AS ShareName,
'재무기획팀 기밀문서' AS Description,
'vol_cifs_share01' AS VolumeName
UNION ALL
SELECT
'HR_Share' AS ShareName,
'인사팀 개인정보자료' AS Description,
'vol_cifs_share01' AS VolumeName
UNION ALL
SELECT
'DevOps_Share' AS ShareName,
'개발운영팀 공용폴더' AS Description,
'vol_user_homes' AS VolumeName
UNION ALL
SELECT
'Public_Projects' AS ShareName,
'전사 프로젝트 공유' AS Description,
'vol_user_homes' AS VolumeName;
"@
# 실제 DB 연결 모드일 경우 실행
$useLive = if ($Config -and $Config.MsSql) { [bool]$Config.MsSql.UseLive } else { $false }
if ($useLive) {
try {
$connStr = Build-SqlConnectionString -Server $Config.MsSql.Server -AuthType $Config.MsSql.AuthType -Username $Config.MsSql.Username -Password $Config.MsSql.Password
$conn = New-Object System.Data.SqlClient.SqlConnection($connStr)
$conn.Open()
$cmd = $conn.CreateCommand()
$cmd.CommandText = $customQuery
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
$table = New-Object System.Data.DataTable
$adapter.Fill($table) | Out-Null
$conn.Close()
$list = [System.Collections.Generic.List[PSCustomObject]]::new()
foreach ($row in $table.Rows) {
$list.Add([PSCustomObject]@{
ShareName = $row["ShareName"]
Description = $row["Description"]
VolumeName = $row["VolumeName"]
})
}
return $list.ToArray()
} catch {
Write-Warning "DB Share 조회 실패: $($_.Exception.Message) (샘플 데이터 반환)"
}
}
# 기본 Mock / 스켈레톤 데이터
return @(
[PSCustomObject]@{ ShareName = "Finance_Share"; Description = "재무기획팀 기밀문서"; VolumeName = "vol_cifs_share01" },
[PSCustomObject]@{ ShareName = "HR_Share"; Description = "인사팀 개인정보자료"; VolumeName = "vol_cifs_share01" },
[PSCustomObject]@{ ShareName = "DevOps_Share"; Description = "개발운영팀 공용폴더"; VolumeName = "vol_user_homes" },
[PSCustomObject]@{ ShareName = "Public_Projects"; Description = "전사 프로젝트 공유"; VolumeName = "vol_user_homes" }
)
}
# 2. 특정 Share에 매핑된 사용자 목록을 DB에서 조회 템플릿
function Get-DbUsersForShare {
param(
[string]$ShareName,
[object]$Config = $null
)
# TODO: 사용자 정의 DB 조회 쿼리로 교체하십시오.
# 예: SELECT UserId, SamAccountName, UserName, Department, IsAssigned, AssignedDate FROM tbl_SharePermissions WHERE ShareName = @ShareName
$customQuery = @"
-- 여기에 실제 사용하실 SELECT 쿼리를 작성하십시오.
-- 파라미터: '$ShareName'
SELECT
'gdhong' AS SamAccountName, '홍길동' AS UserName, '클라우드인프라팀' AS Department, 1 AS IsAssigned, '2026-09-01' AS AssignedDate
UNION ALL
SELECT
'cskim' AS SamAccountName, '김철수' AS UserName, '데이터플랫폼팀' AS Department, 1 AS IsAssigned, '2026-09-10' AS AssignedDate
UNION ALL
SELECT
'yylee' AS SamAccountName, '이영희' AS UserName, '보안관제팀' AS Department, 0 AS IsAssigned, NULL AS AssignedDate
UNION ALL
SELECT
'mschoi' AS SamAccountName, '최민수' AS UserName, '개발운영팀' AS Department, 0 AS IsAssigned, NULL AS AssignedDate
UNION ALL
SELECT
'jhbak' AS SamAccountName, '박지훈' AS UserName, '시스템관리팀' AS Department, 1 AS IsAssigned, '2026-10-01' AS AssignedDate;
"@
# 목업 및 DB 결과 파싱
return @(
[PSCustomObject]@{ IsSelected = $false; SamAccountName = "gdhong"; UserName = "홍길동"; Department = "클라우드인프라팀"; Status = "할당됨"; IsAssigned = $true; AssignedDate = "2026-09-01" },
[PSCustomObject]@{ IsSelected = $false; SamAccountName = "cskim"; UserName = "김철수"; Department = "데이터플랫폼팀"; Status = "할당됨"; IsAssigned = $true; AssignedDate = "2026-09-10" },
[PSCustomObject]@{ IsSelected = $false; SamAccountName = "yylee"; UserName = "이영희"; Department = "보안관제팀"; Status = "미할당 (해제됨)"; IsAssigned = $false; AssignedDate = "-" },
[PSCustomObject]@{ IsSelected = $false; SamAccountName = "mschoi"; UserName = "최민수"; Department = "개발운영팀"; Status = "미할당 (해제됨)"; IsAssigned = $false; AssignedDate = "-" },
[PSCustomObject]@{ IsSelected = $false; SamAccountName = "jhbak"; UserName = "박지훈"; Department = "시스템관리팀"; Status = "할당됨"; IsAssigned = $true; AssignedDate = "2026-10-01" }
)
}
# 3. Share와 동일한 이름의 AD 보안그룹 멤버 목록 조회
function Get-ADGroupMembersByShareName {
param(
[string]$GroupName, # Share 이름과 동일한 AD 그룹명
[object]$Config = $null
)
$useLive = if ($Config -and $Config.ActiveDirectory) { [bool]$Config.ActiveDirectory.UseLive } else { $false }
if ($useLive) {
try {
$dc = $Config.ActiveDirectory.DomainController
$user = $Config.ActiveDirectory.Username
$pass = $Config.ActiveDirectory.Password
$rootPath = "LDAP://$dc"
$rootEntry = if ([string]::IsNullOrWhiteSpace($user)) {
New-Object System.DirectoryServices.DirectoryEntry($rootPath)
} else {
New-Object System.DirectoryServices.DirectoryEntry($rootPath, $user, $pass)
}
# 그룹 찾기
$searcher = New-Object System.DirectoryServices.DirectorySearcher($rootEntry)
$searcher.Filter = "(&(objectCategory=group)(sAMAccountName=$GroupName))"
$groupResult = $searcher.FindOne()
if ($groupResult) {
$groupEntry = $groupResult.GetDirectoryEntry()
$members = [System.Collections.Generic.List[PSCustomObject]]::new()
foreach ($memberDn in $groupEntry.Properties["member"]) {
# 멤버 DN에서 SamAccountName 추출 또는 파싱
$memberEntry = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$dc/$memberDn", $user, $pass)
$sam = $memberEntry.Properties["sAMAccountName"].Value
$disp = $memberEntry.Properties["displayName"].Value
$dept = $memberEntry.Properties["department"].Value
$members.Add([PSCustomObject]@{
SamAccountName = $sam
DisplayName = $disp
Department = $dept
DistinguishedName = $memberDn
})
}
return $members.ToArray()
}
} catch {
Write-Warning "실제 AD 그룹 조회 실패: $($_.Exception.Message)"
}
}
# 기본 데모 데이터
return @(
[PSCustomObject]@{ SamAccountName = "gdhong"; DisplayName = "홍길동"; Department = "클라우드인프라팀"; DistinguishedName = "CN=홍길동,OU=Users,DC=corp,DC=local" },
[PSCustomObject]@{ SamAccountName = "cskim"; DisplayName = "김철수"; Department = "데이터플랫폼팀"; DistinguishedName = "CN=김철수,OU=Users,DC=corp,DC=local" },
[PSCustomObject]@{ SamAccountName = "jhbak"; DisplayName = "박지훈"; Department = "시스템관리팀"; DistinguishedName = "CN=박지훈,OU=Users,DC=corp,DC=local" }
)
}
# 4. 사용자들을 Share 이름의 AD 보안그룹에 추가하고 DB 업데이트
function Add-UsersToShareAndGroup {
param(
[string]$ShareName, # Share 이름 (= AD 보안그룹 이름)
[string[]]$SamAccountNames, # 추가할 사용자 SamAccountName 목록
[object]$Config = $null
)
$logs = [System.Collections.Generic.List[string]]::new()
$logs.Add("[시작] Share [$ShareName] (AD 보안그룹: $ShareName)에 사용자 추가 작업")
foreach ($sam in $SamAccountNames) {
# --- (A) AD 보안그룹에 사용자 객체 추가 로직 ---
# TODO: 사용자의 실제 AD 환경에 맞게 추가 구현 또는 보완하십시오.
# Live 모드일 경우:
# $groupEntry.Properties["member"].Add($userDn)
# $groupEntry.CommitChanges()
# 또는 Add-ADGroupMember -Identity $ShareName -Members $sam
$logs.Add(" -> [AD] 보안그룹 [$ShareName]에 사용자 [$sam] 추가 완료")
# --- (B) DB 권한 테이블 UPDATE / INSERT 로직 ---
# TODO: 실제 DB 쿼리를 아래 공간에 작성하십시오.
# 예: UPDATE tbl_SharePermissions SET IsAssigned = 1, AssignedDate = GETDATE() WHERE ShareName = '$ShareName' AND SamAccountName = '$sam';
$logs.Add(" -> [DB] Share 권한 테이블에 [$sam] 할당 상태 갱신 완료")
}
$logs.Add("[완료] 총 $($SamAccountNames.Count)명 사용자 추가 및 동기화 처리 완료")
return [PSCustomObject]@{
Success = $true
Logs = $logs.ToArray()
Message = "[$ShareName] 그룹 및 DB에 총 $($SamAccountNames.Count)명의 사용자가 추가되었습니다."
}
}
# 5. 사용자들을 Share 이름의 AD 보안그룹에서 제거/해제하고 DB 업데이트
function Remove-UsersFromShareAndGroup {
param(
[string]$ShareName, # Share 이름 (= AD 보안그룹 이름)
[string[]]$SamAccountNames, # 제거할 사용자 SamAccountName 목록
[object]$Config = $null
)
$logs = [System.Collections.Generic.List[string]]::new()
$logs.Add("[시작] Share [$ShareName] (AD 보안그룹: $ShareName)에서 사용자 제거/해제 작업")
foreach ($sam in $SamAccountNames) {
# --- (A) AD 보안그룹에서 사용자 객체 제거 로직 ---
# TODO: 사용자의 실제 AD 환경에 맞게 추가 구현 또는 보완하십시오.
# Live 모드일 경우:
# $groupEntry.Properties["member"].Remove($userDn)
# $groupEntry.CommitChanges()
# 또는 Remove-ADGroupMember -Identity $ShareName -Members $sam -Confirm:$false
$logs.Add(" -> [AD] 보안그룹 [$ShareName]에서 사용자 [$sam] 제거 완료")
# --- (B) DB 권한 테이블 UPDATE / DELETE 로직 ---
# TODO: 실제 DB 쿼리를 아래 공간에 작성하십시오.
# 예: UPDATE tbl_SharePermissions SET IsAssigned = 0, RevokedDate = GETDATE() WHERE ShareName = '$ShareName' AND SamAccountName = '$sam';
$logs.Add(" -> [DB] Share 권한 테이블에서 [$sam] 해제 상태 갱신 완료")
}
$logs.Add("[완료] 총 $($SamAccountNames.Count)명 사용자 제거 및 동기화 처리 완료")
return [PSCustomObject]@{
Success = $true
Logs = $logs.ToArray()
Message = "[$ShareName] 그룹 및 DB에서 총 $($SamAccountNames.Count)명의 사용자가 제거(해제)되었습니다."
}
}