Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

View and Delete Users #17

Merged
merged 1 commit into from
Jan 2, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 51 additions & 1 deletion app/Http/Controllers/Admin/AccountsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
namespace Pterodactyl\Http\Controllers\Admin;

use Alert;
use Mail;
use Pterodactyl\Models\User;
use Pterodactyl\Repositories\UserRepository;
use Pterodactyl\Models\Server;

use Pterodactyl\Http\Controllers\Controller;
use Illuminate\Http\Request;
Expand Down Expand Up @@ -38,7 +40,16 @@ public function getNew(Request $request)

public function getView(Request $request, $id)
{
//
return view('admin.accounts.view', ['user' => User::findOrFail($id), 'servers' => Server::where('owner', $id)->first()]);
}

public function getDelete(Request $request, $id)
{
$user = new UserRepository;
$user->delete($id);

Alert::success('An account has been successfully deleted.')->flash();
return redirect()->route('admin.accounts');
}

public function postNew(Request $request)
Expand All @@ -65,4 +76,43 @@ public function postNew(Request $request)

}

public function postUpdate(Request $request)
{
$this->validate($request, [
'email' => 'required|email|unique:users,email,'.$request->input('user'),
'root_admin' => 'required',
'password' => 'required_with:password_confirmation',
'password_confirmation' => 'required_with:password'
]);

try {

$users = new UserRepository;
$user = [];

$user['email'] = $request->input('email');
$user['root_admin'] = $request->input('root_admin');

if(!empty($request->input('password'))) {
$user['password'] = $request->input('password');
}

$users->update($request->input('user'), $user);

} catch (\Exception $e) {
Alert::danger('An error occured while attempting to update a user. Please check the logs or try again.')->flash();
return redirect()->route('admin.accounts.view', ['id' => $request->input('user')]);
}

if($request->input('email_user')) {
Mail::send('emails.new_password', ['user' => User::findOrFail($request->input('user')), 'password' => $request->input('password')], function($message) use ($request) {
$message->to($request->input('email'))->subject('Pterodactyl - Admin Reset Password');
});
}

Alert::success('A user was successfully updated.')->flash();
return redirect()->route('admin.accounts.view', ['id' => $request->input('user')]);

}

}
8 changes: 6 additions & 2 deletions app/Http/Routes/AdminRoutes.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@ public function map(Router $router) {

// Account Routes
$router->group(['prefix' => 'accounts'], function ($server) use ($router) {
$router->get('/', [ 'as' => 'admin.accounts', 'uses' => 'Admin\AccountsController@getIndex' ]);
$router->get('/view/{id}', [ 'as' => 'admin.accounts.view', 'uses' => 'Admin\AccountsController@getView' ]);

$router->get('/new', [ 'as' => 'admin.accounts.new', 'uses' => 'Admin\AccountsController@getNew' ]);
$router->post('/new', [ 'as' => 'admin.accounts.new', 'uses' => 'Admin\AccountsController@postNew' ]);

$router->get('/', [ 'as' => 'admin.accounts', 'uses' => 'Admin\AccountsController@getIndex' ]);
$router->get('/view/{id}', [ 'as' => 'admin.accounts.view', 'uses' => 'Admin\AccountsController@getView' ]);

$router->post('/update', [ 'as' => 'admin.accounts.update', 'uses' => 'Admin\AccountsController@postUpdate' ]);
$router->get('/delete/{id}', [ 'as' => 'admin.accounts.delete', 'uses' => 'Admin\AccountsController@getDelete' ]);
});

// Server Routes
Expand Down
32 changes: 32 additions & 0 deletions app/Repositories/UserRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,36 @@ public function create($username, $email, $password)

}

/**
* Updates a user on the panel. Returns true if the update was successful.
*
* @param string $username
* @param string $email
* @param string $password An unhashed version of the user's password.
* @return boolean
*/
public function update($id, $user)
{
if(array_key_exists('password', $user)) {
$user['password'] = Hash::make($user['password']);
}

User::where('id', $id)->update($user);
return true;
}

