Skip to content

Commit

Permalink
Merge branch 'release/dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
ombr committed Aug 17, 2012
2 parents 988a917 + b3cd277 commit 7dc79bf
Show file tree
Hide file tree
Showing 31 changed files with 828 additions and 446 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@ install :
@npm install ./
test:
@./node_modules/mocha/bin/mocha
start-example:
@./node_modules/supervisor/lib/cli-wrapper.js ./examples/server.coffee
watch-test:
@./node_modules/mocha/bin/mocha -w

.PHONY: test
57 changes: 56 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,56 @@
# User Authentification and role management REST Webservice
# Usr Authentification and role management REST OAuth Webservice

Everytime you start a new project or create a new service. You need to code the user authentification and your group management in order to manage you users. With Usr you just have one service and easy rest methods to manage you users and their groups.

## Description

Usr provides you a webservice to authenticate and manage your users with a REST API :

- EveryAuth enable your users to login with any credentials or service (Facebook,...)
- Your users create a unique account for all your services.
- All your futures application can use usr to authentificate your user and get their roles.
- Use any storage (MongoDb, CouchDb, MySQL,..)

## Authentification of a user :

1/ You deploy your service to auth.yourdomain.com
2/ You can use Oauth2 to authentificate your user.


## Status

Currently there is not much working on, but you can user
`make test` to see the status


The goal of this project :

An easy to deploy on cloudfoundry webservice that you can use for any of your project to authenticate your user and manage their groups. I follow oAuth2 specs and maps the group user in the scope.

# Features/Status :

In this first dev release you can find :
- the beginning of the local storage (usefull for testing)
- a Makefile
- Some event capabilities with socket io
- a bad version of authentification with token (will be replace quickly with oauth2)
- Basic and non crypted user authentification
- a bit of group management
- Some tests
- first ideas on access management

Next priorities :
- OAuth2
- More test
- Group and access management
- Full restfull interface
- logs
- coffee lint

Some futures priorities :

- Events with socket.io
- MongoDb/CouchDb/Redis stores
- Admin interface

More is coming....
File renamed without changes.
37 changes: 37 additions & 0 deletions examples/myappnewapp.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
express = require 'express'
$ = require 'jquery'

app = express.createServer(
express.bodyParser(),
express.favicon(),
express.cookieParser(),
express.session({ secret: 'supersecret'}),
)

myAppUrl = 'http://127.0.0.1:3001'
usrAppToken = 'lalalal'
usrUrl = "http://local.host:3000"


app.get('/', (req, res)->
if req.session.user
user = req.session.user
res.send("Welcome : #{user.id}, you are in the groups : #{user.groups.join(',')}<a href='/logout/'>logout</a>")
else
res.send("<a href='#{usrUrl}/login/#{myAppUrl}/logguedIn/'>login</a>")
)

app.get('/logout', (req, res)->
delete(req.session.user)
res.redirect(usrUrl+"/logout/#{myAppUrl}")
)

app.get('/logguedIn/:token', (req, res)->
url = usrUrl+"/info/#{req.params.token}/#{usrAppToken}"
$.getJSON(url,(datas)->
req.session.user = datas
res.redirect('/')
)
)

app.listen(3001)
6 changes: 2 additions & 4 deletions lib/exec.coffee → examples/server.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,18 @@ Async = require 'async'
Log = require 'log'

log = new Log('warning')
configs = require '../configs'
configs = require './configs'

express = require 'express'
app = express.createServer(
express.bodyParser(),
express.static(__dirname + "/public"),
express.favicon(),
express.cookieParser(),
express.session({ secret: 'supersecret'}),
)
app.log = log

Auth = require './app'
Auth = require '../index'
auth = new Auth(app,configs)

