-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #111 from 42Box/110-유저에게-권한을-받는-페이지를-추가합니다
feat: 유저에게 권한을 받습니다.
- Loading branch information
Showing
8 changed files
with
285 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// | ||
// PreferencesTableView.swift | ||
// Box42 | ||
// | ||
// Created by Chanhee Kim on 8/31/23. | ||
// | ||
|
||
import AppKit | ||
import SnapKit | ||
import Combine | ||
|
||
enum PreferencesCellList: Int, CaseIterable { | ||
case requestAccessView = 1 | ||
case cpu = 2 | ||
case my = 3 | ||
|
||
var height: CGFloat { | ||
switch self { | ||
case .requestAccessView: | ||
return 100.0 | ||
case .cpu: | ||
return 40.0 | ||
case .my: | ||
return 50.0 | ||
} | ||
} | ||
} | ||
|
||
class PreferencesTableView: NSTableView { | ||
let requestAccessView = RequestAccessView() | ||
|
||
func setup() { | ||
self.delegate = self | ||
self.dataSource = self | ||
|
||
let column1 = NSTableColumn(identifier: NSUserInterfaceItemIdentifier("Preferences")) | ||
column1.width = 100.0 | ||
column1.title = "Preferences" | ||
self.addTableColumn(column1) | ||
} | ||
|
||
} | ||
|
||
extension PreferencesTableView: NSTableViewDelegate, NSTableViewDataSource { | ||
func getCellForRow(at row: Int) -> NSView { | ||
let allCases = PreferencesCellList.allCases | ||
if row >= 0 && row < allCases.count { | ||
switch allCases[row] { | ||
case .requestAccessView: | ||
return requestAccessView | ||
case .cpu: | ||
// Return the view for the CPU cell | ||
return NSView() // Placeholder | ||
case .my: | ||
// Return the view for the "my" cell | ||
return NSView() // Placeholder | ||
} | ||
} | ||
return NSView() // Default view if out of bounds or undefined | ||
} | ||
|
||
func numberOfRows(in tableView: NSTableView) -> Int { | ||
return PreferencesCellList.allCases.count | ||
} | ||
|
||
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { | ||
return getCellForRow(at: row) | ||
} | ||
|
||
func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat { | ||
let allCases = PreferencesCellList.allCases | ||
if row >= 0 && row < allCases.count { | ||
return allCases[row].height | ||
} | ||
|
||
return 44.0 // Default height | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
// | ||
// RequestAccessView.swift | ||
// Box42 | ||
// | ||
// Created by Chanhee Kim on 8/31/23. | ||
// | ||
|
||
import AppKit | ||
import SnapKit | ||
|
||
class RequestAccessView: NSView { | ||
var requestAccessTextField: NSTextField = NSTextField() | ||
var grantAccessButton: NSButton = NSButton() | ||
var revokeAccessButton: NSButton = NSButton() | ||
var directoryNameTextField: NSTextField = NSTextField() | ||
|
||
override init(frame frameRect: NSRect) { | ||
super.init(frame: .zero) | ||
self.wantsLayer = true | ||
self.layer?.backgroundColor = NSColor(hex: "#7FFFFFFF").cgColor | ||
self.layer?.cornerRadius = 13 | ||
|
||
// Add subviews | ||
self.addSubview(requestAccessTextField) | ||
self.addSubview(grantAccessButton) | ||
self.addSubview(revokeAccessButton) | ||
self.addSubview(directoryNameTextField) | ||
|
||
// Initialize UI elements | ||
textfieldInit() | ||
buttonInit() | ||
directoryNameTextFieldInit() | ||
|
||
// Set constraints | ||
textfieldConstraints() | ||
buttonConstraints() | ||
directoryNameTextFieldConstraints() | ||
} | ||
|
||
required init?(coder: NSCoder) { | ||
fatalError("init(coder:) has not been implemented") | ||
} | ||
|
||
func textfieldInit() { | ||
requestAccessTextField.stringValue = "Script 및 기능들을 실행하기 위해서 루트 디렉토리의 권한이 필요합니다." | ||
requestAccessTextField.font = NSFont.systemFont(ofSize: 15) | ||
requestAccessTextField.isEditable = false | ||
requestAccessTextField.isBordered = false | ||
requestAccessTextField.backgroundColor = NSColor.clear | ||
requestAccessTextField.lineBreakMode = .byWordWrapping | ||
requestAccessTextField.maximumNumberOfLines = 3 | ||
} | ||
|
||
func buttonInit() { | ||
grantAccessButton.title = "권한 부여" | ||
grantAccessButton.target = self | ||
grantAccessButton.action = #selector(requestFolderAccess(_:)) | ||
|
||
revokeAccessButton.title = "권한 취소" | ||
revokeAccessButton.target = self | ||
revokeAccessButton.action = #selector(revokeFolderAccess(_:)) | ||
} | ||
|
||
func directoryNameTextFieldInit() { | ||
directoryNameTextField.stringValue = "선택된 디렉터리: 없음" | ||
directoryNameTextField.font = NSFont.systemFont(ofSize: 15) | ||
directoryNameTextField.isEditable = false | ||
directoryNameTextField.isBordered = false | ||
directoryNameTextField.backgroundColor = NSColor.clear | ||
directoryNameTextField.lineBreakMode = .byWordWrapping | ||
} | ||
|
||
func directoryNameTextFieldConstraints() { | ||
directoryNameTextField.snp.makeConstraints { make in | ||
make.top.equalTo(revokeAccessButton.snp.bottom).offset(10) | ||
make.leading.equalToSuperview().offset(17) | ||
make.trailing.equalToSuperview().offset(-17) | ||
} | ||
} | ||
|
||
func textfieldConstraints() { | ||
requestAccessTextField.snp.makeConstraints { make in | ||
make.top.equalToSuperview().offset(10) | ||
make.leading.equalToSuperview().offset(17) | ||
make.trailing.equalToSuperview().offset(-17) | ||
} | ||
} | ||
|
||
func buttonConstraints() { | ||
grantAccessButton.snp.makeConstraints { make in | ||
make.top.equalTo(requestAccessTextField.snp.bottom).offset(10) | ||
make.leading.equalToSuperview().offset(17) | ||
} | ||
|
||
revokeAccessButton.snp.makeConstraints { make in | ||
make.top.equalTo(requestAccessTextField.snp.bottom).offset(10) | ||
make.leading.equalTo(grantAccessButton.snp.trailing).offset(10) | ||
} | ||
} | ||
|
||
@objc func requestFolderAccess(_ sender: NSButton) { | ||
let openPanel = NSOpenPanel() | ||
openPanel.title = "Choose a folder" | ||
openPanel.showsResizeIndicator = true | ||
openPanel.showsHiddenFiles = false | ||
openPanel.canChooseDirectories = true | ||
openPanel.canCreateDirectories = true | ||
openPanel.allowsMultipleSelection = false | ||
openPanel.canChooseFiles = false | ||
|
||
if openPanel.runModal() == NSApplication.ModalResponse.OK { | ||
let result = openPanel.url | ||
|
||
if let result = result { | ||
print("Selected folder is \(result.path)") | ||
|
||
directoryNameTextField.stringValue = "선택된 디렉터리: \(result.path)" | ||
|
||
do { | ||
let bookmarkData = try result.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil) | ||
UserDefaults.standard.set(bookmarkData, forKey: "bookmarkData") | ||
} catch { | ||
print("Error creating bookmark: \(error)") | ||
} | ||
} | ||
} else { | ||
// User clicked on "Cancel" | ||
return | ||
} | ||
} | ||
|
||
@objc func revokeFolderAccess(_ sender: NSButton) { | ||
// TODO: Add code to revoke folder access | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// | ||
// SecurityScopedResourceAccess.swift | ||
// Box42 | ||
// | ||
// Created by Chanhee Kim on 8/31/23. | ||
// | ||
|
||
import Foundation | ||
|
||
class SecurityScopedResourceAccess { | ||
private static let queue = DispatchQueue(label: "com.yourApp.securityAccessQueue", attributes: .concurrent) | ||
private static var isAccessing = false | ||
static var bookmarkData: Data? { | ||
get { | ||
return UserDefaults.standard.data(forKey: "bookmarkData") | ||
} | ||
set { | ||
UserDefaults.standard.set(newValue, forKey: "bookmarkData") | ||
} | ||
} | ||
|
||
static func accessResourceExecuteShellScript(scriptPath: String) { | ||
queue.async(flags: .barrier) { | ||
var url: URL? = nil // 이 부분을 추가하여 url 변수의 스코프를 확장합니다. | ||
do { | ||
var staleBookmarkData = false | ||
guard let bookmarkData = self.bookmarkData else { | ||
print("Bookmark data not available.") | ||
return | ||
} | ||
|
||
print("Stored bookmark data: \(String(describing: UserDefaults.standard.data(forKey: "bookmarkData")))") | ||
|
||
|
||
url = try URL(resolvingBookmarkData: bookmarkData, options: .withSecurityScope, relativeTo: nil, bookmarkDataIsStale: &staleBookmarkData) | ||
|
||
if staleBookmarkData { | ||
// Refresh the bookmark data and save it. | ||
} | ||
|
||
isAccessing = url?.startAccessingSecurityScopedResource() ?? false | ||
|
||
// Perform work here | ||
if isAccessing { | ||
ExecuteScripts.executeShellScript(path: scriptPath) | ||
} | ||
|
||
} catch { | ||
print("An error occurred: \(error)") | ||
} | ||
|
||
// Cleanup | ||
if isAccessing { | ||
// Make sure to match this with a call to startAccessingSecurityScopedResource() | ||
url?.stopAccessingSecurityScopedResource() | ||
} | ||
} | ||
} | ||
} |