/**
* Deletes a user on the panel. Returns true if the deletion was successful.
*
* @param string $username
* @param string $email
* @param string $password An unhashed version of the user's password.
* @return boolean
*/
public function delete($id)
{
User::destroy($id);
return true;
}

}
5 changes: 5 additions & 0 deletions resources/lang/en/base.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@

'validation_error' => 'An error occured while validating the data you submitted:',

'confirm' => 'Are you sure?',
'failed' => 'These credentials do not match our records.',
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
'view_as_admin' => 'You are viewing this server listing as an admin. As such, all servers installed on the system are displayed. Any servers that you are set as the owner of are marked with a blue dot to the left of their name.',
'server_name' => 'Server Name',
'no_servers' => 'You do not currently have any servers listed on your account.',
'form_error' => 'The following errors were encountered while trying to process this request.',
'password_req' => 'Passwords must meet the following requirements: at least one uppercase character, one lowercase character, one digit, and be at least 8 characters in length.',
'root_administrator' => 'Setting this to "Yes" gives a user full administrative access to PufferPanel.',

'account' => [
'totp_header' => 'Two-Factor Authentication',
Expand All @@ -35,6 +37,9 @@
'totp_enabled' => 'Your account has been enabled with TOTP verification. Please click the close button on this box to finish.',
'totp_enabled_error' => 'The TOTP token provided was unable to be verified. Please try again.',

'email_password' => 'Email Password',
'update_user' => 'Update User',
'delete_user' => 'Delete User',
'update_email' => 'Update Email',
'new_email' => 'New Email',
'new_password' => 'New Password',
Expand Down
1 change: 1 addition & 0 deletions resources/lang/en/server.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'socket_status_crashed' => 'This server has been detected as CRASHED.',
],
'index' => [
'add_new' => 'Add New Server',
'memory_use' => 'Memory Usage',
'cpu_use' => 'CPU Usage',
'xaxis' => 'Time (2s Increments)',
Expand Down
4 changes: 4 additions & 0 deletions resources/lang/en/strings.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,9 @@
'submit' => 'Submit',
'current_password' => 'Current Password',
'again' => 'Again',
'registered' => 'Registered',
'root_administrator' => 'Root Administrator',
'yes' => 'Yes',
'no' => 'No'

];
155 changes: 155 additions & 0 deletions resources/views/admin/accounts/view.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
@extends('layouts.admin')

@section('title')
Viewing User
@endsection