app.get('/', (req, res)->
Expand All @@ -29,4 +28,3 @@ app.configure(()->
app.listen(configs.app.port)
log.info __dirname
log.info 'Application started http://local.host:'+configs.app.port
module.exports = app
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
require('coffee-script')
module.exports = require('./lib/exec.coffee');
module.exports = require('./lib/app');
71 changes: 33 additions & 38 deletions lib/access/access.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -13,62 +13,57 @@ module.exports = class Access extends Component
_isUserMemberOfGroup: (userId, groupName)->
_ = @
return (cb)->
try
_.app.stores.group.findGroupByName(groupName, (group)->
_.app.stores.group.isUserMemberOfGroupCache(userId, group.id,(res)->
_.app.stores.group.findGroupByName(groupName, (err,group)->
if err?
if err[0] == 'Not found'
cb(null,false)
return
else
cb(err,null)
return
_.app.stores.group.isUserMemberOfGroupCache(userId, group.id,(err,res)->
cb(null, res)
)
)
catch e
if e == 'Not found'
cb(null, false)
return
throw e

#!TODO improve this function with cache
_checkToken: (token, callbackOK)->
try
@token.getToken(token, (datas)->
#!TODO Token read only ?
#!TODO Token time expiration
if datas.userId?
console.log "TOKEN OK"
callbackOK(datas.userId)
)
catch e
throw e
_checkToken: (token, cb)->
_ = @
@token.getToken(token, (err,datas)->
_.checkErr(err)
#!TODO Token read only ?
#!TODO Token time expiration
if datas.userId?
cb(null,datas.userId)
)

check : (token, groups, cb, action = "undefined") ->
_ = @
@_checkToken(token,
(userId)->
(err,userId)->
_.checkErr(err)
groupCheck = []
for g in groups
groupCheck.push(_._isUserMemberOfGroup(userId, g))
try
require('async').parallel(groupCheck,(err,res)->
if true in res
cb(userId)
_.emit('access/'+action,
granted : true
token : token
userId : userId
groups : groups
)
return
require('async').parallel(groupCheck,(err,res)->
_.checkErr(err)
if true in res
cb(null,userId)
_.emit('access/'+action,
granted : false
granted : true
token : token
userId : userId
groups : groups
)
throw 'Access denied'
return
_.emit('access/'+action,
granted : false
token : token
userId : userId
groups : groups
)
catch e
console.log "ERROR IN CHECK ?#{e}?"
console.log e
throw e
cb(['Access denied'],null)
return
)
)
_add : (groupName, token, cb)->
_ = @
Expand Down
57 changes: 31 additions & 26 deletions lib/app.coffee
Original file line number Diff line number Diff line change
@@ -1,44 +1,49 @@
module.exports = class App
constructor : (app,@configs)->
constructor : (express,@configs)->
_ = @
if not @configs.logger?
Log = require 'log'
@log = new Log("warning")
else
@log = @configs.logger

EventEmitter = require('eventemitter2').EventEmitter2
@_event = new EventEmitter(
wildcard:true
)
@_event.on('*',(infos)->
console.log this.event
console.log infos
_.log.debug "EVENT #{@event} : #{JSON.stringify(infos)}"
)

#!TODO move this function to access...
@_event.once('token/new',(datas)->
console.log "Check INIT ROOT ?"
try
_.stores.group.findGroupByName('root',()->)
catch e
if e == 'Not found'
try
_.stores.group.addGroup('_root',(groupId)->
_.stores.group.addUserToGroup(datas.userId,groupId,(res)->
_.log.debug "First token has been created maybe a root group need to be created ?"
_.stores.group.findGroupByName('root',(err,group)->
if group == null
_.stores.group.addGroup('_root',(err,groupId)->
_.emit('group/new',
groupId : groupId
token : datas.token
)
_.stores.group.addUserToGroup(datas.userId,groupId,(err,res)->
_.emit('group/addUser',
groupId : groupId
token : datas.token
userId : datas.userId
)
_.stores.group.addUserToGroupCache(datas.userId,groupId,(err,res)->
if !res
throw "Error root access granted..."
_.stores.group.addUserToGroupCache(datas.userId,groupId,(res)->
if !res
throw "Error root access granted..."
_.emit('root/new',datas)
)
# Might be a bit strange, but root seems to proclam himself root
_.emit('root/new',datas)
)
)
catch e
console.log "ROOT INIT ERROR"
console.log e
else
throw e

)
)
)
#@log = @app.log
@app = app
@app[ "auth" or @configs.bind] = @ #App binding
@express = express
@express[ "auth" or @configs.bind] = @ #express binding

#Init stores :
@stores = {}
Expand All @@ -50,12 +55,13 @@ module.exports = class App
#Init modules
modules =
'auth' : './auth/auth'
'user' : './user/user'
'group' : './group/group'
'token' : './token/token'
'access' : './access/access'
'event' : './event/event'
for name,file of modules
console.log "Load #{file} as #{name}"
@log.info "Load #{file} as #{name}"
Module = require file
@[name] = new Module(@)

Expand All @@ -82,7 +88,6 @@ module.exports = class App
# Events
###
emit : (args...)->
console.log "EMIT ?"
@event.emit(args...)
on : (args...)->
@event.on(args...)
Loading

0 comments on commit 7dc79bf

Please sign in to comment.