SQLite integration should be complete now

This commit is contained in:
Christoffer Müller Madsen 2017-06-15 02:20:13 +02:00
parent b711f54b84
commit 06eb99c84a
9 changed files with 111 additions and 62 deletions

View File

@ -1,5 +1,4 @@
source 'https://rubygems.org'
gem 'fileutils'
gem 'tty-prompt'
gem 'colorize'
gem 'sqlite3'

View File

@ -1,9 +1,9 @@
FROM ubuntu:xenial
RUN apt-get update
RUN apt-get install -y emacs-nox ruby openssh-server
RUN apt-get install -y build-essential libsqlite3-dev sqlite3
RUN gem install tty-prompt colorize
RUN apt-get install -y emacs-nox openssh-server
RUN apt-get install -y ruby ruby-dev build-essential libsqlite3-dev sqlite3
RUN gem install bundler
RUN mkdir /var/run/sshd
# SSH login fix. Otherwise user is kicked off after login

View File

@ -1,3 +1,4 @@
#!/bin/sh
cp ../eshell ./
cp ../Gemfile* ./
docker build -t emacs-collab:latest .

View File

@ -10,9 +10,11 @@ CREATE TABLE Users (
);
CREATE TABLE Projects (
uid INT NOT NULL,
name VARCHAR (24) NOT NULL,
owner VARCHAR (24) NOT NULL,
uid INT NOT NULL,
name VARCHAR (24) NOT NULL,
path VARCHAR (255) NOT NULL,
posixname VARCHAR (32) NOT NULL,
owner VARCHAR (1024),
users VARCHAR (8192),
PRIMARY KEY (uid),

View File

@ -6,7 +6,7 @@ require_relative 'sshkey'
POSIX_NAME_PREFIX = "emacs"
USER_LOCATION = "./users/"
DATA_PATH = "/home/christoffermadsen/git/emacs-collab/data"
DATA_PATH = "./data"
require_relative 'database/sqlite'
@ -65,13 +65,20 @@ module EmacsCollab
$db.get_project(id)
end
def self.get_projects
$db.get_projects
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"
begin
if get_project(id) then
raise DuplicateProjectError, "Project with id #{id} already exists"
end
rescue EmacsCollab::ProjectNotFoundError => e
end
if not system("useradd -m #{POSIX_NAME_PREFIX}#{id} -s /usr/bin/eshell") then
@ -82,6 +89,7 @@ module EmacsCollab
project.id = id
project.path = "/home/#{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.touch "#{project.path}/.ssh/authorized_keys"
@ -169,9 +177,9 @@ module EmacsCollab
end
def self.flush_projects_with_user(user)
$projects.select{|p| p.users.include? user}.each do |p|
p.flush
end
#$projects.select{|p| p.users.include? user}.each do |p|
# p.flush
#end
end
################################################

View File

@ -14,7 +14,6 @@ module EmacsCollab
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"
@ -23,19 +22,19 @@ module EmacsCollab
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.keys = row[3] == nil ? Array.new : Marshal.load(row[3])
user
end
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.pw_hash = row[1]
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
end
end
@ -49,11 +48,63 @@ module EmacsCollab
@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
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

View File

@ -1,10 +1,11 @@
module EmacsCollab
class Project
attr_accessor :id, :path, :posixname, :users
attr_accessor :uid, :id, :path, :posixname, :users, :owner
attr_reader :keys
def initialize
@users = []
@keys = []
end
def to_s
@ -17,36 +18,30 @@ module EmacsCollab
def add_user(user)
@users << user
user.keys.each do |key|
add_key(key)
end
# TODO: Remove the following comments
#user.keys.each do |key|
# add_key(key)
#end
flush
refresh
end
def remove_user(user)
@user.delete(user)
# TODO Make sure to remove the key of the 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|
$db.update_project(self)
EmacsCollab.get_ssh_keyfile(self,"w+") do |key_file|
@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"
end
end
@ -58,4 +53,7 @@ module EmacsCollab
class DuplicateProjectError < StandardError
end
class ProjectNotFoundError < StandardError
end
end

View File

@ -10,11 +10,10 @@ module EmacsCollab
def initialize(id)
@id = id
@keypath = "#{USER_LOCATION}#{id}"
refresh_keys
end
def add_key_from_string(keystring)
unless valid_pubkey? keystring
unless EmacsCollab.valid_pubkey? keystring
raise InvalidSSHPubKey, "Public key not valid"
end
ks = keystring.split(" ");
@ -25,31 +24,19 @@ module EmacsCollab
else
raise DuplicateSSHPubKey, "Public key is already added to user"
end
p self
flush
refresh_keys
flush_projects_with_user(self)
EmacsCollab.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
EmacsCollab.flush_projects_with_user(self)
end
def flush
File.open(@keypath,"w+") do |key_file|
@keys.each do |key|
key_file << "#{key.to_s}\n"
end
end
$db.update_user(self)
end
end

View File

@ -2,6 +2,9 @@ require_relative 'lib/emacscollab'
require 'tty-prompt'
require 'colorize'
require_relative 'lib/emacscollab/collab'
require_relative 'lib/emacscollab/sshkey'
$prompt = TTY::Prompt.new
$login = "root"
@ -34,10 +37,10 @@ def keys_user(user)
key = $prompt.ask("Please enter a valid public SSH key", echo: false)
begin
user.add_key_from_string(key)
rescue InvalidSSHPubKey => e
rescue EmacsCollab::InvalidSSHPubKey => e
puts e.message.colorize(:red)
keys_user(user)
rescue DuplicateSSHPubKey => e
rescue EmacsCollab::DuplicateSSHPubKey => e
puts e.message.colorize(:red)
keys_user(user)
end
@ -67,8 +70,8 @@ def project_create
input.validate /\A\w+\Z/
end
begin
create_project(id)
rescue DuplicateProjectError => e
EmacsCollab.create_project(id)
rescue EmacsCollab::DuplicateProjectError => e
puts e.message.colorize(:red)
projects
end
@ -77,7 +80,7 @@ end
def project_modify
# 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
def project_users(project)
@ -90,7 +93,7 @@ def project_users(project)
when :add
choices = EmacsCollab.get_users
user = $prompt.select("Pick a user", choices)
project.add_user(user)
project.add_user(user.id)
puts "Added user #{user} to #{project}".colorize(:green)
when :select
choices = EmacsCollab.get_users
@ -99,7 +102,7 @@ def project_users(project)
defaults = []
counter = 1
choices.each do |u|
if project.users.include? u then
if project.users.include? u.id then
defaults << counter
end
counter += 1
@ -111,7 +114,7 @@ def project_users(project)
users = $prompt.multi_select("Select users", choices)
end
project.users = users
project.users = users.map { |u| u.id }
project.flush
project.refresh
end