Kaydet (Commit) 8c8dc2b8 authored tarafından mertcelen's avatar mertcelen

Better permission control

SSH Add list now display user servers.
Missing port added to ssh key list.
Crashes prevented in SSH key list.
Server deletion now removes all connected keys in liman.
Servers now can delete without being online or having a working ssh key.
Dark-Light mode theme switch added.
üst f3578f91
......@@ -20,6 +20,7 @@ class MainController extends Controller
return array_key_exists(request('extension_id'),$value->extensions);
});
$servers = Server::filterPermissions($servers);
// Go through servers and create a city list, it will be used in javascript to highlight cities in map.
$cities = [];
foreach ($servers as $server) {
......@@ -27,6 +28,7 @@ class MainController extends Controller
array_push($cities,$server->city);
}
}
// If user have only servers in one city, redirect to it.
if(count($cities) == 1){
return redirect(route('extension_city',[
......
......@@ -42,6 +42,15 @@ class HomeController extends Controller
}
}
public function setTheme(){
if(\Session::has('dark_mode')){
\Session::remove('dark_mode');
}else{
\Session::put('dark_mode','true');
}
return respond('Tema Guncellendi.');
}
public function new(){
return view('permission.request');
}
......
......@@ -18,6 +18,11 @@ Route::post('/server/kontrol', 'Server\MainController@isAlive')->middleware('par
Route::post('/sunucu/guncelle', 'Server\OneController@update')->name('server_update')->middleware('parameters:server_id,name,control_port,city');
// Remove Server Route
Route::post('/sunucu/sil', 'Server\OneController@remove')->name('server_remove')->middleware('parameters:server_id');
Route::group(['middleware' => ['server']], function () {
......@@ -60,9 +65,4 @@ Route::group(['middleware' => ['server']], function () {
Route::post('/sunucu/yetkilendir', 'Server\OneController@grant')->name('server_grant_permission')->middleware('parameters:server_id,email');
// Remove Server Route
Route::post('/sunucu/sil', 'Server\OneController@remove')->name('server_remove')->middleware('parameters:server_id');
});
\ No newline at end of file
......@@ -10,6 +10,7 @@ class MainController extends Controller
public function __construct()
{
// Specifiy that this controller requires admin middleware in all functions.
$this->middleware('admin');
}
......
......@@ -11,11 +11,13 @@ class SshController extends Controller
public static $protected = true;
public function index(){
// Retrieve User keys.
$keys = Key::where('user_id',\Auth::id())->get();
// Retrieve User servers that has permission.
$servers = Server::all();
foreach ($keys as $key){
$key->server_name = $servers->where('_id',$key->server_id)->first()->name;
}
return view('keys.index',[
"keys" => $keys,
"servers" => $servers
......@@ -23,16 +25,29 @@ class SshController extends Controller
}
public function add(Request $request){
$data = $request->all();
// Get server object, ps: we cannot use server middleware since we may not have access to server at all.
$server = Server::where('_id',request('server_id'))->first();
$key = new Key($data);
// Create object with request parameters, acceptable parameters defined in Key $fillable variable.
$key = new Key($request->all());
// Set User id of Key.
$key->user_id = \Auth::id();
$key->save();
$output = Key::init(request('username'),request('password'),
// Init key with parameters.
$flag = Key::init(request('username'),request('password'),
$server->ip_address,$server->port,\Auth::id());
return [
"result" => 200,
"log" => $output
];
// If key is not usable, cancel operation.
if(!$flag){
return respond('SSH Anahtar Hatasi',201);
}
// Save Key.
$key->save();
// Forward request.
return respond('SSH Anahtari Basariyla Eklendi',200);
}
}
......@@ -14,5 +14,4 @@ class UserController extends Controller
]);
}
}
......@@ -15,9 +15,12 @@ class Admin
*/
public function handle($request, Closure $next)
{
// Check is User is admin, if not, simply abort.
if(!\Auth::user()->isAdmin()){
return respond("Bu işlemi yapmak için yetkiniz yok",403);
}
// Since user is admin, forward request to next target.
return $next($request);
}
}
......@@ -11,6 +11,5 @@ class Authenticate extends Middleware
if (! $request->expectsJson()) {
return route('login');
}
dd('qwe');
}
}
......@@ -12,6 +12,8 @@ class EncryptCookies extends Middleware
* @var array
*/
protected $except = [
// We are using this in order to allow WebSSH to read unencrypted xsrf cookie.
"_xsrf"
];
}
......@@ -16,10 +16,20 @@ class Language
*/
public function handle($request, Closure $next)
{
// Check if web session has a locale set for user.
if ($request->session()->has('locale')) {
// If so, set that locale in to the app to use it later.
$locale = $request->session()->get('locale');
App::setLocale($locale);
}
// Check if session has dark mode set.
if($request->session()->has('dark')){
$request->request->add(['dark_mode' => "true"]);
}
// Forward request to next target.
return $next($request);
}
}
......@@ -8,11 +8,16 @@ class Parameters
{
public function handle($request, Closure $next,...$parameters)
{
// Check for each parameters if it is existing or simply has more characters than 0
foreach ($parameters as $parameter) {
if(!request()->has($parameter) || !strlen(request($parameter))){
// If found something that is missing, abort the process and warn user.
return respond("Missing parameter > $parameter", 403);
}
}
// Forward request to next target.
return $next($request);
}
}
......@@ -7,6 +7,7 @@ use Closure;
class PermissionManager
{
// Verify those values if request have this both in request url or body.
public static $verify = [
"extension" , "script", "server"
];
......
......@@ -8,15 +8,20 @@ class Server
{
public function handle($request, Closure $next)
{
// Extract Server Id from request.
$server_id = null;
if ($request->route('server_id') != null) {
$server_id = $request->route('server_id');
} else if ($request->has('server_id')) {
$server_id = $request->get('server_id');
}
if ($request != null) {
// Check If request has server_id at all.
if ($server_id != null) {
//Let's verify server.
$server = \App\Server::where('_id', $server_id)->first();
//If server is simply not found.
if ($server == null) {
return respond("Sunucu bulunamadı.",404);
......@@ -41,6 +46,7 @@ class Server
}
} else {
// Route specificed using server data but request doesn't have any, so abort request.
return respond("Server bilgisi verilmedi.",404);
}
return $next($request);
......
......@@ -26,10 +26,13 @@ class Key extends Eloquent
// Trust Target Server
shell_exec("ssh-keyscan -p " . $server_port . " -H ". $server_address . " >> ~/.ssh/known_hosts");
}
//Send Keys to target
shell_exec("sshpass -p '" . $password . "' ssh-copy-id -i " . storage_path('keys') . DIRECTORY_SEPARATOR . $account_name ." " . $username
."@" . $server_address ." 2>&1 -p " . $server_port);
return true;
}
public static function initWithKey($username,$key,$server_address,$server_port,$current_name, $new_name){
......
......@@ -10,7 +10,7 @@ class Permission extends Eloquent
protected $connection = 'mongodb';
public static function new($user_id){
// Simply create new permission
// Simply create new permission table
$permissions = new Permission();
$permissions->user_id = $user_id;
......@@ -74,4 +74,5 @@ class Permission extends Eloquent
return $permissions->__get($type);
}
}
......@@ -10,31 +10,61 @@ class Script extends Eloquent
protected $connection = 'mongodb';
public static function readFromFile($uploadedFile){
// Read values from text file.
$file = file_get_contents($uploadedFile);
// Seperate each rows to parse.
$rows = explode("\n", $file);
// Create new script object.
$script = new Script();
// Fill script values using parsed rows.
$script = Script::fillValues($script,$rows);
// Check if script already exists, if so simply don't resave it.
if(Script::where('unique_code',$script->unique_code)->exists()){
return false;
};
// Save and return the script.
$script->save();
return $script;
}
public static function createFile($script,...$parameters){
$script->save();;
// Save script in order to generate unique _id.
$script->save();
//Create File Writer
$file = fopen(storage_path('app' . DIRECTORY_SEPARATOR . 'scripts' ) . DIRECTORY_SEPARATOR . $script->_id, 'w');
// Simply slice the parameters of the function, ex: unique_code, company etc.
$user_inputs = array_slice($parameters[0],0,-1);
// Write each input as a row in to the file.
foreach ($user_inputs as $parameter){
fwrite($file,'#' . $parameter . PHP_EOL);
}
// Write the actual script itself.
fwrite($file,$parameters[0][count($parameters[0]) -1]);
// Close the file writer.
fclose($file);
// Fill values for the database.
return Script::fillValues($script,$user_inputs);
}
public static function fillValues($script, ... $parameters){
// Just a dummy control the correct parameters.
$parameters = $parameters[0];
// Loop through each parameters and set required datas just with specific names in order to save data.
for($i = 0 ; $i <= 12;$i++){
$parameters[$i] = str_replace("# ","",$parameters[$i]);
switch ($i){
......@@ -84,8 +114,4 @@ class Script extends Eloquent
}
return $script;
}
public static function extension($name){
return Script::where('extensions', 'like', '%' . $name . '%')->get();
}
}
......@@ -18,14 +18,14 @@ class Server extends Eloquent
return $this->runSSH($command);
}
public function runSSH($query)
public function runSSH($query, $extra = null)
{
// Log Query
server_log($this->_id, "command_" . $query);
// Build Query
$query = "ssh -p " . $this->port . " " . $this->key->username . "@" . $this->ip_address . " -i " . storage_path('keys') .
DIRECTORY_SEPARATOR . Auth::id() . " " . $query . " 2>&1";
DIRECTORY_SEPARATOR . Auth::id() . " " . $query . " 2>&1" . $extra;
// Execute and return outputs.
return shell_exec($query);
......@@ -52,31 +52,19 @@ class Server extends Eloquent
return shell_exec($query);
}
public function runScript($script, $parameters)
{
public function runScript($script, $parameters,$extra = null){
// Copy script to target.
$this->putFile(storage_path('app/scripts/' . $script->_id), '/tmp/');
// Build Query
$query = ($script->root == 1) ? 'sudo ' : '';
$query = $query . substr($script->language, 1) . ' /tmp/' . $script->_id . " run " . $parameters;
// Execute and return outputs.
return $this->runSSH($query);
}
public function systemScript($name, $parameters)
{
$name = $name . ".lmn";
$copy_file_query = 'scp -P ' . $this->port . " -i " . storage_path('keys') . DIRECTORY_SEPARATOR . Auth::id() . ' ' . storage_path('app/system_scripts/' . $name) . ' ' . $this->key->username . '@' . $this->ip_address . ':/tmp/';
shell_exec($copy_file_query);
shell_exec('sudo chmod +x /tmp/' . $name);
$query = 'sudo /usr/bin/env python3 /tmp/' . $name . " run " . $parameters;
$query = $query = "ssh -p " . $this->port . " " . $this->key->username . "@" . $this->ip_address . " -i " .
storage_path('keys') . DIRECTORY_SEPARATOR . Auth::id() . " " . $query . " 2>&1" . (($name == "network.lmn") ? " > /dev/null 2>/dev/null &" : "");
return shell_exec($query);
return $this->runSSH($query,$extra);
}
public function isRunning($service_name)
{
// Check if services are alive or not.
......@@ -116,7 +104,6 @@ class Server extends Eloquent
'server_id' => $this->id,
'user_id' => Auth::id()
])->first();
if ($key == null) {
return false;
}
......
......@@ -30,23 +30,40 @@ class User extends Authenticatable
];
public function permissions(){
// Check if this function called before in order to prevent more database calls.
if($this->permissions == null){
// Retrieve user permissions and set it into the User object.
$this->permissions = Permission::get($this->_id);
}
// Return permissions just in case user don't want access object again.
return $this->permissions;
}
public function isAdmin(){
// Very simply check status, this function created for more human like code write experience.
return $this->status == 1;
}
public function hasAccess($target,$id = null){
if($this->permissions == null){
$this->permissions = Permission::get($this->_id);
// Ignore everything if user is Admin.
if($this->isAdmin()){
return true;
}
// Call function just in case.
$this->permissions();
// Check if user has access to target at all.
if($this->permissions->__get($target) == null){
return $this->isAdmin();
return false;
}
// Lastly, check if user has permission for specific id of target.
return in_array($id, $this->permissions->__get($target));
}
}
body {
background-color: rgb(43, 43, 45);
color: white;
}
.modal-content, .card, .card-body {
background-color: #2b2b2d;
}
pre {
color: white
}
.navbar .dropdown-menu {
background-color: rgba(255, 255, 255, .1);
border-radius: 20px;
}
.chart{
background-color: #343a40;
}
\ No newline at end of file
......@@ -149,25 +149,6 @@ a, a:hover, .btn-link, .btn-link:hover {
color: white;
}
/*Dark Mode*/
body {
background-color: rgb(43, 43, 45);
color: white;
}
.modal-content, .card, .card-body {
background-color: #2b2b2d;
}
pre {
color: white
}
.navbar .dropdown-menu {
background-color: rgba(255, 255, 255, .1);
border-radius: 20px;
}
.chart {
width: 30%;
min-width: 400px;
......
......@@ -10,22 +10,29 @@
<table class="table">
<thead>
<tr>
<th scope="col">{{ __("Anahtar Adı") }}</th>
<th scope="col">{{ __("Kullanıcı") }}</th>
<th scope="col">{{ __("Sunucu") }}</th>
<th scope="col">{{ __("Kullanıcı") }}</th>
<th scope="col">{{ __("Port") }}</th>
</tr>
</thead>
<tbody data-toggle="modal" data-target="#duzenle">
@foreach ($keys as $key)
<tr onclick="" class="highlight">
<tr>
<td>{{$key->name}}</td>
<td>{{$key->username}}</td>
<td>{{$key->server_name}}</td>
<td>{{$servers->where('_id',$key->server_id)->first()->control_port}}</td>
</tr>
@endforeach
</tbody>
</table>
<?php
$input_servers = [];
foreach($servers as $server){
$input_servers[$server->name] = $server->_id;
}
?>
@include('modal',[
"id"=>"add_key",
"title" => "SSH Anahtar Ekle",
......@@ -33,7 +40,7 @@
"next" => "reload",
"inputs" => [
"Adı" => "name:text",
"Sunucu " => "server_id:text",
"Sunucu Secin:server_id" => $input_servers,
"Kullanıcı Adı" => "username:text",
"Parola" => "password:password"
],
......
......@@ -20,6 +20,10 @@
<link rel="stylesheet" href="{{ asset('css/main.css') }}">
<link rel="stylesheet" href="{{ asset('css/sidebar.css') }}">
<link rel="stylesheet" href="{{ asset('css/fa.min.css') }}">
@if(\Session::has('dark_mode'))
<link rel="stylesheet" href="{{ asset('css/dark.css') }}">
@endif
</head>
<body style="display: block">
<nav class="navbar navbar-dark fixed-top bg-dark flex-md-nowrap p-0">
......@@ -61,6 +65,23 @@
</form>
</li>
</ul>
<ul class="navbar-nav">
<li class="nav-item text-nowrap">
<form action="#" onsubmit="return request('{{route('set_theme')}}',this,reload)"
style="cursor: pointer;">
@if (Session::has('dark_mode'))
<button class="btn btn-link text-white-">
Gece
</button>
@else
<button class="btn btn-link text-white">
Gunduz
</button>
@endif
</form>
</li>
</ul>
<ul class="navbar-nav px-2">
<li class="nav-item text-nowrap" style="cursor: pointer;">
<a class="nav-link text-white" onclick="return request('{{route('logout')}}',new FormData(),reload)"><i
......
......@@ -33,6 +33,9 @@ require_once(app_path('Http/Controllers/Settings/_routes.php'));
// Change the language
Route::post('/locale', 'HomeController@setLocale')->name('set_locale');
// Change the language
Route::post('/theme', 'HomeController@setTheme')->name('set_theme');
// Home Route
Route::get('/', 'HomeController@index')->name('home');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment