restructured + sqllite-integration for users
This commit is contained in:
parent
f4f8d1c316
commit
1ddb9eda1b
304
collab.rb
304
collab.rb
|
@ -1,304 +0,0 @@
|
||||||
require 'fileutils'
|
|
||||||
|
|
||||||
POSIX_NAME_PREFIX = "emacs"
|
|
||||||
USER_LOCATION = "./users/"
|
|
||||||
|
|
||||||
$projects = []
|
|
||||||
$users = []
|
|
||||||
$project_id_map = {}
|
|
||||||
$user_id_map = {}
|
|
||||||
|
|
||||||
|
|
||||||
#####################
|
|
||||||
# User manipulation #
|
|
||||||
#####################
|
|
||||||
|
|
||||||
class User
|
|
||||||
attr_accessor :id, :keypath
|
|
||||||
attr_reader :keys
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
"#{@id}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def initialize(id)
|
|
||||||
@id = id
|
|
||||||
@keypath = "#{USER_LOCATION}#{id}"
|
|
||||||
refresh_keys
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_key_from_string(keystring)
|
|
||||||
unless valid_pubkey? keystring
|
|
||||||
raise InvalidSSHPubKey, "Public key not valid"
|
|
||||||
end
|
|
||||||
ks = keystring.split(" ");
|
|
||||||
key = SSHKey.new(ks[0][4..6], ks[1], ks[2])
|
|
||||||
|
|
||||||
unless @keys.include? key
|
|
||||||
@keys << key
|
|
||||||
else
|
|
||||||
raise DuplicateSSHPubKey, "Public key is already added to user"
|
|
||||||
end
|
|
||||||
|
|
||||||
flush
|
|
||||||
refresh_keys
|
|
||||||
flush_projects_with_user(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
def remove_key(key)
|
|
||||||
@keys.delete(key)
|
|
||||||
flush
|
|
||||||
refresh_keys
|
|
||||||
flush_projects_with_user(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
def refresh_keys
|
|
||||||
#File.open(@keypath,"r") do |f|
|
|
||||||
# @keys = f.read.split("\n").select{ |line| line[0..2] == "ssh" }.map{ |ks| k = ks.split(" "); SSHKey.new(k[0][4..6], k[1], k[2]) }
|
|
||||||
#end
|
|
||||||
end
|
|
||||||
|
|
||||||
def flush
|
|
||||||
File.open(@keypath,"w+") do |key_file|
|
|
||||||
@keys.each do |key|
|
|
||||||
key_file << "#{key.to_s}\n"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_user(id)
|
|
||||||
user = User.new(id)
|
|
||||||
db.add_user(user)
|
|
||||||
$users << user
|
|
||||||
$user_id_map[id] = user
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_user_by_id(id)
|
|
||||||
$user_id_map[id]
|
|
||||||
end
|
|
||||||
|
|
||||||
def validate_password
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
########################
|
|
||||||
# Project manipulation #
|
|
||||||
########################
|
|
||||||
|
|
||||||
class Project
|
|
||||||
attr_accessor :id, :path, :posixname, :users
|
|
||||||
attr_reader :keys
|
|
||||||
|
|
||||||
def initialize
|
|
||||||
@users = []
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
"#{@id}, #{@path}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_key(key)
|
|
||||||
@keys << key
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_user(user)
|
|
||||||
@users << user
|
|
||||||
user.keys.each do |key|
|
|
||||||
add_key(key)
|
|
||||||
end
|
|
||||||
flush
|
|
||||||
refresh
|
|
||||||
end
|
|
||||||
|
|
||||||
def remove_user(user)
|
|
||||||
@user.delete(user)
|
|
||||||
flush
|
|
||||||
refresh
|
|
||||||
end
|
|
||||||
|
|
||||||
def refresh
|
|
||||||
@users = File.open("#{@path}/.ssh/users","r") do |f|
|
|
||||||
f.read.split("\n").map{|id| get_user_by_id(id)}
|
|
||||||
end
|
|
||||||
@keys = extract_ssh_pubkeys("#{@path}/.ssh/authorized_keys")
|
|
||||||
end
|
|
||||||
|
|
||||||
def flush
|
|
||||||
File.open("#{@path}/.ssh/users","w+") do |user_file|
|
|
||||||
@users.each do |u|
|
|
||||||
user_file << "#{u.id}\n"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
get_ssh_keyfile(self,"w+") do |key_file|
|
|
||||||
@users.each do |user|
|
|
||||||
user.keys.each do |key|
|
|
||||||
key_file << "#{key.to_s}\n"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
class DuplicateProjectError < StandardError
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_project(id)
|
|
||||||
$project_id_map[id]
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_project(project)
|
|
||||||
$projects << project
|
|
||||||
$project_id_map[project.id] = project
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_project(id)
|
|
||||||
$projects.each do |p|
|
|
||||||
if p == id then
|
|
||||||
raise DuplicateProjectError, "Project with id #{id} already exists"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if not system("useradd -m #{POSIX_NAME_PREFIX}#{id} -s /usr/bin/eshell") then
|
|
||||||
raise "Project creation failed"
|
|
||||||
end
|
|
||||||
|
|
||||||
project = Project.new
|
|
||||||
project.id = id
|
|
||||||
project.path = "/home/#{POSIX_NAME_PREFIX}#{id}"
|
|
||||||
project.posixname = "#{POSIX_NAME_PREFIX}#{id}"
|
|
||||||
$projects << project
|
|
||||||
$project_id_map[id] = project
|
|
||||||
|
|
||||||
FileUtils.mkdir "#{project.path}/.ssh"
|
|
||||||
FileUtils.touch "#{project.path}/.ssh/authorized_keys"
|
|
||||||
FileUtils.touch "#{project.path}/.ssh/users"
|
|
||||||
FileUtils.chown_R project.posixname, project.posixname, "#{project.path}/.ssh"
|
|
||||||
|
|
||||||
project
|
|
||||||
end
|
|
||||||
|
|
||||||
def remove_project(project)
|
|
||||||
system("userdel -r #{project.posixname}")
|
|
||||||
$projects.delete(project)
|
|
||||||
$project_id_map[id] = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
def project_by_posix_name(posix_name)
|
|
||||||
project = Project.new
|
|
||||||
project.id = posix_name[POSIX_NAME_PREFIX.length..-1]
|
|
||||||
project.path = "/home/#{posix_name}"
|
|
||||||
project.posixname = posix_name
|
|
||||||
project
|
|
||||||
end
|
|
||||||
|
|
||||||
####################
|
|
||||||
# Key manipulation #
|
|
||||||
####################
|
|
||||||
|
|
||||||
class SSHKey
|
|
||||||
attr_accessor :cipher, :pubkey, :comment
|
|
||||||
|
|
||||||
def initialize(cipher,pubkey,comment="")
|
|
||||||
@cipher = cipher
|
|
||||||
@pubkey = pubkey
|
|
||||||
@comment = comment
|
|
||||||
end
|
|
||||||
|
|
||||||
def ==(o)
|
|
||||||
o.class == self.class && o.attrs == attrs
|
|
||||||
end
|
|
||||||
|
|
||||||
def pretty
|
|
||||||
"#{@cipher} #{@comment}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
"ssh-#{@cipher} #{@pubkey} #{@comment}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def attrs
|
|
||||||
[@cipher, @pubkey, @comment]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class InvalidSSHPubKey < StandardError
|
|
||||||
end
|
|
||||||
|
|
||||||
class DuplicateSSHPubKey < StandardError
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_ssh_keyfile(project,mode,&block)
|
|
||||||
file = File.open("#{project.path}/.ssh/authorized_keys",mode)
|
|
||||||
return file unless block_given?
|
|
||||||
yield(file)
|
|
||||||
ensure
|
|
||||||
file.close
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_ssh_pubkeys(project)
|
|
||||||
extract_ssh_pubkeys("#{project.path}/.ssh/authorized_keys")
|
|
||||||
end
|
|
||||||
|
|
||||||
def valid_pubkey?(key)
|
|
||||||
IO.popen("ssh-keygen -qlf -","r+") do |io|
|
|
||||||
io.write key.to_s
|
|
||||||
io.close_write
|
|
||||||
io.read
|
|
||||||
end
|
|
||||||
if $?.to_i == 0
|
|
||||||
true
|
|
||||||
else
|
|
||||||
false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def extract_ssh_pubkeys(file)
|
|
||||||
File.open(file,"r") do |f|
|
|
||||||
f.read.split("\n").select{ |line| line[0..2] == "ssh" }.map{ |ks| k = ks.split(" "); SSHKey.new(k[0][4..6], k[1], k[2]) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
################
|
|
||||||
|
|
||||||
|
|
||||||
###########
|
|
||||||
# Project DB #
|
|
||||||
###########
|
|
||||||
|
|
||||||
def reload_projects_from_passwd
|
|
||||||
$projects = []
|
|
||||||
`cut -d: -f1 /etc/passwd`.split("\n").
|
|
||||||
select{|u| u.start_with? POSIX_NAME_PREFIX}.
|
|
||||||
map{|u| project_by_posix_name(u)}.
|
|
||||||
each{|u| add_project(u)}
|
|
||||||
$projects.each{|p| p.refresh}
|
|
||||||
end
|
|
||||||
|
|
||||||
def reload_users_from_dir
|
|
||||||
`ls -1 #{USER_LOCATION}`.split("\n").
|
|
||||||
map{|u| User.new(u)}.
|
|
||||||
each{|u| add_user(u.id)}
|
|
||||||
end
|
|
||||||
|
|
||||||
def flush_all_to_disk
|
|
||||||
$users.each {|u| u.flush}
|
|
||||||
$projects.each {|p| p.flush}
|
|
||||||
end
|
|
||||||
|
|
||||||
def flush_projects_with_user(user)
|
|
||||||
$projects.select{|p| p.users.include? user}.each do |p|
|
|
||||||
p.flush
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
################################################
|
|
||||||
|
|
||||||
#reload_users_from_dir
|
|
||||||
#reload_projects_from_passwd
|
|
||||||
|
|
||||||
#remove_project 5
|
|
||||||
#create_project 3
|
|
||||||
#add_ssh_pubkey(get_project(3), "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7ZKN2fKcUQUaQqDjNCQQBSdqBVGX7lprNCJmceDBfybhbnuZJ8KvzJJIJIIbzqheW5BVCfkWJY6OgkpAumLWSRCS5n2+AnDHwQgpKDS93OeV+9/kattVtsVUBZaghymyJ2UfA0r918dkxcT9SZbNSl9raiDUUmj3JY8UM219BQP7BRqoZ6e/YZz9lO7ORy6yQT6fIMaVOaZcoDPr6oyNJfadm9POvS/Wl63onoRI9dzpHQG9RuHCcUhHJhkGtzY7GeRWc85WqA9Q4vYo0SK5Je9BG1cvAAVTfV+eYEJEiSDMwWj60roH0C3/ipmzxD/kWqg6YBJWL+XAyQkDnmbuD christoffermadsen@strawberry.thedevcave.net")
|
|
2
lib/emacscollab.rb
Normal file
2
lib/emacscollab.rb
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
module EmacsCollab
|
||||||
|
end
|
182
lib/emacscollab/collab.rb
Normal file
182
lib/emacscollab/collab.rb
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
require 'fileutils'
|
||||||
|
require 'scrypt'
|
||||||
|
require_relative 'user'
|
||||||
|
require_relative 'project'
|
||||||
|
require_relative 'sshkey'
|
||||||
|
|
||||||
|
POSIX_NAME_PREFIX = "emacs"
|
||||||
|
USER_LOCATION = "./users/"
|
||||||
|
DATA_PATH = "/home/christoffermadsen/git/emacs-collab/data"
|
||||||
|
|
||||||
|
|
||||||
|
require_relative 'database/sqlite'
|
||||||
|
$db = EmacsCollab::Database::SQLite.new "test"
|
||||||
|
|
||||||
|
module EmacsCollab
|
||||||
|
|
||||||
|
# TODO: Fix this weird definition
|
||||||
|
|
||||||
|
#####################
|
||||||
|
# User manipulation #
|
||||||
|
#####################
|
||||||
|
|
||||||
|
def self.create_user(id)
|
||||||
|
user = User.new(id)
|
||||||
|
add_user(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.add_user(user)
|
||||||
|
$db.add_user(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.get_user_by_id(id)
|
||||||
|
$db.get_user(id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.change_user_password(id,password)
|
||||||
|
user = get_user_by_id(id)
|
||||||
|
|
||||||
|
hash, salt = salthash_password(password)
|
||||||
|
$db.change_user_password(user, hash, salt)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.check_password(id, password)
|
||||||
|
user = get_user_by_id(id)
|
||||||
|
|
||||||
|
hash = salthash_password(password, user.salt)[0]
|
||||||
|
|
||||||
|
user.pw_hash == hash
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.salthash_password(password, salt = SCrypt::Engine.generate_salt)
|
||||||
|
hash = SCrypt::Engine.hash_secret(password,salt)
|
||||||
|
return hash, salt
|
||||||
|
end
|
||||||
|
|
||||||
|
########################
|
||||||
|
# Project manipulation #
|
||||||
|
########################
|
||||||
|
|
||||||
|
def self.get_project(id)
|
||||||
|
$db.get_project(id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.add_project(project)
|
||||||
|
$db.add_project(project)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.create_project(id)
|
||||||
|
if get_project(id) then
|
||||||
|
raise DuplicateProjectError, "Project with id #{id} already exists"
|
||||||
|
end
|
||||||
|
|
||||||
|
if not system("useradd -m #{POSIX_NAME_PREFIX}#{id} -s /usr/bin/eshell") then
|
||||||
|
raise "Project creation failed"
|
||||||
|
end
|
||||||
|
|
||||||
|
project = Project.new
|
||||||
|
project.id = id
|
||||||
|
project.path = "/home/#{POSIX_NAME_PREFIX}#{id}"
|
||||||
|
project.posixname = "#{POSIX_NAME_PREFIX}#{id}"
|
||||||
|
|
||||||
|
FileUtils.mkdir "#{project.path}/.ssh"
|
||||||
|
FileUtils.touch "#{project.path}/.ssh/authorized_keys"
|
||||||
|
FileUtils.touch "#{project.path}/.ssh/users"
|
||||||
|
FileUtils.chown_R project.posixname, project.posixname, "#{project.path}/.ssh"
|
||||||
|
|
||||||
|
add_project(project)
|
||||||
|
|
||||||
|
project
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.remove_project(project)
|
||||||
|
system("userdel -r #{project.posixname}")
|
||||||
|
$db.remove_project(project)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.load_project_from_posix_name(posix_name)
|
||||||
|
project = Project.new
|
||||||
|
project.id = posix_name[POSIX_NAME_PREFIX.length..-1]
|
||||||
|
project.path = "/home/#{posix_name}"
|
||||||
|
project.posixname = posix_name
|
||||||
|
project
|
||||||
|
end
|
||||||
|
|
||||||
|
####################
|
||||||
|
# Key manipulation #
|
||||||
|
####################
|
||||||
|
|
||||||
|
def self.get_ssh_keyfile(project,mode,&block)
|
||||||
|
file = File.open("#{project.path}/.ssh/authorized_keys",mode)
|
||||||
|
return file unless block_given?
|
||||||
|
yield(file)
|
||||||
|
ensure
|
||||||
|
file.close
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.get_ssh_pubkeys(project)
|
||||||
|
extract_ssh_pubkeys("#{project.path}/.ssh/authorized_keys")
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.valid_pubkey?(key)
|
||||||
|
IO.popen("ssh-keygen -qlf -","r+") do |io|
|
||||||
|
io.write key.to_s
|
||||||
|
io.close_write
|
||||||
|
io.read
|
||||||
|
end
|
||||||
|
if $?.to_i == 0
|
||||||
|
true
|
||||||
|
else
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.extract_ssh_pubkeys(file)
|
||||||
|
File.open(file,"r") do |f|
|
||||||
|
f.read.split("\n").select{ |line| line[0..2] == "ssh" }.map{ |ks| k = ks.split(" "); SSHKey.new(k[0][4..6], k[1], k[2]) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
################
|
||||||
|
|
||||||
|
|
||||||
|
###########
|
||||||
|
# Project $DB #
|
||||||
|
###########
|
||||||
|
|
||||||
|
def self.reload_projects_from_passwd
|
||||||
|
$projects = []
|
||||||
|
`cut -d: -f1 /etc/passwd`.split("\n").
|
||||||
|
select{|u| u.start_with? POSIX_NAME_PREFIX}.
|
||||||
|
map{|u| load_project_from_posix_name(u)}.
|
||||||
|
each{|u| add_project(u)}
|
||||||
|
$projects.each{|p| p.refresh}
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.reload_users_from_dir
|
||||||
|
`ls -1 #{USER_LOCATION}`.split("\n").
|
||||||
|
map{|u| User.new(u)}.
|
||||||
|
each{|u| add_user(u.id)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.flush_all_to_disk
|
||||||
|
$users.each {|u| u.flush}
|
||||||
|
$projects.each {|p| p.flush}
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.flush_projects_with_user(user)
|
||||||
|
$projects.select{|p| p.users.include? user}.each do |p|
|
||||||
|
p.flush
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
################################################
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
#reload_users_from_dir
|
||||||
|
#reload_projects_from_passwd
|
||||||
|
|
||||||
|
#remove_project 5
|
||||||
|
#create_project 3
|
||||||
|
#add_ssh_pubkey(get_project(3), "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7ZKN2fKcUQUaQqDjNCQQBSdqBVGX7lprNCJmceDBfybhbnuZJ8KvzJJIJIIbzqheW5BVCfkWJY6OgkpAumLWSRCS5n2+AnDHwQgpKDS93OeV+9/kattVtsVUBZaghymyJ2UfA0r918dkxcT9SZbNSl9raiDUUmj3JY8UM219BQP7BRqoZ6e/YZz9lO7ORy6yQT6fIMaVOaZcoDPr6oyNJfadm9POvS/Wl63onoRI9dzpHQG9RuHCcUhHJhkGtzY7GeRWc85WqA9Q4vYo0SK5Je9BG1cvAAVTfV+eYEJEiSDMwWj60roH0C3/ipmzxD/kWqg6YBJWL+XAyQkDnmbuD christoffermadsen@strawberry.thedevcave.net")
|
51
lib/emacscollab/database/sqlite.rb
Normal file
51
lib/emacscollab/database/sqlite.rb
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
require_relative '../user'
|
||||||
|
require_relative '../project'
|
||||||
|
require_relative '../sshkey'
|
||||||
|
|
||||||
|
require 'sqlite3'
|
||||||
|
require 'json'
|
||||||
|
|
||||||
|
module EmacsCollab
|
||||||
|
module Database
|
||||||
|
|
||||||
|
class SQLite
|
||||||
|
def initialize(db_name)
|
||||||
|
@db = SQLite3::Database.new "#{DATA_PATH}/#{db_name}.db"
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_user(id)
|
||||||
|
# TODO
|
||||||
|
row = @db.execute("SELECT * FROM Users WHERE name = ?", [id])[0]
|
||||||
|
unless row
|
||||||
|
raise UserNotFoundError, "User with id #{id} could not be found in database"
|
||||||
|
end
|
||||||
|
|
||||||
|
user = User.new(row[0])
|
||||||
|
user.pw_hash = row[1]
|
||||||
|
user.salt = row[2]
|
||||||
|
user.keys = row[3] == nil ? nil : JSON.parse(row[3])
|
||||||
|
|
||||||
|
user
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_user(user)
|
||||||
|
@db.execute("INSERT INTO Users (name) VALUES (?)",
|
||||||
|
[user.id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_user(user)
|
||||||
|
@db.execute("UPDATE Users SET keys = ? WHERE name = ?",
|
||||||
|
[JSON.generate(user.keys),user.id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def change_user_password(user,hash,salt)
|
||||||
|
@db.execute("UPDATE Users SET passwd = ?, salt = ? WHERE name = ?",
|
||||||
|
[hash,salt,user.id])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#user1 = User.new("user1")
|
||||||
|
#add_user(user1)
|
||||||
|
#change_user_password(user1,"testtest")
|
61
lib/emacscollab/project.rb
Normal file
61
lib/emacscollab/project.rb
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
module EmacsCollab
|
||||||
|
class Project
|
||||||
|
attr_accessor :id, :path, :posixname, :users
|
||||||
|
attr_reader :keys
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
@users = []
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
"#{@id}, #{@path}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_key(key)
|
||||||
|
@keys << key
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_user(user)
|
||||||
|
@users << user
|
||||||
|
user.keys.each do |key|
|
||||||
|
add_key(key)
|
||||||
|
end
|
||||||
|
flush
|
||||||
|
refresh
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_user(user)
|
||||||
|
@user.delete(user)
|
||||||
|
flush
|
||||||
|
refresh
|
||||||
|
end
|
||||||
|
|
||||||
|
def refresh
|
||||||
|
@users = File.open("#{@path}/.ssh/users","r") do |f|
|
||||||
|
f.read.split("\n").map{|id| get_user_by_id(id)}
|
||||||
|
end
|
||||||
|
@keys = extract_ssh_pubkeys("#{@path}/.ssh/authorized_keys")
|
||||||
|
end
|
||||||
|
|
||||||
|
def flush
|
||||||
|
File.open("#{@path}/.ssh/users","w+") do |user_file|
|
||||||
|
@users.each do |u|
|
||||||
|
user_file << "#{u.id}\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
get_ssh_keyfile(self,"w+") do |key_file|
|
||||||
|
@users.each do |user|
|
||||||
|
user.keys.each do |key|
|
||||||
|
key_file << "#{key.to_s}\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
class DuplicateProjectError < StandardError
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
35
lib/emacscollab/sshkey.rb
Normal file
35
lib/emacscollab/sshkey.rb
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
module EmacsCollab
|
||||||
|
|
||||||
|
class SSHKey
|
||||||
|
attr_accessor :cipher, :pubkey, :comment
|
||||||
|
|
||||||
|
def initialize(cipher,pubkey,comment="")
|
||||||
|
@cipher = cipher
|
||||||
|
@pubkey = pubkey
|
||||||
|
@comment = comment
|
||||||
|
end
|
||||||
|
|
||||||
|
def ==(o)
|
||||||
|
o.class == self.class && o.attrs == attrs
|
||||||
|
end
|
||||||
|
|
||||||
|
def pretty
|
||||||
|
"#{@cipher} #{@comment}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
"ssh-#{@cipher} #{@pubkey} #{@comment}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def attrs
|
||||||
|
[@cipher, @pubkey, @comment]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class InvalidSSHPubKey < StandardError
|
||||||
|
end
|
||||||
|
|
||||||
|
class DuplicateSSHPubKey < StandardError
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
59
lib/emacscollab/user.rb
Normal file
59
lib/emacscollab/user.rb
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
module EmacsCollab
|
||||||
|
|
||||||
|
class User
|
||||||
|
attr_accessor :id, :keypath, :pw_hash, :salt, :keys
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
"#{@id}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize(id)
|
||||||
|
@id = id
|
||||||
|
@keypath = "#{USER_LOCATION}#{id}"
|
||||||
|
refresh_keys
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_key_from_string(keystring)
|
||||||
|
unless valid_pubkey? keystring
|
||||||
|
raise InvalidSSHPubKey, "Public key not valid"
|
||||||
|
end
|
||||||
|
ks = keystring.split(" ");
|
||||||
|
key = SSHKey.new(ks[0][4..6], ks[1], ks[2])
|
||||||
|
|
||||||
|
unless @keys.include? key
|
||||||
|
@keys << key
|
||||||
|
else
|
||||||
|
raise DuplicateSSHPubKey, "Public key is already added to user"
|
||||||
|
end
|
||||||
|
|
||||||
|
flush
|
||||||
|
refresh_keys
|
||||||
|
flush_projects_with_user(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_key(key)
|
||||||
|
@keys.delete(key)
|
||||||
|
flush
|
||||||
|
refresh_keys
|
||||||
|
flush_projects_with_user(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def refresh_keys
|
||||||
|
#File.open(@keypath,"r") do |f|
|
||||||
|
# @keys = f.read.split("\n").select{ |line| line[0..2] == "ssh" }.map{ |ks| k = ks.split(" "); SSHKey.new(k[0][4..6], k[1], k[2]) }
|
||||||
|
#end
|
||||||
|
end
|
||||||
|
|
||||||
|
def flush
|
||||||
|
File.open(@keypath,"w+") do |key_file|
|
||||||
|
@keys.each do |key|
|
||||||
|
key_file << "#{key.to_s}\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class UserNotFoundError < StandardError
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -1,4 +1,4 @@
|
||||||
require_relative 'collab'
|
require_relative 'lib/emacscollab'
|
||||||
require 'tty-prompt'
|
require 'tty-prompt'
|
||||||
require 'colorize'
|
require 'colorize'
|
||||||
|
|
||||||
|
|
33
sqlite.rb
33
sqlite.rb
|
@ -1,33 +0,0 @@
|
||||||
require 'sqlite3'
|
|
||||||
require 'json'
|
|
||||||
require 'securerandom'
|
|
||||||
require 'scrypt'
|
|
||||||
require_relative 'collab.rb'
|
|
||||||
|
|
||||||
|
|
||||||
$db = SQLite3::Database.new "data/test.db"
|
|
||||||
|
|
||||||
def get_user(id)
|
|
||||||
puts $db.execute("SELECT * FROM Users WHERE name = ?", [id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_user(user)
|
|
||||||
$db.execute("INSERT INTO Users (name) VALUES (?)",
|
|
||||||
[user.id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def update_user(user)
|
|
||||||
$db.execute("UPDATE Users SET keys = ? WHERE name = ?",
|
|
||||||
[JSON.generate(user.keys),user.id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def change_user_password(user,password)
|
|
||||||
salt = SecureRandom.base64(32)
|
|
||||||
hash = SCrypt::Password.create(salt + password)
|
|
||||||
$db.execute("UPDATE Users SET passwd = ?, salt = ? WHERE name = ?",
|
|
||||||
[hash,salt,user.id])
|
|
||||||
end
|
|
||||||
|
|
||||||
#user1 = User.new("user1")
|
|
||||||
#add_user(user1)
|
|
||||||
#change_user_password(user1,"testtest")
|
|
Loading…
Reference in New Issue
Block a user