Giter Club home page Giter Club logo

gu-who's Introduction

GU: Who?

answering: "Who has access to my GitHub organisation - and why?"

gu:who? is a simple service for auditing the members of your GitHub organisation. It was written by The Guardian to get their 200-strong GitHub organisation under control, resulting in 100% of membership being accounted for and 98% Two-Factor-Auth enabled, up from 54% - you can read more about it in this Guardian Developers blogpost.

If your organisation is large - and you have 3rd parties, contractors, etc who you need to give access to your code - it can be very difficult to work out whether some accounts are legitimately members of your GitHub organisation or not. Accounts which don't have many details set in their profile are difficult to identify. When employees leave, how sure are you that you'll remember to remove their account?

gu:who? aims to make dealing with this all a little bit more easy... it aims to ensure all users in your organisation meet some basic requirements, and it makes it easy to see where requirements aren't being met.

It does this by using GitHub as its user-interface: GitHub issues and simple text files stored in GitHub 'people' repo held under your org- no other database or spreadsheet, no Active Directory or LDAP.

Just the tools the developer already uses: GitHub

Enforced Requirements

These requirements are intended to make it easier to manage the user accounts and work out if they should be in your organisation or not:

  • Two-Factor-Auth enabled (this requirement can be waived for users in the 'bots' team - for instance, for a long-lived CI bot account that may need to be accessed by multiple humans, who would otherwise have to share an authentication token)
  • A Full Name set in the user GitHub Profile
  • Sponsor: each GitHub username should be in github.com/your-organization-name/people/blob/main/users.txt (see an example or read more details) - added by Pull Request by any senior member of the organisation (who, in effect, acts as the 'sponsor' for the user for being in the GitHub Org). The current GitHub admin interface doesn't give any long-term audit trail on how a user came to join an Org, so this file serves that purpose.

Actions taken by the gu-who bot...

  • Opens a GitHub issue against each user that doesn't pass the requirements
  • Conceals organisation membership for users which don't comply with the requirements
  • After a grace period of 1 month removes insecure users from the org - a final warning is given 1 week before removal.

Local Deployment

You can start a local application at http://localhost:9000 with the command:

$ export APPLICATION_SECRET=<secret>
$ sbt start

Remote Deployment

What's your logo?

Well, obviously, it would be the ridiculously suitable Riddlocat by @cameronmcefee, but we can't use it for legal reasons laid out on the GitHub Octodex FAQ.

You'll just have to imagine the logo there.

What else?

If you're interested in Git and security, you may also be interested in The BFG Repo-Cleaner, a simpler, faster alternative to git-filter-branch for cleansing bad data out of your Git repository - ie Passwords, Credentials & other private or unwanted data.

You might also be interested in Prout, to tell you when your pull requests are reaching Production.

gu-who's People

Contributors

alexmuller avatar annashipman avatar friism avatar gjtorikian avatar gu-scala-steward-public-repos[bot] avatar jfsoul avatar kaelig avatar kant avatar lindseydew avatar markjamesbutler avatar mchv avatar michaelpereira avatar novembertang avatar rtyley avatar snim2 avatar stof avatar tuix avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gu-who's Issues

Runs this regularly on a server?

Hey,

great tool you built here, thanks for opening it up.

I was wondering: when do the checks run? Is it regularly via some internal scheduling, triggered by a cron or only when a user logs in? From reading code I think it's the later only, correct? How do you run this at the Guardian?

