UNPKG

pimatic

Version:

A home automation server and framework for the Raspberry PI running on node.js

145 lines (123 loc) 4.7 kB
__ = require("i18n-pimatic").__ Promise = require 'bluebird' assert = require 'cassert' _ = require 'lodash' S = require 'string' crypto = require 'crypto' module.exports = (env) -> class UserManager _allowPublicAccessCallbacks: [] constructor: (@framework, @users, @roles) -> #nop addUser: (username, user) -> if _.findIndex(@users, {username: username}) isnt -1 throw new Error('A user with this username already exists') unless user.username? throw new Error('No username given') unless user.role? throw new Error('No role given') @users.push( user = { username: username password: user.password role: user.role }) @framework.saveConfig() @framework._emitUserAdded(user) return page updateUser: (username, user) -> assert typeof username is "string" assert typeof page is "object" assert(if user.username? then typeof user.username is "string" else true) assert(if user.password? then typeof user.password is "string" else true) assert(if user.role? then typeof user.role is "string" else true) theuser = @getUserByUsername(username) unless theuser? throw new Error('User not found') theuser.username = page.username if page.username? theuser.password = page.password if page.password? theuser.role = page.role if page.role? @framework.saveConfig() @framework._emitUserChanged(theuser) return theuser getUserByUsername: (username) -> _.find(@users, {username: username}) hasPermission: (username, scope, access) -> assert scope in [ "pages", "rules", "variables", "messages", "config" "events", "devices", "groups", "plugins", "updates", "database" ] assert access in ["read", "write", "none"] user = @getUserByUsername(username) unless user? throw new Error('User not found') assert typeof user.role is "string" role = @getRoleByName(user.role) unless role? throw new Error("No role with name #{user.role} found.") permission = role.permissions[scope] unless permission? throw new Error("No permissions for #{scope} of #{user.role} found.") switch access when "read" return (permission is "read" or permission is "write") when "write" return (permission is "write") when "none" return yes else return no hasPermissionBoolean: (username, scope) -> user = @getUserByUsername(username) unless user? throw new Error('User not found') assert typeof user.role is "string" role = @getRoleByName(user.role) unless role? throw new Error("No role with name #{user.role} found.") permission = role.permissions[scope] unless permission? throw new Error("No permissions for #{scope} of #{user.role} found.") return (permission is true) checkLogin: (username, password) -> assert typeof username is "string" assert typeof password is "string" if username.length is 0 then return false user = @getUserByUsername(username) unless user? return false return password is user.password getRoleByName: (name) -> assert typeof name is "string" role = _.find(@roles, {name: name}) return role getPermissionsByUsername: (username) -> user = @getUserByUsername(username) unless user? throw new Error('User not found') role = @getRoleByName(user.role) unless role? throw new Error("No role with name #{user.role} found.") return role.permissions getLoginTokenForUsername: (secret, username) -> assert typeof username is "string" assert username.length > 0 assert typeof secret is "string" assert secret.length >= 32 user = @getUserByUsername(username) unless user? throw new Error('User not found') assert typeof user.password is "string" assert user.password.length > 0 shasum = crypto.createHash('sha256') shasum.update(secret, 'utf8') shasum.update(user.password, 'utf8') loginToken = shasum.digest('hex') return loginToken checkLoginToken: (secret, username, loginToken) -> return loginToken is @getLoginTokenForUsername(secret, username) isPublicAccessAllowed: (req) -> for allow in @_allowPublicAccessCallbacks if allow(req) then return yes return no addAllowPublicAccessCallback: (callback) -> @_allowPublicAccessCallbacks.push callback return exports = { UserManager }