commit d9421f9996c2444b84ba20869b74e55ae70e3101 Author: Riku Rouvila Date: Wed Jan 14 18:14:37 2015 +0200 initial commit diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..e1e62b8 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +# http://editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..95b863a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +config.json +node_modules diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..c1f2978 --- /dev/null +++ b/.jshintrc @@ -0,0 +1,3 @@ +{ + "node": true +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..25fc9e4 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# koodiklinikka.fi API diff --git a/deploy/deploy.sh b/deploy/deploy.sh new file mode 100644 index 0000000..e524231 --- /dev/null +++ b/deploy/deploy.sh @@ -0,0 +1,18 @@ +#!/bin/bash +set -e + +export ANSIBLE_SSH_ARGS="-o ForwardAgent=yes" + +# Install dependencies +if ! which pip > /dev/null; then + echo "Installing pip (requires sudo password)" + sudo apt-get install python-pip || sudo easy_install pip +fi + +if ! which ansible > /dev/null; then + echo "Installing ansible (requires sudo password)" + sudo pip install ansible +fi + +cd $(dirname $0) +ansible-playbook deploy.yml -i hosts diff --git a/deploy/deploy.yml b/deploy/deploy.yml new file mode 100644 index 0000000..4afced7 --- /dev/null +++ b/deploy/deploy.yml @@ -0,0 +1,56 @@ +--- +- name: Deploy API + hosts: all:!localhost + remote_user: "{{ service_user }}" + gather_facts: no + vars_files: + - vars.yml + tasks: + - name: Deploy from git + action: > + git + repo="{{ repository_url }}" + dest="{{ projects_path }}" + accept_hostkey=True + notify: restart service + + - name: Setup bot config + copy: > + src=/opt/web/config/api.json + dest="{{ projects_path }}/config.json" + owner=web + group=web + mode=0644 + notify: restart service + + - name: Install NVM + action: > + git + repo="https://github.com/creationix/nvm" + dest="{{ nvm_path }}" + + - name: Make sure Node.js is installed and properly aliased + command: > + bash -c "source {{ nvm_script }} && nvm install {{ nodejs_version }} && nvm alias {{ project_name }} {{ nodejs_version }}" + register: nvm_result + changed_when: > + "already installed" not in nvm_result.stdout + notify: restart service + + - name: Install NPM dependencies and build assets + command: > + bash -c "source {{ nvm_script }} && nvm use {{ project_name }} && cd {{ projects_path }} && npm install" + notify: restart service + + - name: Setup Upstart config + template: > + src=templates/upstart.j2 + dest="/etc/init/{{ project_name }}.conf" + mode=664 + notify: restart service + + handlers: + - name: restart service + service: > + name={{ project_name }} + state=restarted diff --git a/deploy/hosts b/deploy/hosts new file mode 100644 index 0000000..d5dd70d --- /dev/null +++ b/deploy/hosts @@ -0,0 +1 @@ +koodiklinikka.fi diff --git a/deploy/templates/upstart.j2 b/deploy/templates/upstart.j2 new file mode 100644 index 0000000..3ae9685 --- /dev/null +++ b/deploy/templates/upstart.j2 @@ -0,0 +1,12 @@ +description "koodiklinikka.fi API" +author "Riku Rouvila " + +start on runlevel [2345] +stop on runlevel [016] + +respawn +respawn limit 10 5 +env NODE_ENV=production +exec su -s /bin/bash -c 'source {{ nvm_script }} && nvm use {{ project_name }} && cd {{ projects_path }} && exec "$0" "$@"' {{ service_user }} -- \ + node index.js \ + >> /var/log/{{ project_name }}.log 2>&1 diff --git a/deploy/vars.yml b/deploy/vars.yml new file mode 100644 index 0000000..d331482 --- /dev/null +++ b/deploy/vars.yml @@ -0,0 +1,8 @@ +--- +project_name: koodiklinikka.fi-api +projects_path: /opt/web/koodiklinikka.fi-api +repository_url: git@github.com:koodiklinikka/koodiklinikka.fi-api.git +service_user: web +nvm_path: /opt/web/nvm +nvm_script: /opt/web/nvm/nvm.sh +nodejs_version: v0.10.25 diff --git a/index.js b/index.js new file mode 100644 index 0000000..fe63475 --- /dev/null +++ b/index.js @@ -0,0 +1,16 @@ +'use strict'; + +var express = require('express'); +var bodyParser = require('body-parser'); +var app = express(); + +app.use(bodyParser.json()); +require('./routes/invite')(app); + +app.use(function(err, req, res, next) { + console.error(err.message); + console.error(err.stack); + res.status(500).send('Internal server error'); +}); + +app.listen(9000); diff --git a/lib/config.js b/lib/config.js new file mode 100644 index 0000000..7e06070 --- /dev/null +++ b/lib/config.js @@ -0,0 +1,7 @@ +'use strict'; + +var _ = require('lodash'); +var config = require('../config.json'); +var env = process.env.NODE_ENV || 'development'; + +module.exports = _.merge({}, config.all, config[env]); diff --git a/package.json b/package.json new file mode 100644 index 0000000..12ccc84 --- /dev/null +++ b/package.json @@ -0,0 +1,26 @@ +{ + "name": "koodiklinikka.fi-api", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git@github.com:koodiklinikka/koodiklinikka.fi-api.git" + }, + "author": "Riku Rouvila", + "license": "MIT", + "bugs": { + "url": "https://github.com/koodiklinikka/koodiklinikka.fi-api/issues" + }, + "homepage": "https://github.com/koodiklinikka/koodiklinikka.fi-api", + "dependencies": { + "body-parser": "^1.10.1", + "express": "^4.11.0", + "lodash": "^2.4.1", + "superagent": "^0.21.0", + "validator": "^3.27.0" + } +} diff --git a/routes/invite.js b/routes/invite.js new file mode 100644 index 0000000..f057336 --- /dev/null +++ b/routes/invite.js @@ -0,0 +1,40 @@ +'use strict'; + +var validator = require('validator'); +var config = require('../lib/config'); +var request = require('superagent'); + + +module.exports = function (app) { + /* + * POST /invites + * Endpoint for sending invitations automatically + */ + + app.post('/invites', function(req, res, next) { + + if(!validator.isEmail(req.body.email)) { + res.status(400).send('Invalid email'); + } + + request + .post('https://koodiklinikka.slack.com/api/users.admin.invite') + .field('email', req.body.email) + .field('channels', config.slack.channels) + .field('token', config.slack.token) + .field('set_active', 'true') + .end(function(error, response){ + if(error) { + return next(error); + } + + if(!response.body.ok) { + return next(new Error('Creating slack invitation failed')); + } + + res.status(200).end(); + }); + + }); + +};