-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Dont filter content from Copilot #1464
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
Changes from 2 commits
8400964
8ea409b
881dc82
c504141
b3ddb56
ef48964
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,11 +15,12 @@ import ( | |
| // RepoAccessCache caches repository metadata related to lockdown checks so that | ||
| // multiple tools can reuse the same access information safely across goroutines. | ||
| type RepoAccessCache struct { | ||
| client *githubv4.Client | ||
| mu sync.Mutex | ||
| cache *cache2go.CacheTable | ||
| ttl time.Duration | ||
| logger *slog.Logger | ||
| client *githubv4.Client | ||
| mu sync.Mutex | ||
| cache *cache2go.CacheTable | ||
| ttl time.Duration | ||
| logger *slog.Logger | ||
| trustedBotLogins map[string]struct{} | ||
| } | ||
|
|
||
| type repoAccessCacheEntry struct { | ||
|
|
@@ -85,6 +86,9 @@ func GetInstance(client *githubv4.Client, opts ...RepoAccessOption) *RepoAccessC | |
| client: client, | ||
| cache: cache2go.Cache(defaultRepoAccessCacheKey), | ||
| ttl: defaultRepoAccessTTL, | ||
| trustedBotLogins: map[string]struct{}{ | ||
| "copilot": {}, | ||
| }, | ||
| } | ||
| for _, opt := range opts { | ||
| if opt != nil { | ||
|
|
@@ -112,10 +116,13 @@ type CacheStats struct { | |
| func (c *RepoAccessCache) IsSafeContent(ctx context.Context, username, owner, repo string) (bool, error) { | ||
| repoInfo, err := c.getRepoAccessInfo(ctx, username, owner, repo) | ||
| if err != nil { | ||
| c.logDebug("error checking repo access info for content filtering", "owner", owner, "repo", repo, "user", username, "error", err) | ||
| return false, err | ||
| } | ||
| if repoInfo.IsPrivate || repoInfo.ViewerLogin == username { | ||
|
|
||
| c.logInfo(ctx, fmt.Sprintf("evaluated repo access fur user %s to %s/%s for content filtering, result: hasPushAccess=%t, isPrivate=%t", | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this logger hook into MCP logging because log output shows up like an error with MCP servers using stdio, and I think you can instead send server log messages explicitly. Also you can log to stderr (at least the docs from MCP debugging in VS Code say that's better. It looks like this is logging to stdio unless I missed something.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That should be sufficient. |
||
| username, owner, repo, repoInfo.HasPushAccess, repoInfo.IsPrivate)) | ||
|
|
||
| if c.isTrustedBot(username) || repoInfo.IsPrivate || repoInfo.ViewerLogin == strings.ToLower(username) { | ||
| return true, nil | ||
| } | ||
| return repoInfo.HasPushAccess, nil | ||
|
Comment on lines
122
to
134
|
||
|
|
@@ -136,30 +143,34 @@ func (c *RepoAccessCache) getRepoAccessInfo(ctx context.Context, username, owner | |
| if err == nil { | ||
| entry := cacheItem.Data().(*repoAccessCacheEntry) | ||
| if cachedHasPush, known := entry.knownUsers[userKey]; known { | ||
| c.logDebug("repo access cache hit", "owner", owner, "repo", repo, "user", username) | ||
| c.logDebug(ctx, "repo access cache hit") | ||
| return RepoAccessInfo{ | ||
| IsPrivate: entry.isPrivate, | ||
| HasPushAccess: cachedHasPush, | ||
| ViewerLogin: entry.viewerLogin, | ||
| }, nil | ||
| } | ||
| c.logDebug("known users cache miss", "owner", owner, "repo", repo, "user", username) | ||
|
|
||
| c.logDebug(ctx, "known users cache miss") | ||
|
|
||
| info, queryErr := c.queryRepoAccessInfo(ctx, username, owner, repo) | ||
| if queryErr != nil { | ||
| return RepoAccessInfo{}, queryErr | ||
| } | ||
|
|
||
| entry.knownUsers[userKey] = info.HasPushAccess | ||
| entry.viewerLogin = info.ViewerLogin | ||
| entry.isPrivate = info.IsPrivate | ||
| c.cache.Add(key, c.ttl, entry) | ||
|
|
||
| return RepoAccessInfo{ | ||
| IsPrivate: entry.isPrivate, | ||
| HasPushAccess: entry.knownUsers[userKey], | ||
| ViewerLogin: entry.viewerLogin, | ||
| }, nil | ||
| } | ||
|
|
||
| c.logDebug("repo access cache miss", "owner", owner, "repo", repo, "user", username) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why you decided to remove attributes?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| c.logDebug(ctx, "repo access cache miss") | ||
|
|
||
| info, queryErr := c.queryRepoAccessInfo(ctx, username, owner, repo) | ||
| if queryErr != nil { | ||
|
|
@@ -230,12 +241,29 @@ func (c *RepoAccessCache) queryRepoAccessInfo(ctx context.Context, username, own | |
| }, nil | ||
| } | ||
|
|
||
| func cacheKey(owner, repo string) string { | ||
| return fmt.Sprintf("%s/%s", strings.ToLower(owner), strings.ToLower(repo)) | ||
| func (c *RepoAccessCache) log(ctx context.Context, level slog.Level, msg string, attrs ...slog.Attr) { | ||
| if c == nil || c.logger == nil { | ||
| return | ||
| } | ||
| if !c.logger.Enabled(ctx, level) { | ||
| return | ||
| } | ||
| c.logger.LogAttrs(ctx, level, msg, attrs...) | ||
| } | ||
|
|
||
| func (c *RepoAccessCache) logDebug(msg string, args ...any) { | ||
| if c != nil && c.logger != nil { | ||
| c.logger.Debug(msg, args...) | ||
| } | ||
| func (c *RepoAccessCache) logDebug(ctx context.Context, msg string, attrs ...slog.Attr) { | ||
| c.log(ctx, slog.LevelDebug, msg, attrs...) | ||
| } | ||
|
|
||
| func (c *RepoAccessCache) logInfo(ctx context.Context, msg string, attrs ...slog.Attr) { | ||
| c.log(ctx, slog.LevelInfo, msg, attrs...) | ||
| } | ||
|
|
||
| func (c *RepoAccessCache) isTrustedBot(username string) bool { | ||
| _, ok := c.trustedBotLogins[strings.ToLower(username)] | ||
| return ok | ||
| } | ||
|
Comment on lines
+267
to
+270
|
||
|
|
||
| func cacheKey(owner, repo string) string { | ||
| return fmt.Sprintf("%s/%s", strings.ToLower(owner), strings.ToLower(repo)) | ||
| } | ||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's possible if it's expensive enough we might want to use redis or memcached on remote server, do you have a solution in mind for that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I was thinking of that, or even creating an adapter for the local server. Generally using Redis in the remote server would be the next logical step.
Two main aspects that will guide enhancing this mode are