init (copied from thirdpartydatastore-sharelatex)

This commit is contained in:
Shane Kilkelly 2016-03-25 11:04:46 +00:00
commit fc3c0d1384
6 changed files with 262 additions and 0 deletions

View file

@ -0,0 +1,62 @@
compileFolder
Compiled source #
###################
*.com
*.class
*.dll
*.exe
*.o
*.so
# Packages #
############
# it's better to unpack these files and commit the raw source
# git has its own built in compression methods
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip
# Logs and databases #
######################
*.log
*.sql
*.sqlite
# OS generated files #
######################
.DS_Store?
ehthumbs.db
Icon?
Thumbs.db
/node_modules/*
test/IntergrationTests/js/*
data/*/*
app.js
app/js/*
lib/js/*
test/IntergrationTests/js/*
test/UnitTests/js/*
cookies.txt
uploads/*
public/js/editor.js
public/js/home.js
public/js/forms.js
public/js/gui.js
public/js/admin.js
public/stylesheets/mainStyle.css
public/minjs/
test/unit/js/
test/acceptance/js
**.swp
/log.json
hash_folder

View file

@ -0,0 +1,56 @@
spawn = require("child_process").spawn
module.exports = (grunt) ->
grunt.initConfig
coffee:
# app_src:
# expand: true,
# cwd: "app/coffee"
# src: ['**/*.coffee'],
# dest: 'app/js/',
# ext: '.js'
# app:
# src: "app.coffee"
# dest: "app.js"
unit_tests:
expand: true
cwd: "test/unit/coffee"
src: ["**/*.coffee"]
dest: "test/unit/js/"
ext: ".js"
# acceptance_tests:
# expand: true
# cwd: "test/acceptance/coffee"
# src: ["**/*.coffee"]
# dest: "test/acceptance/js/"
# ext: ".js"
clean:
app: ["lib/js/"]
unit_tests: ["test/unit/js"]
mochaTest:
unit:
options:
reporter: grunt.option('reporter') or 'spec'
grep: grunt.option("grep")
src: ["test/unit/js/**/*.js"]
grunt.loadNpmTasks 'grunt-contrib-coffee'
grunt.loadNpmTasks 'grunt-contrib-clean'
grunt.loadNpmTasks 'grunt-mocha-test'
grunt.loadNpmTasks 'grunt-execute'
grunt.loadNpmTasks 'grunt-bunyan'
grunt.registerTask 'compile:unit_tests', ['clean:unit_tests', 'coffee:unit_tests']
grunt.registerTask 'test:unit', ['compile:unit_tests', 'mochaTest:unit']
grunt.registerTask 'compile:acceptance_tests', ['clean:acceptance_tests', 'coffee:acceptance_tests']
grunt.registerTask 'test:acceptance', ['compile:acceptance_tests', 'mochaTest:acceptance']
grunt.registerTask 'install', 'compile:app'
grunt.registerTask 'default', ['run']

View file

@ -0,0 +1,2 @@
require('coffee-script');
module.exports = require('./lib/coffee/AccessTokenEncryptor.coffee');

View file

@ -0,0 +1,44 @@
crypto = require('crypto')
settings = require('settings-sharelatex')
cipherLabel = settings.cipherLabel
throw Error("cipherLabel must not contain a colon (:)") if cipherLabel?.match(/:/)
cipherPassword = settings.cipherPasswords[settings.cipherLabel]
throw Error("cipherPassword not set") if not cipherPassword?
throw Error("cipherPassword too short") if cipherPassword.length < 16
ALGORITHM = 'aes-256-ctr'
keyFn = (password, salt, callback)->
return crypto.pbkdf2(password, salt, 10000, 64, callback)
module.exports =
encryptJson: (json, callback)->
string = JSON.stringify(json)
salt = crypto.randomBytes(16)
keyFn cipherPassword, salt, (err, key)->
if err?
logger.err err:err, "error getting Fn key"
return callback(err)
cipher = crypto.createCipher(ALGORITHM, key)
crypted = cipher.update(string, 'utf8', 'base64') + cipher.final('base64')
callback(null, cipherLabel + ":" + salt.toString('hex') + ":" + crypted)
decryptToJson: (encryptedJson, callback)->
[label, salt, cipherText] = encryptedJson.split(':', 3)
password = settings.cipherPasswords[label]
return callback(new Error("invalid password")) if not password? or password.length < 16
keyFn password, new Buffer(salt, 'hex'), (err, key)->
if err?
logger.err err:err, "error getting Fn key"
return callback(err)
decipher = crypto.createDecipher(ALGORITHM, key)
dec = decipher.update(cipherText, 'base64', 'utf8') + decipher.final('utf8')
try
json = JSON.parse(dec)
catch e
return callback(new Error("error decrypting token"))
callback(null, json)

