GetCredentials implements the credentials.Provider interface for GitHub Apps. If the provided data represents a GitHub App installation and any optional constraints specified by the metadata do not prevent it, this method returns an App installation access token that is scoped only to the repository
( ctx context.Context, req credentials.Request, )
| 95 | // an App installation access token that is scoped only to the repository |
| 96 | // specified by repoURL. |
| 97 | func (p *AppCredentialProvider) GetCredentials( |
| 98 | ctx context.Context, |
| 99 | req credentials.Request, |
| 100 | ) (*credentials.Credentials, error) { |
| 101 | repoName := p.extractRepoName(req.RepoURL) |
| 102 | if repoName == "" { |
| 103 | // Doesn't look like a URL we can do anything with. |
| 104 | return nil, nil |
| 105 | } |
| 106 | |
| 107 | // If there's a scope map in the metadata, take it into consideration... |
| 108 | if scopeMapStr := req.Metadata[kargoapi.AnnotationKeyGitHubTokenScope]; scopeMapStr != "" { |
| 109 | var scopeMap map[string][]string |
| 110 | if err := json.Unmarshal([]byte(scopeMapStr), &scopeMap); err != nil { |
| 111 | return nil, fmt.Errorf("error unmarshaling scope map: %w", err) |
| 112 | } |
| 113 | if !slices.Contains(scopeMap[req.Project], repoName) { |
| 114 | // repoName is NOT one of the scopes the Project is allowed to use. |
| 115 | return nil, nil |
| 116 | } |
| 117 | } |
| 118 | |
| 119 | // Client ID is the newer unique identifier for GitHub Apps. GitHub recommends |
| 120 | // using this when possible. If no client ID is found in the data map, we will |
| 121 | // fall back on the old/deprecated unique identifier, App ID. |
| 122 | appOrClientID := string(req.Data[clientIDKey]) |
| 123 | if appOrClientID == "" { |
| 124 | appOrClientID = string(req.Data[appIDKey]) |
| 125 | } |
| 126 | |
| 127 | installID, err := strconv.ParseInt(string(req.Data[installationIDKey]), 10, 64) |
| 128 | if err != nil { |
| 129 | return nil, fmt.Errorf("error parsing installation ID: %w", err) |
| 130 | } |
| 131 | |
| 132 | return p.getUsernameAndPassword( |
| 133 | ctx, |
| 134 | appOrClientID, |
| 135 | installID, |
| 136 | string(req.Data[privateKeyKey]), |
| 137 | req.RepoURL, |
| 138 | ) |
| 139 | } |
| 140 | |
| 141 | // getUsernameAndPassword gets a username (kargo) and password (installation |
| 142 | // access token) for the given app/client ID, installation ID, PEM-encoded |
nothing calls this directly
no test coverage detected