SQLite integration should be complete now
This commit is contained in:
parent
b711f54b84
commit
06eb99c84a
1
Gemfile
1
Gemfile
|
@ -1,5 +1,4 @@
|
||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
gem 'fileutils'
|
|
||||||
gem 'tty-prompt'
|
gem 'tty-prompt'
|
||||||
gem 'colorize'
|
gem 'colorize'
|
||||||
gem 'sqlite3'
|
gem 'sqlite3'
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
FROM ubuntu:xenial
|
FROM ubuntu:xenial
|
||||||
|
|
||||||
RUN apt-get update
|
RUN apt-get update
|
||||||
RUN apt-get install -y emacs-nox ruby openssh-server
|
RUN apt-get install -y emacs-nox openssh-server
|
||||||
RUN apt-get install -y build-essential libsqlite3-dev sqlite3
|
RUN apt-get install -y ruby ruby-dev build-essential libsqlite3-dev sqlite3
|
||||||
RUN gem install tty-prompt colorize
|
RUN gem install bundler
|
||||||
RUN mkdir /var/run/sshd
|
RUN mkdir /var/run/sshd
|
||||||
|
|
||||||
# SSH login fix. Otherwise user is kicked off after login
|
# SSH login fix. Otherwise user is kicked off after login
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
cp ../eshell ./
|
cp ../eshell ./
|
||||||
|
cp ../Gemfile* ./
|
||||||
docker build -t emacs-collab:latest .
|
docker build -t emacs-collab:latest .
|
||||||
|
|
|
@ -10,9 +10,11 @@ CREATE TABLE Users (
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE Projects (
|
CREATE TABLE Projects (
|
||||||
uid INT NOT NULL,
|
uid INT NOT NULL,
|
||||||
name VARCHAR (24) NOT NULL,
|
name VARCHAR (24) NOT NULL,
|
||||||
owner VARCHAR (24) NOT NULL,
|
path VARCHAR (255) NOT NULL,
|
||||||
|
posixname VARCHAR (32) NOT NULL,
|
||||||
|
owner VARCHAR (1024),
|
||||||
users VARCHAR (8192),
|
users VARCHAR (8192),
|
||||||
|
|
||||||
PRIMARY KEY (uid),
|
PRIMARY KEY (uid),
|
||||||
|
|
|
@ -6,7 +6,7 @@ require_relative 'sshkey'
|
||||||
|
|
||||||
POSIX_NAME_PREFIX = "emacs"
|
POSIX_NAME_PREFIX = "emacs"
|
||||||
USER_LOCATION = "./users/"
|
USER_LOCATION = "./users/"
|
||||||
DATA_PATH = "/home/christoffermadsen/git/emacs-collab/data"
|
DATA_PATH = "./data"
|
||||||
|
|
||||||
|
|
||||||
require_relative 'database/sqlite'
|
require_relative 'database/sqlite'
|
||||||
|
@ -65,13 +65,20 @@ module EmacsCollab
|
||||||
$db.get_project(id)
|
$db.get_project(id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.get_projects
|
||||||
|
$db.get_projects
|
||||||
|
end
|
||||||
|
|
||||||
def self.add_project(project)
|
def self.add_project(project)
|
||||||
$db.add_project(project)
|
$db.add_project(project)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.create_project(id)
|
def self.create_project(id)
|
||||||
if get_project(id) then
|
begin
|
||||||
raise DuplicateProjectError, "Project with id #{id} already exists"
|
if get_project(id) then
|
||||||
|
raise DuplicateProjectError, "Project with id #{id} already exists"
|
||||||
|
end
|
||||||
|
rescue EmacsCollab::ProjectNotFoundError => e
|
||||||
end
|
end
|
||||||
|
|
||||||
if not system("useradd -m #{POSIX_NAME_PREFIX}#{id} -s /usr/bin/eshell") then
|
if not system("useradd -m #{POSIX_NAME_PREFIX}#{id} -s /usr/bin/eshell") then
|
||||||
|
@ -82,6 +89,7 @@ module EmacsCollab
|
||||||
project.id = id
|
project.id = id
|
||||||
project.path = "/home/#{POSIX_NAME_PREFIX}#{id}"
|
project.path = "/home/#{POSIX_NAME_PREFIX}#{id}"
|
||||||
project.posixname = "#{POSIX_NAME_PREFIX}#{id}"
|
project.posixname = "#{POSIX_NAME_PREFIX}#{id}"
|
||||||
|
project.uid = /uid=([0-9]+)\(/.match(`id #{project.posixname}`)[1].to_i
|
||||||
|
|
||||||
FileUtils.mkdir "#{project.path}/.ssh"
|
FileUtils.mkdir "#{project.path}/.ssh"
|
||||||
FileUtils.touch "#{project.path}/.ssh/authorized_keys"
|
FileUtils.touch "#{project.path}/.ssh/authorized_keys"
|
||||||
|
@ -169,9 +177,9 @@ module EmacsCollab
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.flush_projects_with_user(user)
|
def self.flush_projects_with_user(user)
|
||||||
$projects.select{|p| p.users.include? user}.each do |p|
|
#$projects.select{|p| p.users.include? user}.each do |p|
|
||||||
p.flush
|
# p.flush
|
||||||
end
|
#end
|
||||||
end
|
end
|
||||||
|
|
||||||
################################################
|
################################################
|
||||||
|
|
|
@ -14,7 +14,6 @@ module EmacsCollab
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_user(id)
|
def get_user(id)
|
||||||
# TODO
|
|
||||||
row = @db.execute("SELECT * FROM Users WHERE name = ?", [id])[0]
|
row = @db.execute("SELECT * FROM Users WHERE name = ?", [id])[0]
|
||||||
unless row
|
unless row
|
||||||
raise UserNotFoundError, "User with id #{id} could not be found in database"
|
raise UserNotFoundError, "User with id #{id} could not be found in database"
|
||||||
|
@ -23,19 +22,19 @@ module EmacsCollab
|
||||||
user = User.new(row[0])
|
user = User.new(row[0])
|
||||||
user.pw_hash = row[1]
|
user.pw_hash = row[1]
|
||||||
user.salt = row[2]
|
user.salt = row[2]
|
||||||
user.keys = row[3] == nil ? nil : JSON.parse(row[3])
|
user.keys = row[3] == nil ? Array.new : Marshal.load(row[3])
|
||||||
|
|
||||||
user
|
user
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_users
|
def get_users
|
||||||
user_rows = @db.execute("SELECT * FROM Users")
|
rows = @db.execute("SELECT * FROM Users")
|
||||||
|
|
||||||
user_rows.map do |row|
|
rows.map do |row|
|
||||||
user = User.new(row[0])
|
user = User.new(row[0])
|
||||||
user.pw_hash = row[1]
|
user.pw_hash = row[1]
|
||||||
user.salt = row[2]
|
user.salt = row[2]
|
||||||
user.keys = row[3] == nil ? nil : JSON.parse(row[3])
|
user.keys = row[3] == nil ? Array.new : Marshal.load(row[3])
|
||||||
user
|
user
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -54,6 +53,58 @@ module EmacsCollab
|
||||||
@db.execute("UPDATE Users SET passwd = ?, salt = ? WHERE name = ?",
|
@db.execute("UPDATE Users SET passwd = ?, salt = ? WHERE name = ?",
|
||||||
[hash,salt,user.id])
|
[hash,salt,user.id])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def get_project(name)
|
||||||
|
row = @db.execute("SELECT * FROM Projects WHERE name = ?", [name])[0]
|
||||||
|
unless row
|
||||||
|
raise EmacsCollab::ProjectNotFoundError, "Project with name #{name} could not be found in database"
|
||||||
|
end
|
||||||
|
|
||||||
|
proj = Project.new()
|
||||||
|
proj.uid = row[0]
|
||||||
|
proj.id = row[1]
|
||||||
|
proj.path = row[2]
|
||||||
|
proj.posixname = row[3]
|
||||||
|
proj.owner = row[4]
|
||||||
|
users = (row[5] == nil ? Array.new : Marshal.load(row[5]))
|
||||||
|
users.each do |u|
|
||||||
|
EmacsCollab.get_user_by_id(u.id).keys.each do |k|
|
||||||
|
proj.add_key(k)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
proj
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_projects
|
||||||
|
rows = @db.execute("SELECT * FROM Projects")
|
||||||
|
|
||||||
|
rows.map do |row|
|
||||||
|
proj = Project.new()
|
||||||
|
proj.uid = row[0]
|
||||||
|
proj.id = row[1]
|
||||||
|
proj.path = row[2]
|
||||||
|
proj.posixname = row[3]
|
||||||
|
proj.owner = row[4]
|
||||||
|
users = (row[5] == nil ? Array.new : Marshal.load(row[5]))
|
||||||
|
users.each do |u|
|
||||||
|
EmacsCollab.get_user_by_id(u).keys.each do |k|
|
||||||
|
proj.add_key(k)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
proj.users = row[5]
|
||||||
|
proj
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_project(proj)
|
||||||
|
@db.execute("INSERT INTO Projects (uid,name,path,posixname,owner,users) VALUES (?,?,?,?,?,?)",
|
||||||
|
[ proj.uid, proj.id, proj.path, proj.posixname, "", Marshal.dump(proj.users) ])
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_project(proj)
|
||||||
|
@db.execute("UPDATE Projects SET name = ?, path = ?, posixname = ?, owner = ?, users = ? WHERE uid = ?",
|
||||||
|
[ proj.id, proj.path, proj.posixname, "", Marshal.dump(proj.users), proj.uid ])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
module EmacsCollab
|
module EmacsCollab
|
||||||
class Project
|
class Project
|
||||||
attr_accessor :id, :path, :posixname, :users
|
attr_accessor :uid, :id, :path, :posixname, :users, :owner
|
||||||
attr_reader :keys
|
attr_reader :keys
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@users = []
|
@users = []
|
||||||
|
@keys = []
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
|
@ -17,36 +18,30 @@ module EmacsCollab
|
||||||
|
|
||||||
def add_user(user)
|
def add_user(user)
|
||||||
@users << user
|
@users << user
|
||||||
user.keys.each do |key|
|
# TODO: Remove the following comments
|
||||||
add_key(key)
|
#user.keys.each do |key|
|
||||||
end
|
# add_key(key)
|
||||||
|
#end
|
||||||
flush
|
flush
|
||||||
refresh
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_user(user)
|
def remove_user(user)
|
||||||
@user.delete(user)
|
@user.delete(user)
|
||||||
|
# TODO Make sure to remove the key of the user
|
||||||
flush
|
flush
|
||||||
refresh
|
refresh
|
||||||
end
|
end
|
||||||
|
|
||||||
def refresh
|
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
|
end
|
||||||
|
|
||||||
def flush
|
def flush
|
||||||
File.open("#{@path}/.ssh/users","w+") do |user_file|
|
$db.update_project(self)
|
||||||
@users.each do |u|
|
|
||||||
user_file << "#{u.id}\n"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
get_ssh_keyfile(self,"w+") do |key_file|
|
EmacsCollab.get_ssh_keyfile(self,"w+") do |key_file|
|
||||||
@users.each do |user|
|
@users.each do |user|
|
||||||
user.keys.each do |key|
|
EmacsCollab.get_user_by_id(user).keys.each do |key|
|
||||||
key_file << "#{key.to_s}\n"
|
key_file << "#{key.to_s}\n"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -58,4 +53,7 @@ module EmacsCollab
|
||||||
class DuplicateProjectError < StandardError
|
class DuplicateProjectError < StandardError
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class ProjectNotFoundError < StandardError
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,11 +10,10 @@ module EmacsCollab
|
||||||
def initialize(id)
|
def initialize(id)
|
||||||
@id = id
|
@id = id
|
||||||
@keypath = "#{USER_LOCATION}#{id}"
|
@keypath = "#{USER_LOCATION}#{id}"
|
||||||
refresh_keys
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_key_from_string(keystring)
|
def add_key_from_string(keystring)
|
||||||
unless valid_pubkey? keystring
|
unless EmacsCollab.valid_pubkey? keystring
|
||||||
raise InvalidSSHPubKey, "Public key not valid"
|
raise InvalidSSHPubKey, "Public key not valid"
|
||||||
end
|
end
|
||||||
ks = keystring.split(" ");
|
ks = keystring.split(" ");
|
||||||
|
@ -25,31 +24,19 @@ module EmacsCollab
|
||||||
else
|
else
|
||||||
raise DuplicateSSHPubKey, "Public key is already added to user"
|
raise DuplicateSSHPubKey, "Public key is already added to user"
|
||||||
end
|
end
|
||||||
|
p self
|
||||||
flush
|
flush
|
||||||
refresh_keys
|
EmacsCollab.flush_projects_with_user(self)
|
||||||
flush_projects_with_user(self)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_key(key)
|
def remove_key(key)
|
||||||
@keys.delete(key)
|
@keys.delete(key)
|
||||||
flush
|
flush
|
||||||
refresh_keys
|
EmacsCollab.flush_projects_with_user(self)
|
||||||
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
|
end
|
||||||
|
|
||||||
def flush
|
def flush
|
||||||
File.open(@keypath,"w+") do |key_file|
|
$db.update_user(self)
|
||||||
@keys.each do |key|
|
|
||||||
key_file << "#{key.to_s}\n"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
19
prompt.rb
19
prompt.rb
|
@ -2,6 +2,9 @@ require_relative 'lib/emacscollab'
|
||||||
require 'tty-prompt'
|
require 'tty-prompt'
|
||||||
require 'colorize'
|
require 'colorize'
|
||||||
|
|
||||||
|
require_relative 'lib/emacscollab/collab'
|
||||||
|
require_relative 'lib/emacscollab/sshkey'
|
||||||
|
|
||||||
$prompt = TTY::Prompt.new
|
$prompt = TTY::Prompt.new
|
||||||
$login = "root"
|
$login = "root"
|
||||||
|
|
||||||
|
@ -34,10 +37,10 @@ def keys_user(user)
|
||||||
key = $prompt.ask("Please enter a valid public SSH key", echo: false)
|
key = $prompt.ask("Please enter a valid public SSH key", echo: false)
|
||||||
begin
|
begin
|
||||||
user.add_key_from_string(key)
|
user.add_key_from_string(key)
|
||||||
rescue InvalidSSHPubKey => e
|
rescue EmacsCollab::InvalidSSHPubKey => e
|
||||||
puts e.message.colorize(:red)
|
puts e.message.colorize(:red)
|
||||||
keys_user(user)
|
keys_user(user)
|
||||||
rescue DuplicateSSHPubKey => e
|
rescue EmacsCollab::DuplicateSSHPubKey => e
|
||||||
puts e.message.colorize(:red)
|
puts e.message.colorize(:red)
|
||||||
keys_user(user)
|
keys_user(user)
|
||||||
end
|
end
|
||||||
|
@ -67,8 +70,8 @@ def project_create
|
||||||
input.validate /\A\w+\Z/
|
input.validate /\A\w+\Z/
|
||||||
end
|
end
|
||||||
begin
|
begin
|
||||||
create_project(id)
|
EmacsCollab.create_project(id)
|
||||||
rescue DuplicateProjectError => e
|
rescue EmacsCollab::DuplicateProjectError => e
|
||||||
puts e.message.colorize(:red)
|
puts e.message.colorize(:red)
|
||||||
projects
|
projects
|
||||||
end
|
end
|
||||||
|
@ -77,7 +80,7 @@ end
|
||||||
|
|
||||||
def project_modify
|
def project_modify
|
||||||
# Currently, it is implied that modify equals changing which users have access
|
# Currently, it is implied that modify equals changing which users have access
|
||||||
project_users($prompt.select("Pick a project", $projects))
|
project_users($prompt.select("Pick a project", EmacsCollab.get_projects))
|
||||||
end
|
end
|
||||||
|
|
||||||
def project_users(project)
|
def project_users(project)
|
||||||
|
@ -90,7 +93,7 @@ def project_users(project)
|
||||||
when :add
|
when :add
|
||||||
choices = EmacsCollab.get_users
|
choices = EmacsCollab.get_users
|
||||||
user = $prompt.select("Pick a user", choices)
|
user = $prompt.select("Pick a user", choices)
|
||||||
project.add_user(user)
|
project.add_user(user.id)
|
||||||
puts "Added user #{user} to #{project}".colorize(:green)
|
puts "Added user #{user} to #{project}".colorize(:green)
|
||||||
when :select
|
when :select
|
||||||
choices = EmacsCollab.get_users
|
choices = EmacsCollab.get_users
|
||||||
|
@ -99,7 +102,7 @@ def project_users(project)
|
||||||
defaults = []
|
defaults = []
|
||||||
counter = 1
|
counter = 1
|
||||||
choices.each do |u|
|
choices.each do |u|
|
||||||
if project.users.include? u then
|
if project.users.include? u.id then
|
||||||
defaults << counter
|
defaults << counter
|
||||||
end
|
end
|
||||||
counter += 1
|
counter += 1
|
||||||
|
@ -111,7 +114,7 @@ def project_users(project)
|
||||||
users = $prompt.multi_select("Select users", choices)
|
users = $prompt.multi_select("Select users", choices)
|
||||||
end
|
end
|
||||||
|
|
||||||
project.users = users
|
project.users = users.map { |u| u.id }
|
||||||
project.flush
|
project.flush
|
||||||
project.refresh
|
project.refresh
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user