Add support for location-specific LDAP OUs. (#3176)

* Add support for location-specific LDAP OUs.

* Shortened variable names as suggested by Codacy review.
This commit is contained in:
Richard Hofman 2017-01-12 20:37:14 +13:00 committed by snipe
parent 2c695cf7e5
commit c506f30562
7 changed files with 129 additions and 7 deletions

View file

@ -69,6 +69,18 @@ class LdapSync extends Command
$results = Ldap::findLdapUsers();
$ldap_ou_locations = Location::whereNotNull('ldap_ou')->get();
if (sizeof($ldap_ou_locations) > 0) {
LOG::debug('Some locations have special OUs set. Locations will be automatically set for users in those OUs.');
}
$results = Ldap::findLdapUsers();
for ($i = 0; $i < $results["count"]; $i++) {
$results[$i]["ldap_location_override"] = false;
$results[$i]["location_id"] = 0;
}
if ($this->option('location')!='') {
$location = Location::where('name', '=', $this->option('location'))->first();
LOG::debug('Location name '.$this->option('location').' passed');
@ -82,9 +94,30 @@ class LdapSync extends Command
}
if (!isset($location)) {
LOG::debug('That location is invalid, so no location will be assigned.');
LOG::debug('That location is invalid, so no location will be assigned by default.');
}
// Grab subsets based on location-specific DNs, and overwrite location for these users.
foreach ($ldap_ou_locations as $ldap_loc) {
$location_users = Ldap::findLdapUsers($ldap_loc->ldap_ou);
$usernames = array();
for ($i = 0; $i < $location_users["count"]; $i++) {
$location_users[$i]["ldap_location_override"] = true;
$location_users[$i]["location_id"] = $ldap_loc->id;
$usernames[] = $location_users[$i][$ldap_result_username][0];
}
// Delete located users from the general group.
foreach ($results as $key => $generic_entry) {
if (in_array($generic_entry[$ldap_result_username][0], $location_users)) {
unset($results[$key]);
}
}
$global_count = $results['count'];
$results = array_merge($location_users, $results);
$results['count'] = $global_count;
}
$tmp_pass = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 20);
$pass = bcrypt($tmp_pass);
@ -99,6 +132,9 @@ class LdapSync extends Command
$item["lastname"] = isset($results[$i][$ldap_result_last_name][0]) ? $results[$i][$ldap_result_last_name][0] : "";
$item["firstname"] = isset($results[$i][$ldap_result_first_name][0]) ? $results[$i][$ldap_result_first_name][0] : "";
$item["email"] = isset($results[$i][$ldap_result_email][0]) ? $results[$i][$ldap_result_email][0] : "" ;
$item["ldap_location_override"] = isset($results[$i]["ldap_location_override"]) ? $results[$i]["ldap_location_override"]:"";
$item["location_id"] = isset($results[$i]["location_id"]) ? $results[$i]["location_id"]:"";
// User exists
$item["createorupdate"] = 'updated';
@ -118,7 +154,9 @@ class LdapSync extends Command
$user->employee_num = e($item["employee_number"]);
$user->activated = 1;
if ($location) {
if ($item['ldap_location_override'] == true) {
$user->location_id = $item['location_id'];
} else if ($location) {
$user->location_id = e($location->id);
}

View file

@ -184,8 +184,9 @@ class LocationsController extends Controller
$location->state = Input::get('state');
$location->country = Input::get('country');
$location->zip = Input::get('zip');
$location->ldap_ou = Input::get('ldap_ou');
// Was the asset created?
// Was the location updated?
if ($location->save()) {
// Redirect to the saved location page
return redirect()->route("locations.index")->with('success', trans('admin/locations/message.update.success'));

View file

@ -1049,8 +1049,38 @@ class UsersController extends Controller
$summary = array();
$ldap_ou_locations = Location::whereNotNull('ldap_ou')->get();
$results = Ldap::findLdapUsers();
// Inject location information fields
for ($i = 0; $i < $results["count"]; $i++) {
$results[$i]["ldap_location_override"] = false;
$results[$i]["location_id"] = 0;
}
// Grab subsets based on location-specific DNs, and overwrite location for these users.
foreach ($ldap_ou_locations as $ldap_loc) {
$location_users = Ldap::findLdapUsers($ldap_loc->ldap_ou);
$usernames = array();
for ($i = 0; $i < $location_users["count"]; $i++) {
$location_users[$i]["ldap_location_override"] = true;
$location_users[$i]["location_id"] = $ldap_loc->id;
$usernames[] = $location_users[$i][$ldap_result_username][0];
}
// Delete located users from the general group.
foreach ($results as $key => $generic_entry) {
if (in_array($generic_entry[$ldap_result_username][0], $location_users)) {
unset($results[$key]);
}
}
$global_count = $results['count'];
$results = array_merge($location_users, $results);
$results['count'] = $global_count;
}
$tmp_pass = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 20);
$pass = bcrypt($tmp_pass);
@ -1063,6 +1093,8 @@ class UsersController extends Controller
$item["lastname"] = isset($results[$i][$ldap_result_last_name][0]) ? $results[$i][$ldap_result_last_name][0] : "";
$item["firstname"] = isset($results[$i][$ldap_result_first_name][0]) ? $results[$i][$ldap_result_first_name][0] : "";
$item["email"] = isset($results[$i][$ldap_result_email][0]) ? $results[$i][$ldap_result_email][0] : "" ;
$item["ldap_location_override"] = isset($results[$i]["ldap_location_override"]) ? $results[$i]["ldap_location_override"]:"";
$item["location_id"] = isset($results[$i]["location_id"]) ? $results[$i]["location_id"]:"";
// User exists
$item["createorupdate"] = 'updated';
@ -1079,7 +1111,9 @@ class UsersController extends Controller
$user->email = e($item["email"]);
$user->employee_num = e($item["employee_number"]);
$user->activated = 1;
if ($request->input('location_id')!='') {
if ($item['ldap_location_override'] == true) {
$user->location_id = $item['location_id'];
} else if ($request->input('location_id')!='') {
$user->location_id = e($request->input('location_id'));
}
$user->notes = 'Imported from LDAP';

View file

@ -232,18 +232,21 @@ class Ldap extends Model
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @param $ldapatttibutes
* @param $base_dn
* @return array|bool
*/
static function findLdapUsers()
static function findLdapUsers($base_dn = null)
{
$ldapconn = Ldap::connectToLdap();
$ldap_bind = Ldap::bindAdminToLdap($ldapconn);
$base_dn = Setting::getSettings()->ldap_basedn;
// Default to global base DN if nothing else is provided.
if (is_null($base_dn)) {
$base_dn = Setting::getSettings()->ldap_basedn;
}
$filter = Setting::getSettings()->ldap_filter;
// Set up LDAP pagination for very large databases
// @author Richard Hofman
$page_size = 500;
$cookie = '';
$result_set = array();

View file

@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateLocationsLdapQueryField extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('locations', function ($table) {
$table->string('ldap_ou')->nullable()->default(null);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('locations', function ($table) {
$table->string('ldap_ou')->nullable()->default(null);
});
}
}

View file

@ -17,4 +17,5 @@ return array(
'locations' => 'Locations',
'parent' => 'Parent',
'currency' => 'Location Currency',
'ldap_ou' => 'LDAP Search OU',
);

View file

@ -33,6 +33,20 @@
</div>
@include ('partials.forms.edit.address')
<!-- LDAP Search OU -->
@if ($snipeSettings->ldap_enabled == 1)
<div class="form-group {{ $errors->has('currency') ? ' has-error' : '' }}">
<label for="ldap_ou" class="col-md-3 control-label">
{{ trans('admin/locations/table.ldap_ou') }}
</label>
<div class="col-md-7{{ (\App\Helpers\Helper::checkIfRequired($item, 'currency')) ? ' required' : '' }}">
{{ Form::text('ldap_ou', Input::old('ldap_ou', $item->ldap_ou), array('class' => 'form-control')) }}
{!! $errors->first('ldap_ou', '<span class="alert-msg">:message</span>') !!}
</div>
</div>
@endif
@stop
@if (!$item->id)