Skip to content

wip: add an API of plugins to retrieve authentication information #7150

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions Sources/Commands/Utilities/PluginDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,20 @@ final class PluginDelegate: PluginInvocationDelegate {
}
}

func authorizationInfoRequest(
for url: URL,
completion: @escaping (Result<PluginInvocationAuthorizationInfoResult?, Error>) -> Void
) {
// Get the authorization info from the authorization provider
DispatchQueue.sharedConcurrent.async {
completion(Result {
try self.swiftTool.getAuthorizationProvider()?.authentication(for: url).map {
.init(username: $0, password: $1)
}
})
}
}

private func createSymbolGraphForPlugin(
forTarget targetName: String,
options: PluginInvocationSymbolGraphOptions
Expand Down
28 changes: 28 additions & 0 deletions Sources/PackagePlugin/PackageManagerProxy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,27 @@ public struct PackageManager {
/// The directory that contains the symbol graph files for the target.
public var directoryPath: Path
}

/// Return authorization information for the URL.
// FIXME: add a hashing key
public func getAuthorizationInfo(
for url: String
) throws -> AuthorizationInfo? {
// Ask the plugin host for authorization information, and wait for a response.
// FIXME: We'll want to make this asynchronous when there is back deployment support for it.
return try sendMessageAndWaitForReply(.authorizationInfoRequest(url: url)) {
guard case .authorizationInfoResponse(let result) = $0 else { return nil }
return result.map{ .init($0) }
}
}

/// Represents authorization information
public struct AuthorizationInfo {
/// The username
public var username: String
/// The password
public var password: String
}
}

fileprivate extension PackageManager {
Expand Down Expand Up @@ -440,3 +461,10 @@ fileprivate extension PackageManager.SymbolGraphResult {
self.directoryPath = .init(result.directoryPath)
}
}

fileprivate extension PackageManager.AuthorizationInfo {
init(_ result: HostToPluginMessage.AuthorizationInfo) {
self.username = result.username
self.password = result.password
}
}
12 changes: 11 additions & 1 deletion Sources/PackagePlugin/PluginMessages.swift
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,14 @@ enum HostToPluginMessage: Codable {
struct SymbolGraphResult: Codable {
var directoryPath: String
}


/// A response to a request for authorization info
case authorizationInfoResponse(result: AuthorizationInfo?)
struct AuthorizationInfo: Codable {
var username: String
var password: String
}

/// A response of an error while trying to complete a request.
case errorResponse(error: String)
}
Expand Down Expand Up @@ -324,4 +331,7 @@ enum PluginToHostMessage: Codable {
var includeSPI: Bool
var emitExtensionBlocks: Bool
}

/// the plugin requesting authorization information
case authorizationInfoRequest(url: String)
}
39 changes: 39 additions & 0 deletions Sources/SPMBuildCore/Plugins/PluginInvocation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,23 @@ extension PluginTarget {
self.observabilityScope.emit(debug: "couldn't send reply to plugin", underlyingError: error)
}
}
case .authorizationInfoRequest(let _url):
guard let url = URL(string: _url) else {
throw StringError("Invalid URL: \(_url)")
}
self.invocationDelegate.authorizationInfoRequest(for: url) {
do {
switch $0 {
case .success(let result):
responder(try HostToPluginMessage.authorizationInfoResponse(result: result.map{ .init($0) }).toData())
case .failure(let error):
responder(try HostToPluginMessage.errorResponse(error: String(describing: error)).toData())
}
}
catch {
self.observabilityScope.emit(debug: "couldn't send reply to plugin", underlyingError: error)
}
}
}
}
}
Expand Down Expand Up @@ -702,6 +719,9 @@ public protocol PluginInvocationDelegate {

/// Called when a plugin requests that the host computes and returns symbol graph information for a particular target.
func pluginRequestedSymbolGraph(forTarget name: String, options: PluginInvocationSymbolGraphOptions, completion: @escaping (Result<PluginInvocationSymbolGraphResult, Error>) -> Void)

/// Called when a plugin requests authorization information through the PackagePlugin APIs.
func authorizationInfoRequest(for url: URL, completion: @escaping (Result<PluginInvocationAuthorizationInfoResult?, Error>) -> Void)
}

public struct PluginInvocationSymbolGraphOptions {
Expand All @@ -721,6 +741,15 @@ public struct PluginInvocationSymbolGraphResult {
}
}

public struct PluginInvocationAuthorizationInfoResult {
public var username: String
public var password: String
public init(username: String, password: String) {
self.username = username
self.password = password
}
}

public enum PluginInvocationBuildSubset {
case all(includingTests: Bool)
case product(String)
Expand Down Expand Up @@ -829,6 +858,9 @@ public extension PluginInvocationDelegate {
func pluginRequestedSymbolGraph(forTarget name: String, options: PluginInvocationSymbolGraphOptions, completion: @escaping (Result<PluginInvocationSymbolGraphResult, Error>) -> Void) {
DispatchQueue.sharedConcurrent.async { completion(Result.failure(StringError("unimplemented"))) }
}
func authorizationInfoRequest(for url: URL, completion: @escaping (Result<PluginInvocationAuthorizationInfoResult?, Error>) -> Void) {
DispatchQueue.sharedConcurrent.async { completion(Result.failure(StringError("unimplemented"))) }
}
}

fileprivate extension PluginInvocationBuildSubset {
Expand Down Expand Up @@ -999,6 +1031,13 @@ fileprivate extension HostToPluginMessage.SymbolGraphResult {
}
}

fileprivate extension HostToPluginMessage.AuthorizationInfo {
init(_ result: PluginInvocationAuthorizationInfoResult) {
self.username = result.username
self.password = result.password
}
}

extension ObservabilityMetadata {
public var fileLocation: FileLocation? {
get {
Expand Down