Skip to content
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

[WIP] Accept Github webhooks payload #34

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open

Conversation

smashwilson
Copy link
Collaborator

This is the first step in implementing #5. Add a webhook to your repository with a URL in the following format:

http://<your-ip>:6161/webhooks/receive/<project-id>

... and DCIY will automatically build branches when they're pushed. Pretty neat! It's starting to feel like a proper CI, now.

This is the very core functionality for that ticket, though; it's pretty unrefined. What's left to do:

  • Show new builds live as they happen, with some kind of CoffeeScript polling on projects/:id/builds.
  • Either add a button to register the hook with the GitHub instance, or show you a "help" page that walks you through how to do it.
  • Build incoming pull requests, too! Maybe. This has Security Implications ™️ like @cobyism brought up earlier.

Ash Wilson added 4 commits January 17, 2014 15:16
It turns out that `:repository/:name` in the webhook payload doesn't include
the user or organization prefix. Rather than try to reconstruct it myself, I'll
just include the project id in the callback URL.
We might define 12 fixtures; we probably won't define 9999999.
# POST /webhooks/receive
def receive
push = JSON.parse(params[:payload])
p = Project.where(id: params[:project_id]).take
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How come you need this .take call at the end if you’re querying by id? Surely id is a primary key so only one result is ever going to be returned?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep yep, it is unique, but .where returns an association so we need the .take to pull that (single) result.

I'm using .where().take here because it returns nil if the project id isn't valid, rather than throwing a RecordNotFound exception like Project.find(project_id). By default RecordNotFound renders a 404 with an HTML page, which felt wrong for an API response.

This does feel kind of awkward, though... I think there's a way to control what gets rendered on exceptions, on a per-controller basis, so that would be cleaner. I'll look into it 🔍

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nah, that’s fine and that actually makes a ton of sense. I just didn’t realise that you needed a single result object here instead of an AR association/relation. I wouldn’t worry about looking into it further 👍

@cobyism
Copy link
Owner

cobyism commented Jan 21, 2014

💖 This is awesome! On the security side, I think it might be worth (at least in the short term) implementing some kind of ENV['WEBHOOK_SECRET_KEY'] variable check or something to make it possible to at least be reasonably sure incoming payloads are from the correct source. What are your thoughts on that as a low-tech solution?

@smashwilson
Copy link
Collaborator Author

Hmmm, checking a secret token might let us "verify" that requests are coming from the right source, but that doesn't buy us much. An attacker who knows your DCIY's url could maybe DDoS you by running expensive builds over and over again, but the bigger issue is the code that's actually run as part of the build itself. All someone has to do is submit a pull request that adds a spec:

it "wipes your hard drive clean"

... and you're sunk! You can't even really whitelist PRs, as there's nothing stopping someone from adding bad code to the branch after the fact when you're not looking. (Er, no idea what I was thinking way back at the start with whitelisting commands.)

You'd mentioned using Vagrant and/or Docker to sandbox builds -- I think that's ultimately going to have to be the way we go.

@cobyism
Copy link
Owner

cobyism commented Jan 21, 2014

using Vagrant and/or Docker to sandbox builds -- I think that's ultimately going to have to be the way we go.

Fair enough. Yeah, sandboxing is something I’d really like to make possible eventually anyway, so if that means we can just bank on that then 👍 At the end of the day, if you’re really worried about the security implications here, people should just A) not run it on a machine they care about or have sensitive information on, and/or B) kill the server process when they don’t need it running.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants