You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1197 lines
30 KiB
1197 lines
30 KiB
# certcenter/app.rb
|
|
|
|
certsenter_ruby_gem_version = '3.3.0'
|
|
Gem.paths = {
|
|
'GEM_HOME' => "#{__dir__}/vendor/bundle/ruby/#{certsenter_ruby_gem_version}",
|
|
'GEM_PATH' => "#{__dir__}/vendor/bundle/ruby/#{certsenter_ruby_gem_version}"
|
|
}
|
|
|
|
require 'sinatra'
|
|
require 'sequel'
|
|
require 'sqlite3'
|
|
require 'securerandom'
|
|
require 'base64'
|
|
require 'jwt'
|
|
require 'openssl'
|
|
|
|
# --- i18n setup ---
|
|
require 'i18n'
|
|
require 'i18n/backend/fallbacks'
|
|
I18n.load_path += Dir[File.expand_path('locale/*.yml', __dir__)]
|
|
I18n.backend.load_translations
|
|
I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
|
|
I18n.default_locale = :en
|
|
I18n.enforce_available_locales = false
|
|
I18n.locale = ENV["LANG"].split("_").first.downcase.to_sym || :en
|
|
# -------------------
|
|
|
|
require_relative 'classes/config'
|
|
|
|
DB = Sequel.sqlite('db/base.sqlite')
|
|
|
|
require_relative 'models/users'
|
|
require_relative 'models/userdata'
|
|
|
|
require_relative 'classes/cert'
|
|
require_relative 'classes/pagination'
|
|
|
|
configure do
|
|
Dir.mkdir('logs') unless Dir.exist?('logs')
|
|
unless File.exist?('logs/actions.log')
|
|
File.new('logs/actions.log', 'w').close
|
|
end
|
|
log_file = File.open('logs/actions.log', 'a+')
|
|
STDOUT.reopen(log_file)
|
|
STDERR.reopen(log_file)
|
|
STDOUT.sync = true
|
|
STDERR.sync = true
|
|
end
|
|
|
|
set :bind, IPBIND
|
|
set :port, PORT
|
|
|
|
signing_key_path = File.expand_path("../caapp.private.key.pem", __FILE__)
|
|
verify_key_path = File.expand_path("../caapp.public.key.pem", __FILE__)
|
|
|
|
signing_key = ""
|
|
verify_key = ""
|
|
|
|
File.open(signing_key_path) do |file|
|
|
signing_key = OpenSSL::PKey.read(file)
|
|
end
|
|
|
|
File.open(verify_key_path) do |file|
|
|
verify_key = OpenSSL::PKey.read(file)
|
|
end
|
|
|
|
set :signing_key, signing_key
|
|
set :verify_key, verify_key
|
|
|
|
enable :sessions
|
|
set :public_folder, File.dirname(__FILE__) + '/public'
|
|
|
|
configure do
|
|
use Rack::Session::Pool, {
|
|
expire_after: 86400,
|
|
}
|
|
end
|
|
|
|
register do
|
|
def auth(types)
|
|
condition do
|
|
unless send("is#{types}?")
|
|
redirect '/login' if request.path == '/'
|
|
redirect "/perms"
|
|
end
|
|
end
|
|
end
|
|
|
|
def authtok(types)
|
|
condition do
|
|
unless send("ist#{types}?")
|
|
halt(403, { error: I18n.t('errors.no_permission'), content: nil }.to_json)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
helpers do
|
|
def isuser?
|
|
hasperms? 'user'
|
|
end
|
|
|
|
def iscreator?
|
|
hasperms? 'creator'
|
|
end
|
|
|
|
def isadmin?
|
|
hasperms? 'admin'
|
|
end
|
|
|
|
def hasperms?(level)
|
|
return false if session[:user].nil?
|
|
return true if level == 'admin' && session[:user].auth? && session[:user].role == 2
|
|
return true if level == 'creator' && session[:user].auth? && [1, 2].include?(session[:user].role)
|
|
return true if level == 'user' && session[:user].auth? && [0, 1, 2].include?(session[:user].role)
|
|
|
|
false
|
|
end
|
|
|
|
def istuser?
|
|
hastperms? 'user'
|
|
end
|
|
|
|
def istcreator?
|
|
hastperms? 'creator'
|
|
end
|
|
|
|
def istadmin?
|
|
hastperms? 'admin'
|
|
end
|
|
|
|
def hastperms?(level)
|
|
return false if params[:token].nil?
|
|
begin
|
|
session_raw, headers = JWT.decode(params[:token], settings.verify_key, true, { algorithm: 'RS256'} )
|
|
session_info = {}
|
|
session_info["user"] = UserSessionData.deserialize(session_raw["user"])
|
|
rescue JWT::DecodeError => e
|
|
halt 401, { error: I18n.t('errors.authorization_error'), content: nil }.to_json
|
|
end
|
|
halt 401, { error: I18n.t('errors.token_expired'), content: nil }.to_json if headers["exp"] < Time.now.to_i
|
|
@global_session = {}
|
|
@global_session[:user] = session_info["user"]
|
|
return false if session_info["user"].nil?
|
|
return true if level == 'admin' && session_info["user"].auth? && session_info["user"].role == 2
|
|
return true if level == 'creator' && session_info["user"].auth? && [1, 2].include?(session_info["user"].role)
|
|
return true if level == 'user' && session_info["user"].auth? && [0, 1, 2].include?(session_info["user"].role)
|
|
|
|
false
|
|
end
|
|
end
|
|
|
|
before do
|
|
lang = request.env['HTTP_ACCEPT_LANGUAGE']&.scan(/[a-z]{2}/)&.first || ENV["LANG"] || :en
|
|
I18n.locale = lang.split("_").first.downcase.to_sym || :en
|
|
if request.media_type == 'application/json'
|
|
request.body.rewind
|
|
body = request.body.read
|
|
begin
|
|
json_params = JSON.parse(body)
|
|
params.merge!(json_params)
|
|
rescue JSON::ParserError
|
|
halt 400, { error: I18n.t('errors.invalid_json'), content: nil }.to_json
|
|
end
|
|
end
|
|
end
|
|
|
|
before do
|
|
next if request.path == '/install'
|
|
next if request.path.start_with?('/api/')
|
|
unless File.exist?('utils/custom_config.sh')
|
|
redirect '/install'
|
|
end
|
|
end
|
|
|
|
before do
|
|
allowed = ALLOWED_IPS
|
|
if request.path.start_with?('/api/v1')
|
|
halt 403, { error: I18n.t('errors.access_denied'), content: nil }.to_json unless allowed.include?(request.ip) || request.ip == '127.0.0.1' || request.ip == '::1' || allowed.include?("*")
|
|
else
|
|
unless allowed.include?(request.ip) || request.ip == '127.0.0.1' || request.ip == '::1' || allowed.include?("*")
|
|
status 403
|
|
@error = I18n.t('errors.access_denied')
|
|
@log = nil
|
|
erb :errinfo
|
|
halt
|
|
end
|
|
end
|
|
end
|
|
|
|
# Главная страница
|
|
get '/' do
|
|
if File.exist?('utils/custom_config.sh')
|
|
redirect '/login' unless hasperms? 'user'
|
|
@error = nil
|
|
@log = nil
|
|
@list_serv_full = []
|
|
@tab = 0
|
|
File.open(LOCK_PATH, File::RDWR | File::CREAT) do |f|
|
|
mn = CertManager.new
|
|
unless mn.error?
|
|
@list_serv_full = mn.get_server_certs
|
|
if mn.error?
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
else
|
|
pg = Paginator.new(params, PER_PAGE)
|
|
@list_serv = pg.get_page(@list_serv_full)
|
|
@pages = pg.pages_info(@list_serv_full)
|
|
end
|
|
else
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
f.flock(File::LOCK_UN)
|
|
end
|
|
@page_name = I18n.t('pages.servers')
|
|
@menu = true
|
|
if @error.nil?
|
|
erb :list
|
|
else
|
|
erb :errinfo
|
|
end
|
|
|
|
else
|
|
redirect '/install'
|
|
end
|
|
end
|
|
|
|
get '/clients/?:id?', :auth => 'user' do
|
|
@error = nil
|
|
@log = nil
|
|
@list_clients_full = []
|
|
@list_servers_full = []
|
|
@tab = 0
|
|
server_cert = nil
|
|
File.open(LOCK_PATH, File::RDWR | File::CREAT) do |f|
|
|
mn = CertManager.new
|
|
unless mn.error?
|
|
@list_clients_full = mn.get_clients_certs('')
|
|
if mn.error?
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
else
|
|
pg = Paginator.new(params, PER_PAGE)
|
|
@list_clients = pg.get_page(@list_clients_full)
|
|
@pages = pg.pages_info(@list_clients_full)
|
|
if params[:id]
|
|
server_cert = mn.get_cert_info(params[:id])
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
end
|
|
else
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
if @error.nil?
|
|
@list_servers_full = mn.get_server_certs.map { |item| item[:ui][:CN] }.reject(&:empty?).uniq
|
|
end
|
|
f.flock(File::LOCK_UN)
|
|
end
|
|
if params[:id]
|
|
@id = params[:id].to_i
|
|
@tab = 1
|
|
pg_c = Paginator.new(params, PER_PAGE, 'fp')
|
|
if !server_cert.nil? && server_cert[:ui] && params[:id]
|
|
cn = server_cert[:ui][:CN]
|
|
@server_name = cn
|
|
@list_clients_short = @list_clients_full.select { |entry| entry[:ui][:CN] == cn }
|
|
@pages_short = pg_c.pages_info(@list_clients_short)
|
|
@list_clients_full = @list_clients_short if params['cli'] == 'yes'
|
|
end
|
|
end
|
|
|
|
@page_name = I18n.t('pages.clients')
|
|
@menu = true
|
|
if @error.nil?
|
|
erb :listc
|
|
else
|
|
erb :errinfo
|
|
end
|
|
end
|
|
|
|
get '/shows/:id', :auth => 'user' do
|
|
@page_name = I18n.t('pages.servers')
|
|
@cert_info = nil
|
|
@tab = 1
|
|
File.open(LOCK_PATH, File::RDWR | File::CREAT) do |f|
|
|
mn = CertManager.new
|
|
unless mn.error?
|
|
@cert_info = mn.get_detail_cert_info(params[:id])
|
|
if mn.error?
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
else
|
|
@list_serv_full = mn.get_server_certs
|
|
if mn.error?
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
else
|
|
pg = Paginator.new(params, PER_PAGE)
|
|
@list_serv = pg.get_page(@list_serv_full)
|
|
@pages = pg.pages_info(@list_serv_full)
|
|
end
|
|
end
|
|
else
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
f.flock(File::LOCK_UN)
|
|
end
|
|
|
|
@page_name = I18n.t('pages.clients')
|
|
@menu = true
|
|
if @error.nil?
|
|
erb :list
|
|
else
|
|
erb :errinfo
|
|
end
|
|
end
|
|
|
|
get '/showc/:id', :auth => 'user' do
|
|
@page_name = I18n.t('pages.clients')
|
|
@cert_info = nil
|
|
@tab = 2
|
|
@list_servers_full = []
|
|
File.open(LOCK_PATH, File::RDWR | File::CREAT) do |f|
|
|
mn = CertManager.new
|
|
unless mn.error?
|
|
@cert_info = mn.get_detail_cert_info(params[:id])
|
|
if mn.error?
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
else
|
|
@list_clients_full = mn.get_clients_certs('')
|
|
if mn.error?
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
else
|
|
pg = Paginator.new(params, PER_PAGE)
|
|
@list_clients = pg.get_page(@list_clients_full)
|
|
@pages = pg.pages_info(@list_clients_full)
|
|
end
|
|
end
|
|
else
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
if @error.nil?
|
|
@list_servers_full = mn.get_server_certs.map { |item| item[:ui][:CN] }.reject(&:empty?).uniq
|
|
end
|
|
f.flock(File::LOCK_UN)
|
|
end
|
|
|
|
@page_name = I18n.t('pages.clients')
|
|
@menu = true
|
|
if @error.nil?
|
|
erb :listc
|
|
else
|
|
erb :errinfo
|
|
end
|
|
|
|
end
|
|
|
|
get '/revoke/:id', :auth => 'creator' do
|
|
@page_name = I18n.t('pages.revocation')
|
|
begin
|
|
if params[:id].nil? || params[:id].strip == ''
|
|
@error = I18n.t('errors.revocation_missing_id')
|
|
@log = ""
|
|
raise ArgumentError
|
|
end
|
|
File.open(LOCK_PATH, File::RDWR | File::CREAT) do |f|
|
|
mn = CertManager.new
|
|
unless mn.error?
|
|
@cert_info = mn.revoke_certificat(params[:id])
|
|
if mn.error?
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
else
|
|
if @cert_info.nil?
|
|
@error = I18n.t('errors.revocation_failed')
|
|
@log = mn.log?
|
|
end
|
|
end
|
|
else
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
f.flock(File::LOCK_UN)
|
|
end
|
|
rescue ArgumentError
|
|
#Nothing to do
|
|
end
|
|
|
|
if @error.nil?
|
|
if @cert_info[:is_client]
|
|
redirect "/showc/#{@cert_info[:id]}"
|
|
else
|
|
redirect "/shows/#{@cert_info[:id]}"
|
|
end
|
|
else
|
|
erb :errinfo
|
|
end
|
|
|
|
end
|
|
|
|
post '/addclient', :auth => 'creator' do
|
|
@page_name = I18n.t('pages.clients')
|
|
begin
|
|
if params['server_domain'].nil? || params['server_domain'].strip == ''
|
|
@error = I18n.t('errors.server_domain_missing')
|
|
@log = ""
|
|
raise ArgumentError
|
|
end
|
|
if params['client'].nil? || params['client'].strip == ''
|
|
@error = I18n.t('errors.client_id_missing')
|
|
@log = ""
|
|
raise ArgumentError
|
|
end
|
|
if params['validity_days'].nil? || params['validity_days'].to_i < 1
|
|
@error = I18n.t('errors.validity_days_missing')
|
|
@log = ""
|
|
raise ArgumentError
|
|
end
|
|
File.open(LOCK_PATH, File::RDWR | File::CREAT) do |f|
|
|
mn = CertManager.new
|
|
unless mn.error?
|
|
@cert_info = mn.add_client_cert(params['server_domain'], params['client'], params['validity_days'])
|
|
if mn.error?
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
else
|
|
if @cert_info.nil?
|
|
@error = I18n.t('errors.cert_created_error')
|
|
@log = mn.log?
|
|
end
|
|
end
|
|
else
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
f.flock(File::LOCK_UN)
|
|
end
|
|
rescue ArgumentError
|
|
#Nothing to do
|
|
end
|
|
|
|
if @error.nil?
|
|
redirect "/showc/#{@cert_info[:id]}"
|
|
else
|
|
erb :errinfo
|
|
end
|
|
end
|
|
|
|
post '/addserver', :auth => 'creator' do
|
|
@page_name = I18n.t('pages.servers')
|
|
begin
|
|
if params['domains'].nil? || params['domains'].strip == ''
|
|
@error = I18n.t('errors.domains_missing')
|
|
@log = ""
|
|
raise ArgumentError
|
|
end
|
|
if params['validity_days'].nil? || params['validity_days'].to_i < 1
|
|
@error = I18n.t('errors.validity_days_missing')
|
|
@log = ""
|
|
raise ArgumentError
|
|
end
|
|
File.open(LOCK_PATH, File::RDWR | File::CREAT) do |f|
|
|
mn = CertManager.new
|
|
unless mn.error?
|
|
@cert_info = mn.add_cert(params['validity_days'], params['domains'])
|
|
if mn.error?
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
else
|
|
if @cert_info.nil?
|
|
@error = I18n.t('errors.cert_created_error')
|
|
@log = mn.log?
|
|
end
|
|
end
|
|
else
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
f.flock(File::LOCK_UN)
|
|
end
|
|
rescue ArgumentError
|
|
#Nothing to do
|
|
end
|
|
|
|
if @error.nil?
|
|
redirect "/shows/#{@cert_info[:id]}"
|
|
else
|
|
erb :errinfo
|
|
end
|
|
end
|
|
|
|
get '/download/:id' ,:auth => 'creator' do
|
|
binary_data = nil
|
|
File.open(LOCK_PATH, File::RDWR | File::CREAT) do |f|
|
|
mn = CertManager.new
|
|
unless mn.error?
|
|
binary_data = mn.get_cert_binary(params[:id])
|
|
if binary_data.nil?
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
else
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
f.flock(File::LOCK_UN)
|
|
end
|
|
|
|
if @error.nil?
|
|
content_type 'application/octet-stream'
|
|
attachment('keys.zip')
|
|
binary_data[:zip]
|
|
else
|
|
erb :errinfo
|
|
end
|
|
|
|
end
|
|
|
|
get '/ulist' ,:auth => 'admin' do
|
|
@menu = true
|
|
@page_name = I18n.t('pages.users')
|
|
@tab = 0
|
|
@users = session[:user].list_users
|
|
@pages = Paginator.new(params, PER_PAGE).pages_info(@users)
|
|
|
|
erb :ulist
|
|
|
|
end
|
|
|
|
get '/deleteuser/:id', :auth => 'admin' do
|
|
user_id = params[:id]
|
|
result = session[:user].del_user(nil, user_id)
|
|
|
|
if result.nil? || result[:error].nil?
|
|
redirect '/ulist'
|
|
else
|
|
@error = result[:error]
|
|
erb :errinfo
|
|
end
|
|
end
|
|
|
|
post '/adduser', :auth => 'admin' do
|
|
name = params[:login]
|
|
password = params[:password]
|
|
email = params[:email] || ''
|
|
role = params[:role]
|
|
|
|
if name.nil? || name.strip == '' || password.nil? || password.strip == '' || role.nil?
|
|
@error = 'All fields are required'
|
|
erb :errinfo
|
|
else
|
|
session[:user].add_user(name, password, email, role)
|
|
if session[:user].err
|
|
@error = session[:user].err
|
|
erb :errinfo
|
|
else
|
|
redirect '/ulist'
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/edituser/:id', :auth => 'admin' do
|
|
@page_name = I18n.t('pages.users')
|
|
user_id = params[:id]
|
|
@selected_user = session[:user].user_info(nil, user_id)
|
|
|
|
if @selected_user.nil?
|
|
@error = I18n.t('errors.user_not_found')
|
|
erb :errinfo
|
|
else
|
|
@menu = true
|
|
@tab = 1
|
|
@users = session[:user].list_users
|
|
@pages = Paginator.new(params, PER_PAGE).pages_info(@users)
|
|
erb :ulist
|
|
end
|
|
end
|
|
|
|
post '/edituser/:id', :auth => 'admin' do
|
|
@selected_user = session[:user].user_info(nil, params[:id])
|
|
|
|
if @selected_user.nil?
|
|
@error = I18n.t('errors.user_not_found')
|
|
erb :errinfo
|
|
else
|
|
name = params[:login]
|
|
password = params[:password]
|
|
role = params[:role]
|
|
id = params[:id]
|
|
email = params[:email]
|
|
|
|
if name.nil? || name.strip == '' || role.nil?
|
|
@error = 'All fields are required'
|
|
erb :errinfo
|
|
else
|
|
session[:user].update_user(name, password, email, role, id)
|
|
if session[:user].err
|
|
@error = session[:user].err
|
|
erb :errinfo
|
|
else
|
|
redirect '/ulist'
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/login' do
|
|
redirect '/' if hasperms?('user')
|
|
@page_name = I18n.t('pages.login')
|
|
erb :login
|
|
end
|
|
|
|
post '/login' do
|
|
@page_name = I18n.t('pages.login')
|
|
name = params[:login]
|
|
password = params[:password]
|
|
user_session = UserSessionData.new(name, password)
|
|
|
|
if user_session.auth?
|
|
session[:user] = user_session
|
|
redirect '/'
|
|
else
|
|
@error = I18n.t('errors.invalid_username_password')
|
|
erb :login
|
|
end
|
|
end
|
|
|
|
get '/logout' do
|
|
session[:user] = nil
|
|
|
|
redirect '/'
|
|
end
|
|
|
|
get '/install' do
|
|
@page_name = I18n.t('pages.install_server')
|
|
if File.exist?('utils/custom_config.sh')
|
|
@reason = I18n.t('messages.install_not_possible')
|
|
@info_descr = I18n.t('messages.install_detected')
|
|
erb :info
|
|
elsif GRANTED_UTILS.any? { |util| !File.exist?(util) }
|
|
@reason = I18n.t('messages.install_not_possible')
|
|
@info_descr = I18n.t('messages.missing_utilities', missing: GRANTED_UTILS.reject { |util| File.exist?(util) }.join(', '))
|
|
erb :info
|
|
else
|
|
erb :config
|
|
end
|
|
end
|
|
|
|
post '/install' do
|
|
File.open(LOCK_PATH, File::RDWR | File::CREAT) do |f|
|
|
result = f.flock(File::LOCK_EX | File::LOCK_NB)
|
|
@page_name = I18n.t('pages.install_server')
|
|
if File.exist?('utils/custom_config.sh')
|
|
f.flock(File::LOCK_UN)
|
|
@reason = I18n.t('messages.install_not_possible')
|
|
@info_descr = I18n.t('messages.install_detected')
|
|
erb :info
|
|
elsif GRANTED_UTILS.any? { |util| !File.exist?(util) }
|
|
f.flock(File::LOCK_UN)
|
|
@reason = I18n.t('messages.install_not_possible')
|
|
@info_descr = I18n.t('messages.missing_utilities', missing: GRANTED_UTILS.reject { |util| File.exist?(util) }.join(', '))
|
|
erb :info
|
|
halt
|
|
end
|
|
|
|
cert_path = params['cert-path']
|
|
org_name = params['org-name']
|
|
common_name = params['common-name']
|
|
cert_password = params['cert-password']
|
|
country_name = params['country-name']
|
|
validity_days = params['validity-days']
|
|
|
|
cert_path = File.expand_path(cert_path) unless cert_path.start_with?('/')
|
|
|
|
if !(cert_path.strip.empty? && org_name.strip.empty? && common_name.strip.empty? && cert_password.strip.empty? && country_name.strip.empty? && validity_days.strip.empty?)
|
|
if File.directory?(cert_path) && !cert_path.start_with?('/etc')
|
|
File.open('utils/custom_config.sh', 'w') do |file|
|
|
file.puts %(ROOT_DIR="#{cert_path}")
|
|
file.puts %(COUNTRY_NAME="#{country_name}")
|
|
file.puts %(ORG_NAME="#{org_name}")
|
|
file.puts %(COMM_NAME="#{common_name}")
|
|
file.puts %(SERT_PASS="#{cert_password}")
|
|
file.puts %(VAL_DAYS="#{validity_days}")
|
|
end
|
|
result_status = 0
|
|
result_error = ''
|
|
Dir.chdir('utils') do
|
|
result = `bash ./prepare.sh`
|
|
result_status = $?.exitstatus
|
|
if result_status != 0
|
|
result_error = result.strip
|
|
Dir.chdir('../..')
|
|
end
|
|
end
|
|
f.flock(File::LOCK_UN)
|
|
if result_status != 0
|
|
@reason = I18n.t('messages.install_failed', cert_path: cert_path)
|
|
@info_descr = result_error
|
|
else
|
|
@reason = I18n.t('messages.install_success')
|
|
@info_descr = I18n.t('messages.install_success_descr')
|
|
end
|
|
erb :info
|
|
end
|
|
else
|
|
f.flock(File::LOCK_UN)
|
|
@reason = I18n.t('messages.install_not_possible')
|
|
@info_descr = I18n.t('messages.install_incomplete')
|
|
erb :info
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/perms' do
|
|
status 403
|
|
@reason = I18n.t('messages.install_failed', cert_path: cert_path)
|
|
@info_descr = 'Авторизируйтесь или обратитесь к администратору для повышения своих прав.'
|
|
erb :perms
|
|
end
|
|
|
|
get '/apiinfo', :auth => 'user' do
|
|
@page_name = I18n.t('pages.api')
|
|
@menu = true
|
|
erb :api
|
|
end
|
|
|
|
get '/root', :auth => 'user' do
|
|
@page_name = I18n.t('pages.root')
|
|
@menu = true
|
|
File.open(LOCK_PATH, File::RDWR | File::CREAT) do |f|
|
|
mn = CertManager.new
|
|
unless mn.error?
|
|
@cert_info = mn.get_root_info
|
|
if !mn.error.nil?
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
else
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
f.flock(File::LOCK_UN)
|
|
end
|
|
if @error.nil?
|
|
erb :root
|
|
else
|
|
erb :errinfo
|
|
end
|
|
end
|
|
|
|
not_found do
|
|
request_path = env['REQUEST_PATH']
|
|
|
|
status 404
|
|
if request_path.start_with?('/api/v1')
|
|
content_type 'application/json'
|
|
{ error: I18n.t('errors.page_not_found'), content: nil }.to_json
|
|
else
|
|
@page_name = I18n.t('pages.not_found')
|
|
@reason = I18n.t('pages.not_found')
|
|
@info_descr = I18n.t('pages.not_found')
|
|
erb :info
|
|
end
|
|
end
|
|
|
|
# API v1
|
|
|
|
post '/api/v1/login' do
|
|
login = params[:login]
|
|
password = params[:password]
|
|
|
|
if login.nil? || login.strip == '' || password.nil? || password.strip == ''
|
|
{ error: I18n.t('errors.invalid_username_password'), content: nil }.to_json
|
|
else
|
|
user_session = UserSessionData.new(login, password)
|
|
if user_session.auth?
|
|
headers = {
|
|
exp: Time.now.to_i + LIFE_TOKEN
|
|
}
|
|
token = JWT.encode({ user: user_session.serialize }, settings.signing_key, 'RS256', headers)
|
|
{ error: nil, content: { token: token } }.to_json
|
|
else
|
|
{ error: I18n.t('errors.invalid_username_password'), content: nil }.to_json
|
|
end
|
|
end
|
|
end
|
|
|
|
post '/api/v1/servers', :authtok => 'user' do
|
|
@error = nil
|
|
@log = nil
|
|
@list_serv_full = []
|
|
File.open(LOCK_PATH, File::RDWR | File::CREAT) do |f|
|
|
mn = CertManager.new
|
|
unless mn.error?
|
|
@list_serv_full = mn.get_server_certs
|
|
if mn.error?
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
else
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
f.flock(File::LOCK_UN)
|
|
end
|
|
content_type :json
|
|
if @error.nil?
|
|
{ error: nil, content: @list_serv_full }.to_json
|
|
else
|
|
{ error: @error, content: @log }.to_json
|
|
end
|
|
end
|
|
|
|
post '/api/v1/clients', :authtok => 'user' do
|
|
@error = nil
|
|
@log = nil
|
|
@list_clients_full = []
|
|
File.open(LOCK_PATH, File::RDWR | File::CREAT) do |f|
|
|
mn = CertManager.new
|
|
unless mn.error?
|
|
@list_clients_full = mn.get_clients_certs('')
|
|
if mn.error?
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
else
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
f.flock(File::LOCK_UN)
|
|
end
|
|
content_type :json
|
|
if @error.nil?
|
|
{ error: nil, content: @list_clients_full }.to_json
|
|
else
|
|
{ error: @error, content: @log }.to_json
|
|
end
|
|
end
|
|
|
|
post '/api/v1/certinfo/:id', :authtok => 'user' do
|
|
@error = nil
|
|
@log = nil
|
|
@list_clients_full = []
|
|
File.open(LOCK_PATH, File::RDWR | File::CREAT) do |f|
|
|
mn = CertManager.new
|
|
unless mn.error?
|
|
@cert_info = mn.get_detail_cert_info(params[:id])
|
|
if mn.error?
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
else
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
f.flock(File::LOCK_UN)
|
|
end
|
|
content_type :json
|
|
if @error.nil?
|
|
{ error: nil, content: @cert_info }.to_json
|
|
else
|
|
{ error: @error, content: @log }.to_json
|
|
end
|
|
end
|
|
|
|
post '/api/v1/root', :authtok => 'user' do
|
|
@error = nil
|
|
@log = nil
|
|
@cert_info = nil
|
|
File.open(LOCK_PATH, File::RDWR | File::CREAT) do |f|
|
|
mn = CertManager.new
|
|
unless mn.error?
|
|
@cert_info = mn.get_root_info
|
|
if mn.error?
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
else
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
f.flock(File::LOCK_UN)
|
|
end
|
|
content_type :json
|
|
if @error.nil?
|
|
{ error: nil, content: @cert_info }.to_json
|
|
else
|
|
{ error: @error, content: @log }.to_json
|
|
end
|
|
end
|
|
|
|
post '/api/v1/revoke/:id', :authtok => 'creator' do
|
|
@error = nil
|
|
@log = nil
|
|
@list_clients_full = []
|
|
File.open(LOCK_PATH, File::RDWR | File::CREAT) do |f|
|
|
mn = CertManager.new
|
|
unless mn.error?
|
|
@cert_info = mn.revoke_certificat(params[:id])
|
|
if mn.error?
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
else
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
f.flock(File::LOCK_UN)
|
|
end
|
|
content_type :json
|
|
if @error.nil?
|
|
{ error: nil, content: @cert_info }.to_json
|
|
else
|
|
{ error: @error, content: @log }.to_json
|
|
end
|
|
end
|
|
|
|
post '/api/v1/addclient', :authtok => 'creator' do
|
|
@log = nil
|
|
@error = nil
|
|
begin
|
|
if params['server_domain'].nil? || params['server_domain'].strip == ''
|
|
@error = I18n.t('errors.server_domain_missing')
|
|
@log = ""
|
|
raise ArgumentError
|
|
end
|
|
if params['client'].nil? || params['client'].strip == ''
|
|
@error = I18n.t('errors.client_id_missing')
|
|
@log = ""
|
|
raise ArgumentError
|
|
end
|
|
if params['validity_days'].nil? || params['validity_days'].to_i < 1
|
|
@error = I18n.t('errors.validity_days_missing')
|
|
@log = ""
|
|
raise ArgumentError
|
|
end
|
|
File.open(LOCK_PATH, File::RDWR | File::CREAT) do |f|
|
|
mn = CertManager.new
|
|
unless mn.error?
|
|
@cert_info = mn.add_client_cert(params['server_domain'], params['client'], params['validity_days'])
|
|
if mn.error?
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
else
|
|
if @cert_info.nil?
|
|
@error = I18n.t('errors.cert_created_error')
|
|
@log = mn.log?
|
|
end
|
|
end
|
|
else
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
f.flock(File::LOCK_UN)
|
|
end
|
|
rescue ArgumentError
|
|
#Nothing to do
|
|
end
|
|
|
|
content_type :json
|
|
if @error.nil?
|
|
{ error: nil, content: @cert_info }.to_json
|
|
else
|
|
{ error: @error, content: @log }.to_json
|
|
end
|
|
end
|
|
|
|
post '/api/v1/addserver', :authtok => 'creator' do
|
|
@log = nil
|
|
@error = nil
|
|
begin
|
|
if params['domains'].nil? || params['domains'].strip == ''
|
|
@error = I18n.t('errors.domains_missing')
|
|
@log = ""
|
|
raise ArgumentError
|
|
end
|
|
if params['validity_days'].nil? || params['validity_days'].to_i < 1
|
|
@error = I18n.t('errors.validity_days_missing')
|
|
@log = ""
|
|
raise ArgumentError
|
|
end
|
|
File.open(LOCK_PATH, File::RDWR | File::CREAT) do |f|
|
|
mn = CertManager.new
|
|
unless mn.error?
|
|
@cert_info = mn.add_cert(params['validity_days'], params['domains'])
|
|
if mn.error?
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
else
|
|
if @cert_info.nil?
|
|
@error = I18n.t('errors.cert_created_error')
|
|
@log = mn.log?
|
|
end
|
|
end
|
|
else
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
f.flock(File::LOCK_UN)
|
|
end
|
|
rescue ArgumentError
|
|
#Nothing to do
|
|
end
|
|
|
|
content_type :json
|
|
if @error.nil?
|
|
{ error: nil, content: @cert_info }.to_json
|
|
else
|
|
{ error: @error, content: @log }.to_json
|
|
end
|
|
end
|
|
|
|
post '/api/v1/download/:id' ,:auth => 'creator' do
|
|
@log = nil
|
|
@error = nil
|
|
binary_data = nil
|
|
File.open(LOCK_PATH, File::RDWR | File::CREAT) do |f|
|
|
mn = CertManager.new
|
|
unless mn.error?
|
|
binary_data = mn.get_cert_binary(params[:id])
|
|
if binary_data.nil?
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
else
|
|
@error = mn.error
|
|
@log = mn.log?
|
|
end
|
|
f.flock(File::LOCK_UN)
|
|
end
|
|
|
|
content_type :json
|
|
if @error.nil?
|
|
{ error: nil, content: Base64.encode64(binary_data) }.to_json
|
|
else
|
|
{ error: @error, content: @log }.to_json
|
|
end
|
|
|
|
end
|
|
|
|
post '/api/v1/ulist' ,:authtok => 'admin' do
|
|
@log = nil
|
|
@users = @global_session[:user].list_users
|
|
@error = @global_session[:user].err
|
|
|
|
content_type :json
|
|
if @error.nil?
|
|
{ error: nil, content: @users.map{ |item| item.to_hash } }.to_json
|
|
else
|
|
{ error: @error, content: @log }.to_json
|
|
end
|
|
|
|
end
|
|
|
|
post '/api/v1/deleteuser/:id', :authtok => 'admin' do
|
|
@log = nil
|
|
user_id = params[:id]
|
|
result = @global_session[:user].del_user(nil, user_id)
|
|
@error = @global_session[:user].err
|
|
|
|
content_type :json
|
|
if result.nil? || result[:error].nil?
|
|
{ error: nil, content: I18n.t('messages.user_deleted') }.to_json
|
|
else
|
|
{ error: @error, content: @log }.to_json
|
|
end
|
|
end
|
|
|
|
post '/api/v1/adduser', :authtok => 'admin' do
|
|
@log = nil
|
|
@error = nil
|
|
name = params[:login]
|
|
password = params[:password]
|
|
email = params[:email] || ''
|
|
role = params[:role]
|
|
|
|
if name.nil? || name.strip == '' || password.nil? || password.strip == '' || role.nil?
|
|
@error = I18n.t('errors.all_fields_required')
|
|
end
|
|
|
|
@global_session[:user].add_user(name, password, email, role) if @error.nil?
|
|
@error = @global_session[:user].err
|
|
|
|
content_type :json
|
|
if @error.nil?
|
|
{ error: nil, content: I18n.t('messages.user_added') }.to_json
|
|
else
|
|
{ error: @error, content: @log }.to_json
|
|
end
|
|
end
|
|
|
|
post '/api/v1/edituser/:id', :authtok => 'admin' do
|
|
@log = nil
|
|
@error = nil
|
|
@selected_user = @global_session[:user].user_info(nil, params[:id])
|
|
|
|
if @selected_user.nil?
|
|
@error = I18n.t('errors.user_not_found')
|
|
else
|
|
name = params[:login]
|
|
password = params[:password]
|
|
role = params[:role]
|
|
id = params[:id]
|
|
email = params[:email]
|
|
|
|
if name.nil? || name.strip == '' || role.nil?
|
|
@error = I18n.t('errors.all_fields_required')
|
|
else
|
|
@global_session[:user].update_user(name, password, email, role, id)
|
|
@error = @global_session[:user].err
|
|
end
|
|
end
|
|
|
|
content_type :json
|
|
if @error.nil?
|
|
{ error: nil, content: I18n.t('messages.user_added') }.to_json
|
|
else
|
|
{ error: @error, content: @log }.to_json
|
|
end
|
|
end
|
|
|
|
post '/api/v1/install' do
|
|
File.open(LOCK_PATH, File::RDWR | File::CREAT) do |f|
|
|
result = f.flock(File::LOCK_EX | File::LOCK_NB)
|
|
if File.exist?('utils/custom_config.sh')
|
|
f.flock(File::LOCK_UN)
|
|
@reason = I18n.t('messages.install_not_possible')
|
|
@info_descr = I18n.t('messages.install_detected')
|
|
content_type :json
|
|
{ error: @reason, content: @info_descr }.to_json
|
|
halt 503
|
|
elsif GRANTED_UTILS.any? { |util| !File.exist?(util) }
|
|
f.flock(File::LOCK_UN)
|
|
@reason = I18n.t('messages.install_not_possible')
|
|
@info_descr = I18n.t('messages.missing_utilities', missing: GRANTED_UTILS.reject { |util| File.exist?(util) }.join(', '))
|
|
content_type :json
|
|
{ error: @reason, content: @info_descr }.to_json
|
|
halt 503
|
|
end
|
|
|
|
cert_path = params['cert-path']
|
|
org_name = params['org-name']
|
|
common_name = params['common-name']
|
|
cert_password = params['cert-password']
|
|
country_name = params['country-name']
|
|
validity_days = params['validity-days']
|
|
|
|
cert_path = File.expand_path(cert_path) unless cert_path.start_with?('/')
|
|
|
|
if !(cert_path.strip.empty? && org_name.strip.empty? && common_name.strip.empty? && cert_password.strip.empty? && country_name.strip.empty? && validity_days.strip.empty?)
|
|
if File.directory?(cert_path) && !cert_path.start_with?('/etc')
|
|
File.open('utils/custom_config.sh', 'w') do |file|
|
|
file.puts %(ROOT_DIR="#{cert_path}")
|
|
file.puts %(COUNTRY_NAME="#{country_name}")
|
|
file.puts %(ORG_NAME="#{org_name}")
|
|
file.puts %(COMM_NAME="#{common_name}")
|
|
file.puts %(SERT_PASS="#{cert_password}")
|
|
file.puts %(VAL_DAYS="#{validity_days}")
|
|
end
|
|
result_status = 0
|
|
result_error = ''
|
|
Dir.chdir('utils') do
|
|
result = `bash ./prepare.sh`
|
|
result_status = $?.exitstatus
|
|
if result_status != 0
|
|
result_error = result.strip
|
|
Dir.chdir('../..')
|
|
end
|
|
end
|
|
f.flock(File::LOCK_UN)
|
|
if result_status != 0
|
|
content_type :json
|
|
halt(200, { content: '', error: result_error }.to_json)
|
|
else
|
|
content_type :json
|
|
halt(200, { content: I18n.t('messages.install_success'), error: '' }.to_json)
|
|
end
|
|
end
|
|
else
|
|
f.flock(File::LOCK_UN)
|
|
@reason = I18n.t('messages.install_not_possible')
|
|
@info_descr = I18n.t('messages.install_incomplete')
|
|
content_type :json
|
|
{ error: @reason, content: @info_descr }.to_json
|
|
halt 503
|
|
end
|
|
end
|
|
end
|