OAuth server: first draft
authorChocobozzz <florian.bigard@gmail.com>
Mon, 21 Mar 2016 10:56:33 +0000 (11:56 +0100)
committerChocobozzz <florian.bigard@gmail.com>
Mon, 21 Mar 2016 10:56:33 +0000 (11:56 +0100)
package.json
server.js
server/controllers/api/v1/index.js
server/controllers/api/v1/users.js [new file with mode: 0644]
server/middlewares/oauth2.js [new file with mode: 0644]
server/models/users.js [new file with mode: 0644]

index a5f32fe1119c86fe9c4defd3bbb3b356f6ff0339..e94d34fa18c714a5df21eb53e8dd589ac9cccfdf 100644 (file)
@@ -31,7 +31,7 @@
     "client:tsc": "cd client && npm run tsc",
     "client:tsc:watch": "cd client && npm run tsc:w",
     "client:tsc:clean": "cd client && find angular -regextype posix-egrep -regex \".*\\.(js|map)$\" -exec rm -f {} \\;",
-    "dev": "npm run build && concurrently \"npm run livereload\" \"npm run client:tsc:watch\" \"npm run client:sass:watch\" \"npm start\"",
+    "dev": "npm run build && NODE_ENV=test concurrently \"npm run livereload\" \"npm run client:tsc:watch\" \"npm run client:sass:watch\" \"npm start\"",
     "livereload": "livereload ./client",
     "start": "node server",
     "test": "standard && mocha server/tests",
@@ -48,6 +48,7 @@
     "dezalgo": "^1.0.3",
     "electron-spawn": "https://github.com/Chocobozzz/electron-spawn",
     "express": "^4.12.4",
+    "express-oauth-server": "https://github.com/oauthjs/express-oauth-server",
     "express-validator": "^2.11.0",
     "js-yaml": "^3.5.4",
     "lodash-node": "^3.10.2",
@@ -62,7 +63,7 @@
     "segfault-handler": "^1.0.0",
     "ursa": "^0.9.1",
     "validator": "^5.0.0",
-    "webtorrent": "^0.85.1",
+    "webtorrent": "^0.86.0",
     "winston": "^2.1.1",
     "ws": "^1.0.1"
   },
index cf594453d24172a63a3642295385e9c34aca8899..f9925eb247c04afbbcecc6fe1ea5616cced3a69f 100644 (file)
--- a/server.js
+++ b/server.js
@@ -119,6 +119,14 @@ app.use(function (err, req, res, next) {
   res.sendStatus(err.status || 500)
 })
 