View file

@ -0,0 +1,28 @@
{
"name": "access-token-encryptor-sharelatex",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "Proprietary",
"dependencies": {
"coffee-script": "^1.10.0",
"settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#master"
},
"devDependencies": {
"nock": "0.15.2",
"sandboxed-module": "",
"sinon": "",
"chai": "",
"grunt-contrib-clean": "~0.5.0",
"grunt-mocha-test": "~0.10.2",
"grunt-contrib-coffee": "~0.10.1",
"grunt": "~0.4.5",
"grunt-execute": "~0.2.1",
"bunyan": "~0.22.3",
"grunt-bunyan": "~0.5.0"
}
}

View file

@ -0,0 +1,70 @@
sinon = require('sinon')
chai = require('chai')
should = chai.should()
expect = chai.expect
modulePath = "../../../index.js"
SandboxedModule = require('sandboxed-module')
path = require('path')
describe 'AccessTokenEncryptor', ->
beforeEach ->
@testObject = {"hello":"world"}
@Encrypted = "2016.1:6e7ac79ab13a18b5749eace965ec7962:sAAYt1yQZqpvOnu6l8iUD/Y="
@oldEncrypted = "2015.1:473a66fb5d816bc716f278ab819d88a5:+mTg7O9sgUND8pNQFG6h2GE="
@badLabel = "xxxxxx:c7a39310056b694c:jQf+Uh5Den3JREtvc82GW5Q="
@badKey = "2015.1:d7a39310056b694c:jQf+Uh5Den3JREtvc82GW5Q="
@badCipherText = "2015.1:c7a39310056b694c:xQf+Uh5Den3JREtvc82GW5Q="
@requires = requires:
"settings-sharelatex":
cipherLabel: "2016.1"
cipherPasswords:
"2016.1": "11111111111111111111111111111111111111"
"2015.1": "22222222222222222222222222222222222222"
@AccessTokenEncryptor = SandboxedModule.require modulePath, @requires
describe "encrypt", ->
it 'should encrypt the object', (done)->
@AccessTokenEncryptor.encryptJson @testObject, (err, encrypted)->
expect(err).to.be.null
encrypted.should.match(/^2016.1:[0-9a-f]+:[a-zA-Z0-9=+\/]+$/)
done()
it 'should encrypt the object differently the next time', (done)->
@AccessTokenEncryptor.encryptJson @testObject, (err, encrypted1)=>
@AccessTokenEncryptor.encryptJson @testObject, (err, encrypted2)=>
encrypted1.should.not.equal(encrypted2)
done()
describe "decrypt", ->
it 'should decrypt the string to get the same object', (done)->
@AccessTokenEncryptor.encryptJson @testObject, (err, encrypted) =>
expect(err).to.be.null
@AccessTokenEncryptor.decryptToJson encrypted, (err, decrypted) =>
expect(err).to.be.null
expect(decrypted).to.deep.equal @testObject
done()
it 'should decrypt an old string to get the same object', (done)->
@AccessTokenEncryptor.decryptToJson @oldEncrypted, (err, decrypted)=>
expect(err).to.be.null
expect(decrypted).to.deep.equal @testObject
done()
it 'should return an error when decrypting an invalid label', (done)->
@AccessTokenEncryptor.decryptToJson @badLabel, (err, decrypted)->
expect(err).to.be.instanceof(Error)
expect(decrypted).to.be.undefined
done()
it 'should return an error when decrypting an invalid key', (done)->
@AccessTokenEncryptor.decryptToJson @badKey, (err, decrypted)->
expect(err).to.be.instanceof(Error)
expect(decrypted).to.be.undefined
done()
it 'should return an error when decrypting an invalid ciphertext',(done)->
@AccessTokenEncryptor.decryptToJson @badCipherText, (err, decrypted)->
expect(err).to.be.instanceof(Error)
expect(decrypted).to.be.undefined
done()