@section('content')
<div class="col-md-9">
<ul class="breadcrumb">
<li><a href="/admin">Admin Controls</a></li>
<li><a href="/admin/accounts">Accounts</a></li>
<li class="active">{{ $user->id }}</li>
</ul>
@if (count($errors) > 0)
<div class="alert alert-danger">
<strong>{{ trans('strings.whoops') }}!</strong> {{ trans('auth.errorencountered') }}<br><br>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@foreach (Alert::getMessages() as $type => $messages)
@foreach ($messages as $message)
<div class="alert alert-{{ $type }} alert-dismissable" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
{!! $message !!}
</div>
@endforeach
@endforeach
<h3>Viewing User: {{ $user->email }}</h3><hr />
<div class="row">
<div class="col-md-12">
<form action="/admin/accounts/update" method="post">
<div class="col-md-6">
<fieldset>
<div class="form-group">
<label for="email" class="control-label">{{ trans('strings.email') }}</label>
<div>
<input type="text" name="email" value="{{ $user->email }}" class="form-control">
</div>
</div>
<div class="form-group">
<label for="registered" class="control-label">{{ trans('strings.registered') }}</label>
<div>
<input type="text" name="registered" value="{{ $user->created_at }}" readonly="readonly" class="form-control">
</div>
</div>
<div class="form-group">
<label for="root_admin" class="control-label">{{ trans('strings.root_administrator') }}</label>
<div>
<select name="root_admin" class="form-control">
<option value="0">{{ trans('strings.no') }}</option>
<option value="1" @if($user->root_admin)selected="selected"@endif>{{ trans('strings.yes') }}</option>
</select>
<p><small class="text-muted"><em><strong><i class="fa fa-warning"></i></strong> {{ trans('base.root_administrator') }}</em></small></p>
</div>
</div>
<div class="form-group">
<input type="hidden" name="user" value="{{ $user->id }}">
{!! csrf_field() !!}
<input type="submit" value="{{ trans('base.account.update_user') }}" class="btn btn-primary btn-sm">
<a href="/admin/accounts/delete/{{ $user->id }}">
<button id="delete" type="button" class="btn btn-sm btn-danger" value="{{ trans('base.account.delete_user') }}">{{ trans('base.account.delete_user') }}</button>
</a>
</div>
</fieldset>
</div>
<div class="col-md-6">
<div class="well" style="padding-bottom: 0;">
<h4 class="nopad">{{ trans('base.account.update_pass') }}</h5><hr>
<div class="alert alert-success" style="display:none;margin-bottom:10px;" id="gen_pass"></div>
<div class="form-group">
<label for="password" class="control-label">{{ trans('strings.password') }}</label>
<div>
<input type="password" id="password" name="password" class="form-control">
</div>
</div>
<div class="form-group">
<label for="password_confirmation" class="control-label">{{ trans('auth.confirmpassword') }}</label>
<div>
<input type="password" id="password_confirmation" name="password_confirmation" class="form-control">
<div class="checkbox">
<label><input type="checkbox" name="email_user" value="1">{{ trans('base.account.email_password') }}</label>
</div>
</div>
<button class="btn btn-default btn-sm" id="gen_pass_bttn" type="button">Generate Password</button>
</div>
</div>
</div>
</form>
</div>
</div>
<div class="row">
<div class="col-md-12">
<h3>Associated Servers</h3><hr>
@if($servers)
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th style="width:2%;"></th>
<th>Server Name</th>
<th>Node</th>
<th>Connection</th>
<th style="width:10%;"></th>
</tr>
</thead>
<tbody>
@foreach($servers as $server)
<tr>
<td><a href="/server/{{ $server->uuidShort }}"><i class="fa fa-tachometer"></i></a></td>
<td><a href="/admin/server/view/{{ $server->id }}">{{ $server->name }}</a></td>
<td>{{ $server->node_name }}</td>
<td>{{ $server->server_ip }}:{{ $server->server_port }}</td>
<td>@if($server->active)<span class="label label-success">Enabled</span>@else<span class="label label-danger">Disabled</span>@endif</td>
</td>
@endforeach
</tbody>
</table>
@else
<div class="alert alert-info">There are no servers associated with this account.</div>
@endif
<a href="/admin/servers/new?email={{ $user->email }}"><button type="button" class="btn btn-success btn-sm">{{ trans('server.index.add_new') }}</button></a>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function(){
$("#sidebar_links").find("a[href='/admin/accounts']").addClass('active');
$('#delete').click(function() {
if(confirm('{{ trans('base.confirm') }}')) {
$('#delete').load($(this).attr('href'));
}
});
$("#gen_pass_bttn").click(function(e){
e.preventDefault();
$.ajax({
type: "GET",
url: "/password-gen/12",
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
success: function(data) {
$("#gen_pass").html('<strong>Generated Password:</strong> ' + data).slideDown();
$('input[name="password"], input[name="password_confirmation"]').val(data);
return false;
}
});
return false;
});
});
</script>
@endsection
14 changes: 14 additions & 0 deletions resources/views/emails/new_password.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

<html>
<head>
<title>Pterodactyl - Admin Reset Password</title>
</head>
<body>
<center><h1>Pterodactyl - Admin Reset Password</h1></center>
<p>Hello there! You are receiving this email because an admin has reset the password on your Pterodactyl account.</p>
<p><strong>Login:</strong> <a href="{{ config('app.url') }}/auth/login">{{ config('app.url') }}/auth/login</a><br>
<strong>Email:</strong> {{ $user->email }}<br>
<strong>Password:</strong> {{ $password }}</p>
<p>Thanks,<br>Pterodactyl</p>
</body>
</html>