+// TODO: move into initializer
+require('./server/models/users').createClient('coucou', [ 'password' ], function (err, id) {
+  if (err) throw err
+  logger.info('Client id: ' + id)
+
+  require('./server/models/users').createUser('floflo', 'coucou', function () {})
+})
+
 // ----------- Create the certificates if they don't already exist -----------
 peertubeCrypto.createCertsIfNotExist(function (err) {
   if (err) throw err
index 45f07ae1f449200c242ae1c926189c597bde474e..7b3ec32c054b8b08381fc4b6ebc74325d465e865 100644 (file)
@@ -6,10 +6,12 @@ const router = express.Router()
 
 const podsController = require('./pods')
 const remoteVideosController = require('./remoteVideos')
+const usersController = require('./users')
 const videosController = require('./videos')
 
 router.use('/pods', podsController)
 router.use('/remotevideos', remoteVideosController)
+router.use('/users', usersController)
 router.use('/videos', videosController)
 router.use('/*', badRequest)
 
diff --git a/server/controllers/api/v1/users.js b/server/controllers/api/v1/users.js
new file mode 100644 (file)
index 0000000..acb860c
--- /dev/null
@@ -0,0 +1,22 @@
+'use strict'
+
+var express = require('express')
+var oAuth2 = require('../../../middlewares/oauth2')
+
+const middleware = require('../../../middlewares')
+const cacheMiddleware = middleware.cache
+
+const router = express.Router()
+
+router.post('/token', cacheMiddleware.cache(false), oAuth2.token(), success)
+router.get('/authenticate', cacheMiddleware.cache(false), oAuth2.authenticate(), success)
+
+// ---------------------------------------------------------------------------
+
+module.exports = router
+
+// ---------------------------------------------------------------------------
+
+function success (req, res, next) {
+  res.end()
+}
diff --git a/server/middlewares/oauth2.js b/server/middlewares/oauth2.js
new file mode 100644 (file)
index 0000000..a1fa61f
--- /dev/null
@@ -0,0 +1,11 @@
+'use strict'
+
+const OAuthServer = require('express-oauth-server')
+
+const oAuth2 = new OAuthServer({
+  model: require('../models/users')
+})
+
+// ---------------------------------------------------------------------------
+
+module.exports = oAuth2
diff --git a/server/models/users.js b/server/models/users.js
new file mode 100644 (file)
index 0000000..355d991
--- /dev/null
@@ -0,0 +1,108 @@
+const mongoose = require('mongoose')
+
+const logger = require('../helpers/logger')
+
+// ---------------------------------------------------------------------------
+
+const oAuthTokensSchema = mongoose.Schema({
+  accessToken: String,
+  accessTokenExpiresOn: Date,
+  client: { type: mongoose.Schema.Types.ObjectId, ref: 'oAuthClients' },
+  refreshToken: String,
+  refreshTokenExpiresOn: Date,
+  user: { type: mongoose.Schema.Types.ObjectId, ref: 'users' }
+})
+const OAuthTokensDB = mongoose.model('oAuthTokens', oAuthTokensSchema)
+
+const oAuthClientsSchema = mongoose.Schema({
+  clientSecret: String,
+  grants: Array,
+  redirectUris: Array
+})
+const OAuthClientsDB = mongoose.model('oAuthClients', oAuthClientsSchema)
+
+const usersSchema = mongoose.Schema({
+  password: String,
+  username: String
+})
+const UsersDB = mongoose.model('users', usersSchema)
+
+// ---------------------------------------------------------------------------
+
+const Users = {
+  createClient: createClient,
+  createUser: createUser,
+  getAccessToken: getAccessToken,
+  getClient: getClient,
+  getRefreshToken: getRefreshToken,
+  getUser: getUser,
+  saveToken: saveToken
+}
+
+function createClient (secret, grants, callback) {
+  logger.debug('Creating client.')
+
+  const mongo_id = new mongoose.mongo.ObjectID()
+  return OAuthClientsDB.create({ _id: mongo_id, clientSecret: secret, grants: grants }, function (err) {
+    if (err) return callback(err)
+
+    return callback(null, mongo_id)
+  })
+}
+
+function createUser (username, password, callback) {
+  logger.debug('Creating user.')
+
+  return UsersDB.create({ username: username, password: password }, callback)
+}
+
+function getAccessToken (bearerToken, callback) {
+  logger.debug('Getting access token (bearerToken: ' + bearerToken + ').')
+
+  return OAuthTokensDB.findOne({ accessToken: bearerToken }).populate('user')
+}
+
+function getClient (clientId, clientSecret) {
+  logger.debug('Getting Client (clientId: ' + clientId + ', clientSecret: ' + clientSecret + ').')
+
+  // TODO req validator
+  const mongo_id = new mongoose.mongo.ObjectID(clientId)
+  return OAuthClientsDB.findOne({ _id: mongo_id, clientSecret: clientSecret })
+}
+
+function getRefreshToken (refreshToken) {
+  logger.debug('Getting RefreshToken (refreshToken: ' + refreshToken + ').')
+
+  return OAuthTokensDB.findOne({ refreshToken: refreshToken })
+}
+
+function getUser (username, password) {
+  logger.debug('Getting User (username: ' + username + ', password: ' + password + ').')
+  return UsersDB.findOne({ username: username, password: password })
+}
+
+function saveToken (token, client, user) {
+  logger.debug('Saving token for client ' + client.id + ' and user ' + user.id + '.')
+
+  const token_to_create = {
+    accessToken: token.accessToken,
+    accessTokenExpiresOn: token.accessTokenExpiresOn,
+    client: client.id,
+    refreshToken: token.refreshToken,
+    refreshTokenExpiresOn: token.refreshTokenExpiresOn,
+    user: user.id
+  }
+
+  return OAuthTokensDB.create(token_to_create, function (err, token_created) {
+    if (err) throw err // node-oauth2-server library use Promise.try
+
+    token_created.client = client
+    token_created.user = user
+
+    return token_created
+  })
+}
+
+// ---------------------------------------------------------------------------
+
+module.exports = Users