My ideal case here would be to run this on a server (with an access token of a user who's in the bots group).

403 trying to post directly to service - CSRF Error

At the end of the validation it says:

You can re-run this process, and update the associated issues, by calling our endpoint directly:
curl -X POST http://gu-who.herokuapp.com/audit/myorg?apiKey={{ YOUR_GITHUB_API_KEY }}

Your GitHub API key needs to have the scopes repo and write:org.

If I do I get a 403 error with this content: No CSRF token found in headers

warning confuses when issue closed in same comment

Hi, I'm running gu-who on my org and on my second run (initial run 30 days ago, next run today) noticed that it comments with a "scary" sounding warning and closes the issue in the same comment. It seems confusing that it would warn "you're going to be removed on 11 Dec" and "you're good to go" in the same comment. Is this something that you would welcome a fix for (I could try my hand at putting in a PR for it)?

WARNING: If requirements for this account aren't met, it will be removed from DataXu, Inc.'s organisation on Friday, December 11, 2015.

Thanks for fixing those requirements (ie Sponsor). Closing this issue, you're good to go! :sparkles:

screen shot 2015-12-08 at 4 02 56 pm

Update other build configuration

The master branch of this repository has been migrated to main using the master-to-main tool.

Please check any build related configuration and update as required:

  • TeamCity - See the required steps in the migrating.md document
  • Change snyk github integration(s) - it uses the default branch, but you will need to delete and reimport the project+file as this is the only way to refresh the default branch at present.
  • Any other externally configured analysis tooling your team is using e.g. travis CI

It's probably a good idea to merge test PR to main once this is complete, to make sure that everything is working as expected. 🙂

mention the grace period in the issues that are open

When the policy violation issues are opened, it might be nice to let the user know how long they have to fix the issue(s). That being said, I understand that giving a specific amount of time will cause people to procrastinate. Maybe something in the middle, like "you have a limited amount of time to fix these issues". Thoughts?

/cc @jgrevich

add a test mode

We are planning to use this @18F, and even though we've done some testing in a sandbox organization, it would be nice to see what the bot would do against our real org. Would be great to have a test/no-op option, where it (for example) prints out all of the issues it would file and the users it would kick out, without actually doing so. I've never done any Scala, but could possibly hack on this a bit if there's interest.

/cc @jgrevich

Users who lose their sponsor when the sponsor leaves the Organisation

There should probably be an account requirement that gets played against users that have been sponsored, but by users who have left the organisation. The point of sponsorship is to ensure there's always someone responsible for any given user account - the person you can ask: "Does this person still work for us?!" - and this breaks down when senior staff leave, taking their workplace/staff knowledge with them.

The algorithm would be something like:

  • do a git blame on users.txt
  • use this to construct a map of user -> sponsor(s?) ...note this probably requires mapping from email to github username on the sponsor?! Instead, do scrape the github blame page?!?
  • any user that doesn't have a sponsor currently in the organisation, needs to get an issue raised against them, asking them to get a new sponsor to add a comment to the relevant line in users.txt so they now assume responsibility for that user.

gu-who incorrectly reporting that user account is <3 months old

I get this error when trying to audit an organization:

[info] application - Asked to audit @MYORG
[error] play - Cannot invoke the action, eventually got an error: java.lang.IllegalArgumentException: requirement failed: Organisation @MYORG must have at least one *public* member whose account is over 3 months old
[error] application - 

The rest of the traceback is as you would expect for that error message. This is running on Ubuntu Trusty, OpenJDK 1.7, Scala 2.9.2.

Now, the organisation is under 3 months old, but I am the only member of it, and my account dates from 2009. I'm not sure if this is a bug or whether it is intended behaviour with a confusing error message. However, I would suggest that a new organisation shouldn't be seen as an error.

Protect against stupid operators who didn't fill out a users.txt before running

I ran this against my organization, thinking it would be awesome. It was. It sent out hundreds of emails to our users - sometimes multiple, depending upon if they setup bots - which means that now everyone is upset at me.

We should instead:

  • have a big shiny warning if the file doesn't exist
  • fail if the person authenticating isn't on that list (they should be!)
  • fail if the list of users in the users.txt doesnt match at least some percentage (25?) of users in the org
  • straightup-bomb out if an env var doesnt exist to override the above.

make grace period configurable

Took a bit of digging to find the grace period in the code...a few ideas, in order of importance:

  • Mention the amount of time in the README
  • Make the amount of time configurable
  • Make different grace periods for the different infractions. In other words, not having 2FA enabled is a security issue, whereas not having a full name isn't a huge deal. Totally understand if you want to keep things simple and not do this one.

Thanks!

/cc @jgrevich

Oops, an error occured

Hello - I've hit a red "Oops, an error occured" with This exception has been logged with id 6jbmp8eo0 & 6jbmpa5ai (tried) twice, if you can fix this it would be great to use this tool.. here's exact steps of what I was doing:

  1. went to https://gu-who.herokuapp.com/
  2. clicked on "Log In via GitHub!"
  3. using myself (vorburger)
  4. choose the TemenosDS org. (which was just set-up -- there isn't some cacheing issue or something?)
  5. it went to https://gu-who.herokuapp.com/audit/TemenosDS
  6. the red "Oops, an error occured" page appeared

Document the "bots" and "2fa_disabled" groups

Diving into the code I saw that there is a concept of a bot user or a user without the two factor auth requirement.

My scala is a but rusty so I'm not 100% sure what putting a user in these groups changes.

Outside collaborators

It seems like they are not validated?

What happened was:

  1. the member was flagged as having all 3 issues
  2. the member has addressed 2fa and full name
  3. the member was changed to outside collaborator and added to users.txt at the same time
  4. after running gu-who the issue was not closed

Add deployment process in readme

Thanks for the great work :)

Tried to deploy to heroku from the fork.
The app crashes with this error, the secret is missing, trying to figure it out...

2016-06-07T11:09:12.891646+00:00 heroku[router]: at=info method=GET path="/" host=mol-gu-who.herokuapp.com request_id=98116e43-c0f1-4cd1-a931-aa1c8e2118e2 fwd="195.234.242.6" dyno=web.1 connect=0ms service=271ms status=500 bytes=2296
2016-06-07T11:09:12.802735+00:00 app[web.1]: [error] p.a.l.CryptoConfigParser - The application secret has not been set, and we are in prod mode. Your application is not secure.
2016-06-07T11:09:12.807093+00:00 app[web.1]: [error] p.a.l.CryptoConfigParser - To set the application secret, please read http://playframework.com/documentation/latest/ApplicationSecret
2016-06-07T11:09:12.828670+00:00 app[web.1]: [error] p.c.s.n.PlayDefaultUpstreamHandler - Cannot invoke the action
2016-06-07T11:09:12.828680+00:00 app[web.1]: com.google.inject.ProvisionException: Unable to provision, see the following errors:
2016-06-07T11:09:12.828702+00:00 app[web.1]: 
2016-06-07T11:09:12.828703+00:00 app[web.1]: 1) Error in custom provider, @70b975c16: Configuration error
2016-06-07T11:09:12.828704+00:00 app[web.1]:   while locating play.api.libs.CryptoConfigParser
2016-06-07T11:09:12.828705+00:00 app[web.1]:     for parameter 0 at play.api.libs.Crypto.<init>(Crypto.scala:282)
2016-06-07T11:09:12.828705+00:00 app[web.1]:   while locating play.api.libs.CryptoConfig
2016-06-07T11:09:12.828706+00:00 app[web.1]:   at play.api.inject.BuiltinModule.bindings(BuiltinModule.scala:49):
2016-06-07T11:09:12.828707+00:00 app[web.1]: Binding(class play.api.libs.Crypto to self) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
2016-06-07T11:09:12.828707+00:00 app[web.1]:   while locating play.api.libs.Crypto
2016-06-07T11:09:12.828708+00:00 app[web.1]: 
2016-06-07T11:09:12.828710+00:00 app[web.1]:    at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1051) ~[com.google.inject.guice-4.0.jar:na]
2016-06-07T11:09:12.828708+00:00 app[web.1]: 1 error
2016-06-07T11:09:12.828711+00:00 app[web.1]:    at play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:316) ~[com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.828711+00:00 app[web.1]:    at play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:321) ~[com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.828712+00:00 app[web.1]:    at play.api.Application$$anonfun$instanceCache$1.apply(Application.scala:235) ~[com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.828712+00:00 app[web.1]:    at play.api.Application$$anonfun$instanceCache$1.apply(Application.scala:235) ~[com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.828709+00:00 app[web.1]:    at com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1025) ~[com.google.inject.guice-4.0.jar:na]
2016-06-07T11:09:12.828713+00:00 app[web.1]:    at play.utils.InlineCache.fresh(InlineCache.scala:69) ~[com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.828714+00:00 app[web.1]:    at play.api.libs.Crypto$.crypto(Crypto.scala:43) ~[com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.828713+00:00 app[web.1]:    at scala.Option.fold(Option.scala:158) ~[org.scala-lang.scala-library-2.11.7.jar:na]
2016-06-07T11:09:12.828713+00:00 app[web.1]:    at play.utils.InlineCache.apply(InlineCache.scala:55) ~[com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.828716+00:00 app[web.1]:    at play.api.libs.CryptoConfigParser.get(Crypto.scala:197) ~[com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.828715+00:00 app[web.1]:    at play.api.libs.CryptoConfigParser.get$lzycompute(Crypto.scala:236) ~[com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.828714+00:00 app[web.1]: Caused by: play.api.PlayException: Configuration error[Application secret not set]
2016-06-07T11:09:12.828716+00:00 app[web.1]:    at com.google.inject.internal.BoundProviderFactory.provision(BoundProviderFactory.java:72) ~[com.google.inject.guice-4.0.jar:na]
2016-06-07T11:09:12.828717+00:00 app[web.1]:    at com.google.inject.internal.ProviderInternalFactory.circularGet(ProviderInternalFactory.java:61) ~[com.google.inject.guice-4.0.jar:na]
2016-06-07T11:09:12.828716+00:00 app[web.1]:    at com.google.inject.internal.ProviderInternalFactory.provision(ProviderInternalFactory.java:81) ~[com.google.inject.guice-4.0.jar:na]
2016-06-07T11:09:12.828717+00:00 app[web.1]:    at com.google.inject.internal.BoundProviderFactory.get(BoundProviderFactory.java:62) ~[com.google.inject.guice-4.0.jar:na]
2016-06-07T11:09:12.828718+00:00 app[web.1]:    at com.google.inject.internal.SingleParameterInjector.inject(SingleParameterInjector.java:38) ~[com.google.inject.guice-4.0.jar:na]
2016-06-07T11:09:12.828718+00:00 app[web.1]:    at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:104) ~[com.google.inject.guice-4.0.jar:na]
2016-06-07T11:09:12.828718+00:00 app[web.1]:    at com.google.inject.internal.SingleParameterInjector.getAll(SingleParameterInjector.java:62) ~[com.google.inject.guice-4.0.jar:na]
2016-06-07T11:09:12.828715+00:00 app[web.1]:    at play.api.libs.CryptoConfigParser.get(Crypto.scala:203) ~[com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.838948+00:00 app[web.1]:  
2016-06-07T11:09:12.838949+00:00 app[web.1]: play.api.UnexpectedException: Unexpected exception[ProvisionException: Unable to provision, see the following errors:
2016-06-07T11:09:12.838945+00:00 app[web.1]: 
2016-06-07T11:09:12.838947+00:00 app[web.1]: ! @70b975c29 - Internal server error, for (GET) [/] ->
2016-06-07T11:09:12.838949+00:00 app[web.1]: 
2016-06-07T11:09:12.838929+00:00 app[web.1]: [error] application - 
2016-06-07T11:09:12.838950+00:00 app[web.1]: 1) Error in custom provider, @70b975c16: Configuration error
2016-06-07T11:09:12.838950+00:00 app[web.1]:   while locating play.api.libs.CryptoConfigParser
2016-06-07T11:09:12.838952+00:00 app[web.1]:     for parameter 0 at play.api.libs.Crypto.<init>(Crypto.scala:282)
2016-06-07T11:09:12.838953+00:00 app[web.1]:   at play.api.inject.BuiltinModule.bindings(BuiltinModule.scala:49):
2016-06-07T11:09:12.838954+00:00 app[web.1]: Binding(class play.api.libs.Crypto to self) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
2016-06-07T11:09:12.838951+00:00 app[web.1]:   while locating play.api.libs.CryptoConfig
2016-06-07T11:09:12.838954+00:00 app[web.1]:   while locating play.api.libs.Crypto
2016-06-07T11:09:12.838955+00:00 app[web.1]: 1 error]
2016-06-07T11:09:12.838955+00:00 app[web.1]: 
2016-06-07T11:09:12.838958+00:00 app[web.1]:    at play.api.GlobalSettings$class.onError(GlobalSettings.scala:179) [com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.838956+00:00 app[web.1]:    at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:261) ~[com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.838957+00:00 app[web.1]:    at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:191) ~[com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.838960+00:00 app[web.1]:    at play.api.http.GlobalSettingsHttpErrorHandler.onServerError(HttpErrorHandler.scala:94) [com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.838961+00:00 app[web.1]:    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3.applyOrElse(PlayDefaultUpstreamHandler.scala:262) [com.typesafe.play.play-netty-server_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.838960+00:00 app[web.1]:    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3.applyOrElse(PlayDefaultUpstreamHandler.scala:266) [com.typesafe.play.play-netty-server_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.838963+00:00 app[web.1]:    at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:344) [org.scala-lang.scala-library-2.11.7.jar:na]
2016-06-07T11:09:12.838959+00:00 app[web.1]:    at play.api.mvc.WithFilters.onError(Filters.scala:93) [com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.838963+00:00 app[web.1]:    at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:343) [org.scala-lang.scala-library-2.11.7.jar:na]
2016-06-07T11:09:12.838966+00:00 app[web.1]: 1) Error in custom provider, @70b975c16: Configuration error
2016-06-07T11:09:12.838964+00:00 app[web.1]:    at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32) [org.scala-lang.scala-library-2.11.7.jar:na]
2016-06-07T11:09:12.838968+00:00 app[web.1]:     for parameter 0 at play.api.libs.Crypto.<init>(Crypto.scala:282)
2016-06-07T11:09:12.838965+00:00 app[web.1]: Caused by: com.google.inject.ProvisionException: Unable to provision, see the following errors:
2016-06-07T11:09:12.838969+00:00 app[web.1]:   at play.api.inject.BuiltinModule.bindings(BuiltinModule.scala:49):
2016-06-07T11:09:12.838970+00:00 app[web.1]: Binding(class play.api.libs.Crypto to self) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
2016-06-07T11:09:12.838966+00:00 app[web.1]: 
2016-06-07T11:09:12.838973+00:00 app[web.1]:    at com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1025) ~[com.google.inject.guice-4.0.jar:na]
2016-06-07T11:09:12.838967+00:00 app[web.1]:   while locating play.api.libs.CryptoConfigParser
2016-06-07T11:09:12.838968+00:00 app[web.1]:   while locating play.api.libs.CryptoConfig
2016-06-07T11:09:12.838975+00:00 app[web.1]:    at play.api.Application$$anonfun$instanceCache$1.apply(Application.scala:235) ~[com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.838973+00:00 app[web.1]:    at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1051) ~[com.google.inject.guice-4.0.jar:na]
2016-06-07T11:09:12.838976+00:00 app[web.1]:    at play.api.Application$$anonfun$instanceCache$1.apply(Application.scala:235) ~[com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.838975+00:00 app[web.1]:    at play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:316) ~[com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.838971+00:00 app[web.1]: 
2016-06-07T11:09:12.838972+00:00 app[web.1]: 1 error
2016-06-07T11:09:12.838978+00:00 app[web.1]:    at play.utils.InlineCache.apply(InlineCache.scala:55) ~[com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.838978+00:00 app[web.1]:    at scala.Option.fold(Option.scala:158) ~[org.scala-lang.scala-library-2.11.7.jar:na]
2016-06-07T11:09:12.838980+00:00 app[web.1]: Caused by: play.api.PlayException: Configuration error[Application secret not set]
2016-06-07T11:09:12.838971+00:00 app[web.1]:   while locating play.api.libs.Crypto
2016-06-07T11:09:12.839004+00:00 app[web.1]:    at play.api.libs.CryptoConfigParser.get(Crypto.scala:197) ~[com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.838981+00:00 app[web.1]:    at play.api.libs.CryptoConfigParser.get(Crypto.scala:203) ~[com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.839005+00:00 app[web.1]:    at com.google.inject.internal.ProviderInternalFactory.provision(ProviderInternalFactory.java:81) ~[com.google.inject.guice-4.0.jar:na]
2016-06-07T11:09:12.838977+00:00 app[web.1]:    at play.utils.InlineCache.fresh(InlineCache.scala:69) ~[com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.839005+00:00 app[web.1]:    at com.google.inject.internal.BoundProviderFactory.provision(BoundProviderFactory.java:72) ~[com.google.inject.guice-4.0.jar:na]
2016-06-07T11:09:12.838979+00:00 app[web.1]:    at play.api.libs.Crypto$.crypto(Crypto.scala:43) ~[com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.838974+00:00 app[web.1]:    at play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:321) ~[com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.839025+00:00 app[web.1]:    at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:104) ~[com.google.inject.guice-4.0.jar:na]
2016-06-07T11:09:12.839008+00:00 app[web.1]:    at com.google.inject.internal.SingleParameterInjector.inject(SingleParameterInjector.java:38) ~[com.google.inject.guice-4.0.jar:na]
2016-06-07T11:09:12.838980+00:00 app[web.1]:    at play.api.libs.CryptoConfigParser.get$lzycompute(Crypto.scala:236) ~[com.typesafe.play.play_2.11-2.4.4.jar:2.4.4]
2016-06-07T11:09:12.839006+00:00 app[web.1]:    at com.google.inject.internal.ProviderInternalFactory.circularGet(ProviderInternalFactory.java:61) ~[com.google.inject.guice-4.0.jar:na]
2016-06-07T11:09:12.839007+00:00 app[web.1]:    at com.google.inject.internal.BoundProviderFactory.get(BoundProviderFactory.java:62) ~[com.google.inject.guice-4.0.jar:na]
2016-06-07T11:09:12.839008+00:00 app[web.1]:    at com.google.inject.internal.SingleParameterInjector.getAll(SingleParameterInjector.java:62) ~[com.google.inject.guice-4.0.jar:na]

bot user and access token requirements

Maybe I'm missing it somewhere, but the start-to-finish steps for running this seem a little unclear. I've gleaned that you need a bot server running gu-who (done that) and you also need a people repo (done that), but there's some other details that are referenced in passing without enough detail, such as:

  1. I'm assuming a bot github user needs to be created -- what kind of access? just to the people repo? etc.
  2. What scopes should be enabled on the access token (per https://developer.github.com/v3/oauth/#scopes)?

Would really love a step-by-step list for the whole process like this:

  1. setup bot server
  2. create people repo
  3. create bot user
  4. generate key

Even if those steps just link off to existing READMEs.

Thanks! Looks like a cool tool.

Heroku request timeout

In my case the app always times out with this message on the page:

Application Error
An error occurred in the application and your page could not be served. Please try again in a few moments.
If you are the application owner, check your logs for details.

The logs are ok, the actual audit is successful and all the issues are created/updated.

The timeout is 30 sec and according to docs it is not configurable.

The solution is to serve page first and then dynamically serve results.

Or at least start sending the static page heading and once the results are ready finish sending the page - it would increase the timeout by 55 sec.

Application does not run in a path that contains spaces

While starting up the application in a fresh environment I got this error:

/Users/timmattison/Google Drive/gu-who/target/universal/stage/bin/gu-who: line 12: cd: /Users/timmattison/Google: No such file or directory
/Users/timmattison/Google Drive/gu-who/target/universal/stage/bin/gu-who: line 12: cd: /Users/timmattison/Google: No such file or directory
/Users/timmattison/Google Drive/gu-who/target/universal/stage/bin/gu-who: line 12: cd: /Users/timmattison/Google: No such file or directory
/Users/timmattison/Google Drive/gu-who/target/universal/stage/bin/gu-who: line 356: cd: /Users/timmattison/Google Drive/gu-who/gu-who/..: No such file or directory
Error: Could not find or load main class play.core.server.NettyServer

It looks like double quotes might fix that (unless someone has double quotes in the dir name) or some other kind of escaping.

Different lints for Pull vs Push members

Some people in the organization are added to read only groups so they can be assigned tasks, but not pull permission because they might not be coding at all.

If they only have Pull permission to the repo, the 2 factor isn't really important (good idea though), but a full profile should be required.

The current assumption is that the "all" users have pull permission to the repo.
edit: updated title to reflect pull = read, and push = write

Users allowed to sponsor themselves

There should be logic that requires the sponsor username to be different than the sponsored username. You shouldn't be able to sponsor yourself!

Handle org where 'all' team doesn't have access to 'people' repo

If the 'all' team doesn't have access to the 'people' repo, members of the org (who don't have read access to the 'people' repo) can not be assigned to issues in that repo - and so gu-who crashes.

We should probably automatically make the 'all' team have access to the people repo, or at least let the user know it's a problem.

Allow anonymous users

Some users would prefer to not fill in their full name to stay anonymous (in order to avoid targeted bullying, recruiters, bot traffic…).

I was wondering if there could be a "anonymous" team that would wave the full name requirement.

NullPointerException after selecting organization

I am running from master (ffba45d) and I'm experiencing a consistent NullPointerException after I pasted in my API key and then select my organization. Relevant log section below.

This is not issue #12 since that commit has already been merged. The NullPointerException appears to occur in a different place.

Play server process ID is 17644
[info] play - Application started (Prod)
[info] play - Listening for HTTP on /0:0:0:0:0:0:0:0:9000
[info] application - Asked to audit @company
[info] application - Cloning new Git repo...
[info] application - Open issue count: Success(0)
[info] application - bots team count: Success(0)
[info] application - 2fa_disabled count: Success(62)
[info] application - User count: Success(73)
[error] play - Cannot invoke the action, eventually got an error: java.lang.NullPointerException
[error] application - 

! @6ig86e160 - Internal server error, for (POST) [/audit/company] ->

play.api.Application$$anon$1: Execution exception[[NullPointerException: null]]
    at play.api.Application$class.handleError(Application.scala:296) ~[com.typesafe.play.play_2.10-2.3.0.jar:2.3.0]
    at play.api.DefaultApplication.handleError(Application.scala:402) [com.typesafe.play.play_2.10-2.3.0.jar:2.3.0]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$4.apply(PlayDefaultUpstreamHandler.scala:320) [com.typesafe.play.play_2.10-2.3.0.jar:2.3.0]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$4.apply(PlayDefaultUpstreamHandler.scala:320) [com.typesafe.play.play_2.10-2.3.0.jar:2.3.0]
    at scala.Option.map(Option.scala:145) [org.scala-lang.scala-library-2.10.4.jar:na]
Caused by: java.lang.NullPointerException: null
    at org.eclipse.jgit.internal.storage.file.UnpackedObjectCache$Table.index(UnpackedObjectCache.java:146) ~[org.eclipse.jgit.org.eclipse.jgit-3.3.0.201403021825-r.jar:3.3.0.201403021825-r]
    at org.eclipse.jgit.internal.storage.file.UnpackedObjectCache$Table.contains(UnpackedObjectCache.java:109) ~[org.eclipse.jgit.org.eclipse.jgit-3.3.0.201403021825-r.jar:3.3.0.201403021825-r]
    at org.eclipse.jgit.internal.storage.file.UnpackedObjectCache.isUnpacked(UnpackedObjectCache.java:64) ~[org.eclipse.jgit.org.eclipse.jgit-3.3.0.201403021825-r.jar:3.3.0.201403021825-r]
    at org.eclipse.jgit.internal.storage.file.ObjectDirectory.openObject(ObjectDirectory.java:367) ~[org.eclipse.jgit.org.eclipse.jgit-3.3.0.201403021825-r.jar:3.3.0.201403021825-r]
    at org.eclipse.jgit.internal.storage.file.WindowCursor.open(WindowCursor.java:145) ~[org.eclipse.jgit.org.eclipse.jgit-3.3.0.201403021825-r.jar:3.3.0.201403021825-r]

Hosted and self-hosted instances of gu-who appear to be broken?

Hi, I've just tried running gu-who against a test organisation both through https://gu-who.herokuapp.com and through a test instance I spun up myself on Heroku, and both error when trying to audit that organisation (URL: https://gu-who.herokuapp.com/audit/MOJ-gu-who-test) despite the app being granted the correct permissions, whether when using a pre-generated access token or using GitHub login.

The error page says “This exception has been logged with id 781o327gn.” (or similar; the ID is different every time).

Do you have any suggestions for what I might do to resolve this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.