From 31933a56fae554becbc36355de17620249296c2e Mon Sep 17 00:00:00 2001 From: Brady Wetherington Date: Wed, 7 Jul 2021 15:24:23 -0700 Subject: [PATCH 01/46] Trying to get the login screen working --- app/Http/Livewire/LoginForm.php | 13 ++++++++----- resources/views/livewire/login-form.blade.php | 4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/app/Http/Livewire/LoginForm.php b/app/Http/Livewire/LoginForm.php index 7d10cb78ae..f4fe02f28f 100644 --- a/app/Http/Livewire/LoginForm.php +++ b/app/Http/Livewire/LoginForm.php @@ -38,11 +38,14 @@ class LoginForm extends Component $this->can_submit = false; } - $this->validateOnly($fields); - - $this->can_submit = true; - + $whatever = $this->validateOnly($fields); + //\Log::info(print_r($whatever,true)); + $errors = $this->getErrorBag(); + + $this->can_submit = $this->username !== "" && $this->password !== "" && !$errors->has('username') && !$errors->has('password') ; // wait, what? + + \Log::info("Oy - can we submit yet?!".$this->can_submit); } /** @@ -58,7 +61,7 @@ class LoginForm extends Component public function submitForm() { - $this->can_submit = true; + //$this->can_submit = true; if (auth()->attempt($this->validate())) { return redirect()->intended('/'); diff --git a/resources/views/livewire/login-form.blade.php b/resources/views/livewire/login-form.blade.php index d7cad82505..6561adc8e1 100644 --- a/resources/views/livewire/login-form.blade.php +++ b/resources/views/livewire/login-form.blade.php @@ -41,7 +41,7 @@ {{ trans('admin/users/table.username') }} - + @error('username') {{ $message }} @@ -53,7 +53,7 @@ {{ trans('admin/users/table.password') }} - + @error('password') {{ $message }} From 4dda28de9ec2d13df7ab67e9395bdaec79dfa504 Mon Sep 17 00:00:00 2001 From: Brady Wetherington Date: Tue, 27 Jul 2021 20:09:58 -0700 Subject: [PATCH 02/46] WIP: cleaning up LDAP --- app/Console/Commands/LdapSyncNg.php | 398 ------------ .../Controllers/Api/SettingsController.php | 1 - .../Users/LDAPImportController.php | 23 +- app/Providers/LdapServiceProvider.php | 39 -- app/Services/LdapAd.php | 572 ------------------ app/Services/LdapAdConfiguration.php | 311 ---------- composer.json | 1 - composer.lock | 121 +--- config/app.php | 1 - 9 files changed, 3 insertions(+), 1464 deletions(-) delete mode 100644 app/Console/Commands/LdapSyncNg.php delete mode 100644 app/Providers/LdapServiceProvider.php delete mode 100644 app/Services/LdapAd.php delete mode 100644 app/Services/LdapAdConfiguration.php diff --git a/app/Console/Commands/LdapSyncNg.php b/app/Console/Commands/LdapSyncNg.php deleted file mode 100644 index b271c6c10c..0000000000 --- a/app/Console/Commands/LdapSyncNg.php +++ /dev/null @@ -1,398 +0,0 @@ - - * - * @since 5.0.0 - */ -class LdapSyncNg extends Command -{ - /** - * The name and signature of the console command. - * - * @var string - */ - protected $signature = 'snipeit:ldap-sync-ng - {--location= : A location name } - {--location_id= : A location id} - {--base_dn= : A diffrent base DN to use } - {--summary : Print summary } - {--json_summary : Print summary in json format } - {--dryrun : Run the sync process but don\'t update the database}'; - - /** - * The console command description. - * - * @var string - */ - protected $description = 'Command line LDAP/AD sync'; - - /** - * An LdapAd instance. - * - * @var \App\Models\LdapAd - */ - private $ldap; - - /** - * LDAP settings collection. - * - * @var \Illuminate\Support\Collection - */ - private $settings = null; - - /** - * A default location collection. - * - * @var \Illuminate\Support\Collection - */ - private $defaultLocation = null; - - /** - * Mapped locations collection. - * - * @var \Illuminate\Support\Collection - */ - private $mappedLocations = null; - - /** - * The summary collection. - * - * @var \Illuminate\Support\Collection - */ - private $summary; - - /** - * Is dry-run? - * - * @var bool - */ - private $dryrun = false; - - /** - * Show users to be imported. - * - * @var array - */ - private $userlist = []; - - /** - * Create a new command instance. - */ - public function __construct(LdapAd $ldap) - { - parent::__construct(); - $this->ldap = $ldap; - $this->settings = $this->ldap->ldapSettings; - $this->summary = collect(); - } - - /** - * Execute the console command. - * - * @return mixed - */ - public function handle() - { - $dispatcher = \Adldap\Adldap::getEventDispatcher(); - - // Listen for all model events. - $dispatcher->listen('Adldap\Models\Events\*', function ($eventName, array $data) { - echo $eventName; // Returns 'Adldap\Models\Events\Updating' - var_dump($data); // Returns [0] => (object) Adldap\Models\Events\Updating; - \Log::debug('Event: '.$eventName.' data - '.print_r($data, true)); - }); - $dispatcher->listen('Adldap\Auth\Events\*', function ($eventName, array $data) { - echo $eventName; // Returns 'Adldap\Models\Events\Updating' - var_dump($data); // Returns [0] => (object) Adldap\Models\Events\Updating; - \Log::debug('Event: '.$eventName.' data - '.print_r($data, true)); - }); - - ini_set('max_execution_time', env('LDAP_TIME_LIM', '600')); //600 seconds = 10 minutes - ini_set('memory_limit', '500M'); - $old_error_reporting = error_reporting(); // grab old error_reporting .ini setting, for later re-enablement - error_reporting($old_error_reporting & ~E_DEPRECATED); // disable deprecation warnings, for LDAP in PHP 7.4 (and greater) - - if ($this->option('dryrun')) { - $this->dryrun = true; - } - $this->checkIfLdapIsEnabled(); - $this->checkLdapConnection(); - $this->setBaseDn(); - $this->getUserDefaultLocation(); - /* - * Use the default location if set, this is needed for the LDAP users sync page - */ - if (! $this->option('base_dn') && null == $this->defaultLocation) { - $this->getMappedLocations(); - } - $this->processLdapUsers(); - // Print table of users - if ($this->dryrun) { - $this->info('The following users will be synced!'); - $headers = ['First Name', 'Last Name', 'Username', 'Email', 'Employee #', 'Location Id', 'Status']; - $this->table($headers, $this->summary->toArray()); - } - - error_reporting($old_error_reporting); // re-enable deprecation warnings. - - return $this->getSummary(); - } - - /** - * Generate the LDAP sync summary. - * - * @author Wes Hulette - * - * @since 5.0.0 - * - * @return string - */ - private function getSummary(): string - { - if ($this->option('summary') && null === $this->dryrun) { - $this->summary->each(function ($item) { - $this->info('USER: '.$item['note']); - - if ('ERROR' === $item['status']) { - $this->error('ERROR: '.$item['note']); - } - }); - } elseif ($this->option('json_summary')) { - $json_summary = [ - 'error' => false, - 'error_message' => '', - 'summary' => $this->summary->toArray(), - ]; - $this->info(json_encode($json_summary)); - } - - return ''; - } - - /** - * Create a new user or update an existing user. - * - * @author Wes Hulette - * - * @since 5.0.0 - * - * @param \Adldap\Models\User $snipeUser - */ - private function updateCreateUser(AdldapUser $snipeUser): void - { - $user = $this->ldap->processUser($snipeUser, $this->defaultLocation, $this->mappedLocations); - $summary = [ - 'firstname' => $user->first_name, - 'lastname' => $user->last_name, - 'username' => $user->username, - 'employee_number' => $user->employee_num, - 'email' => $user->email, - 'location_id' => $user->location_id, - ]; - // Only update the database if is not a dry run - if (! $this->dryrun) { - if ($user->isDirty()) { //if nothing on the user changed, don't bother trying to save anything nor put anything in the summary - if ($user->save()) { - $summary['note'] = ($user->wasRecentlyCreated ? 'CREATED' : 'UPDATED'); - $summary['status'] = 'SUCCESS'; - } else { - $errors = ''; - foreach ($user->getErrors()->getMessages() as $error) { - $errors .= implode(', ', $error); - } - $summary['note'] = $snipeUser->getDN().' was not imported. REASON: '.$errors; - $summary['status'] = 'ERROR'; - } - } else { - $summary = null; - } - } - - // $summary['note'] = ($user->getOriginal('username') ? 'UPDATED' : 'CREATED'); // this seems, kinda, like, superfluous, relative to the $summary['note'] thing above, yeah? - if ($summary) { //if the $user wasn't dirty, $summary was set to null so that we will skip the following push() - $this->summary->push($summary); - } - } - - /** - * Process the users to update / create. - * - * @author Wes Hulette - * - * @since 5.0.0 - */ - private function processLdapUsers(): void - { - try { - \Log::debug('CAL:LING GET LDAP SUSERS'); - $ldapUsers = $this->ldap->getLdapUsers(); - \Log::debug('END CALLING GET LDAP USERS'); - } catch (Exception $e) { - $this->outputError($e); - exit($e->getMessage()); - } - - if (0 == $ldapUsers->count()) { - $msg = 'ERROR: No users found!'; - Log::error($msg); - if ($this->dryrun) { - $this->error($msg); - } - exit($msg); - } - - // Process each individual users - foreach ($ldapUsers->getResults() as $user) { // AdLdap2's paginate() method is weird, it gets *everything* and ->getResults() returns *everything* - $this->updateCreateUser($user); - } - } - - /** - * Get the mapped locations if a base_dn is provided. - * - * @author Wes Hulette - * - * @since 5.0.0 - */ - private function getMappedLocations() - { - $ldapOuLocation = Location::where('ldap_ou', '!=', '')->select(['id', 'ldap_ou'])->get(); - $locations = $ldapOuLocation->sortBy(function ($ou, $key) { - return strlen($ou->ldap_ou); - }); - if ($locations->count() > 0) { - $msg = 'Some locations have special OUs set. Locations will be automatically set for users in those OUs.'; - LOG::debug($msg); - if ($this->dryrun) { - $this->info($msg); - } - - $this->mappedLocations = $locations->pluck('ldap_ou', 'id'); // TODO: this seems ok-ish, but the key-> value is going location_id -> OU name, and the primary action here is the opposite of that - going from OU's to location ID's. - } - } - - /** - * Set the base dn if supplied. - * - * @author Wes Hulette - * - * @since 5.0.0 - */ - private function setBaseDn(): void - { - if ($this->option('base_dn')) { - $this->ldap->baseDn = $this->option('base_dn'); - $msg = sprintf('Importing users from specified base DN: "%s"', $this->ldap->baseDn); - LOG::debug($msg); - if ($this->dryrun) { - $this->info($msg); - } - } - } - - /** - * Get a default location id for imported users. - * - * @author Wes Hulette - * - * @since 5.0.0 - */ - private function getUserDefaultLocation(): void - { - $location = $this->option('location_id') ?? $this->option('location'); - if ($location) { - $userLocation = Location::where('name', '=', $location) - ->orWhere('id', '=', intval($location)) - ->select(['name', 'id']) - ->first(); - if ($userLocation) { - $msg = 'Importing users with default location: '.$userLocation->name.' ('.$userLocation->id.')'; - LOG::debug($msg); - - if ($this->dryrun) { - $this->info($msg); - } - - $this->defaultLocation = collect([ - $userLocation->id => $userLocation->name, - ]); - } else { - $msg = 'The supplied location is invalid!'; - LOG::error($msg); - if ($this->dryrun) { - $this->error($msg); - } - exit(0); - } - } - } - - /** - * Check if LDAP intergration is enabled. - * - * @author Wes Hulette - * - * @since 5.0.0 - */ - private function checkIfLdapIsEnabled(): void - { - if (false === $this->settings['ldap_enabled']) { - $msg = 'LDAP intergration is not enabled. Exiting sync process.'; - $this->info($msg); - Log::info($msg); - exit(0); - } - } - - /** - * Check to make sure we can access the server. - * - * @author Wes Hulette - * - * @since 5.0.0 - */ - private function checkLdapConnection(): void - { - try { - $this->ldap->testLdapAdUserConnection(); - $this->ldap->testLdapAdBindConnection(); - } catch (Exception $e) { - $this->outputError($e); - exit(0); - } - } - - /** - * Output the json summary to the screen if enabled. - * - * @param Exception $error - */ - private function outputError($error): void - { - if ($this->option('json_summary')) { - $json_summary = [ - 'error' => true, - 'error_message' => $error->getMessage(), - 'summary' => [], - ]; - $this->info(json_encode($json_summary)); - } - $this->error($error->getMessage()); - LOG::error($error); - } -} diff --git a/app/Http/Controllers/Api/SettingsController.php b/app/Http/Controllers/Api/SettingsController.php index 852530c207..59236731e4 100644 --- a/app/Http/Controllers/Api/SettingsController.php +++ b/app/Http/Controllers/Api/SettingsController.php @@ -7,7 +7,6 @@ use App\Http\Transformers\LoginAttemptsTransformer; use App\Models\Ldap; use App\Models\Setting; use App\Notifications\MailTest; -use App\Services\LdapAd; use GuzzleHttp\Client; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; diff --git a/app/Http/Controllers/Users/LDAPImportController.php b/app/Http/Controllers/Users/LDAPImportController.php index a204581eb6..88a6b207df 100644 --- a/app/Http/Controllers/Users/LDAPImportController.php +++ b/app/Http/Controllers/Users/LDAPImportController.php @@ -4,32 +4,12 @@ namespace App\Http\Controllers\Users; use App\Http\Controllers\Controller; use App\Models\User; -use App\Services\LdapAd; use Illuminate\Http\Request; use Illuminate\Support\Facades\Artisan; // Note that this is awful close to 'Users' the namespace above; be careful class LDAPImportController extends Controller { - /** - * An Ldap instance. - * - * @var LdapAd - */ - protected $ldap; - - /** - * __construct. - * - * @param LdapAd $ldap - */ - public function __construct(LdapAd $ldap) - { - parent::__construct(); - $this->ldap = $ldap; - $this->ldap->init(); - } - - /** + /** * Return view for LDAP import. * * @author Aladin Alaily @@ -43,6 +23,7 @@ class LDAPImportController extends Controller */ public function create() { + // I guess this prolly oughtta... I dunno. Do something? $this->authorize('update', User::class); try { //$this->ldap->connect(); I don't think this actually exists in LdapAd.php, and we don't really 'persist' LDAP connections anyways...right? diff --git a/app/Providers/LdapServiceProvider.php b/app/Providers/LdapServiceProvider.php deleted file mode 100644 index 58f93096d3..0000000000 --- a/app/Providers/LdapServiceProvider.php +++ /dev/null @@ -1,39 +0,0 @@ -app->singleton(LdapAd::class, LdapAd::class); - } - - /** - * Get the services provided by the provider. - * - * @return array - */ - public function provides() - { - return [LdapAd::class]; - } -} diff --git a/app/Services/LdapAd.php b/app/Services/LdapAd.php deleted file mode 100644 index 186a2c7a9d..0000000000 --- a/app/Services/LdapAd.php +++ /dev/null @@ -1,572 +0,0 @@ - - * - * @since 5.0.0 - */ -class LdapAd extends LdapAdConfiguration -{ - /* The following is _probably_ the correct logic, but we can't use it because - some users may have been dependent upon the previous behavior, and this - could cause additional access to be available to users they don't want - to allow to log in. - $useraccountcontrol = $results[$i]['useraccountcontrol'][0]; - if( - // based on MS docs at: https://support.microsoft.com/en-us/help/305144/how-to-use-useraccountcontrol-to-manipulate-user-account-properties - ($useraccountcontrol & 0x200) && // is a NORMAL_ACCOUNT - !($useraccountcontrol & 0x02) && // *and* _not_ ACCOUNTDISABLE - !($useraccountcontrol & 0x10) // *and* _not_ LOCKOUT - ) { - $user->activated = 1; - } else { - $user->activated = 0; - } */ - const AD_USER_ACCOUNT_CONTROL_FLAGS = [ - '512', // 0x200 NORMAL_ACCOUNT - '544', // 0x220 NORMAL_ACCOUNT, PASSWD_NOTREQD - '66048', // 0x10200 NORMAL_ACCOUNT, DONT_EXPIRE_PASSWORD - '66080', // 0x10220 NORMAL_ACCOUNT, PASSWD_NOTREQD, DONT_EXPIRE_PASSWORD - '262656', // 0x40200 NORMAL_ACCOUNT, SMARTCARD_REQUIRED - '262688', // 0x40220 NORMAL_ACCOUNT, PASSWD_NOTREQD, SMARTCARD_REQUIRED - '328192', // 0x50200 NORMAL_ACCOUNT, SMARTCARD_REQUIRED, DONT_EXPIRE_PASSWORD - '328224', // 0x50220 NORMAL_ACCOUNT, PASSWD_NOT_REQD, SMARTCARD_REQUIRED, DONT_EXPIRE_PASSWORD - '4260352', // 0x410200 NORMAL_ACCOUNT, DONT_EXPIRE_PASSWORD, DONT_REQ_PREAUTH - '1049088', // 0x100200 NORMAL_ACCOUNT, NOT_DELEGATED - '1114624', // 0x110200 NORMAL_ACCOUNT, NOT_DELEGATED, DONT_EXPIRE_PASSWORD - ]; - - /** - * The LDAP results per page. - */ - const PAGE_SIZE = 500; - - /** - * A base dn. - * - * @var string - */ - public $baseDn = null; - - /** - * Adldap instance. - * - * @var \Adldap\Adldap - */ - protected $ldap; - - /** - * Initialize LDAP from user settings - * - * @since 5.0.0 - * - * @return void - */ - public function init() - { - // Already initialized - if ($this->ldap) { - return true; - } - - parent::init(); - if ($this->isLdapEnabled()) { - if ($this->ldapSettings['is_ad'] == 0) { //only for NON-AD setups! - $this->ldapConfig['account_prefix'] = $this->ldapSettings['ldap_auth_filter_query']; - $this->ldapConfig['account_suffix'] = ','.$this->ldapConfig['base_dn']; - } /* - To the point mentioned in ldapLogin(), we might want to add an 'else' clause here that - sets up an 'account_suffix' of '@'.$this->ldapSettings['ad_domain'] *IF* the user has - $this->ldapSettings['ad_append_domain'] enabled. - That code in ldapLogin gets simplified, in exchange for putting all the weirdness here only. - */ - $this->ldap = new Adldap(); - $this->ldap->addProvider($this->ldapConfig); - - return true; - } - - return false; - } - - public function __construct() - { - $this->init(); - } - - /** - * Create a user if they successfully login to the LDAP server. - * - * @author Wes Hulette - * - * @since 5.0.0 - * - * @param string $username - * @param string $password - * - * @return \App\Models\User - * - * @throws Exception - */ - public function ldapLogin(string $username, string $password): User - { - if ($this->ldapSettings['ad_append_domain']) { //if you're using 'userprincipalname', don't check the ad_append_domain checkbox - $login_username = $username.'@'.$this->ldapSettings['ad_domain']; // I feel like could can be solved with the 'suffix' feature? Then this would be easier. - } else { - $login_username = $username; - } - - if ($this->ldapConfig['username'] && $this->ldapConfig['password']) { - $bind_as_user = false; - } else { - $bind_as_user = true; - } - - if (($this->ldap) && ($this->ldap->auth()->attempt($login_username, $password, $bind_as_user) === false)) { - throw new Exception('Unable to validate user credentials!'); - } - - // Should we sync the logged in user - Log::debug('Attempting to find user in LDAP directory'); - $record = $this->ldap->search()->findBy($this->ldapSettings['ldap_username_field'], $username); - - if ($record) { - if ($this->isLdapSync($record)) { - $this->syncUserLdapLogin($record, $password); - } - } else { - throw new Exception('Unable to find user in LDAP directory!'); - } - - $user = User::where('username', $username) - ->whereNull('deleted_at')->where('ldap_import', '=', 1) - ->where('activated', '=', '1')->first(); - /* Above, I could've just done ->firstOrFail() which would've been cleaner, but it would've been miserable to - troubleshoot if it ever came up (giving a really generic and untraceable error message) - */ - if (! $user) { - throw new Exception("User is either deleted, not activated (can't log in), not from LDAP, or can't be found in database"); - } - - return $user; - } - - /** - * Set the user information based on the LDAP settings. - * - * @author Wes Hulette - * - * @since 5.0.0 - * - * @param \Adldap\Models\User $user - * @param null|Collection $defaultLocation - * @param null|Collection $mappedLocations - * - * @return null|\App\Models\User - */ - public function processUser(AdldapUser $user, ?Collection $defaultLocation = null, ?Collection $mappedLocations = null): ?User - { - // Only sync active users <- I think this actually means 'existing', not 'activated/deactivated' - if (! $user) { - return null; - } - $snipeUser = []; - $snipeUser['username'] = $user->{$this->ldapSettings['ldap_username_field']}[0] ?? ''; - $snipeUser['employee_number'] = $user->{$this->ldapSettings['ldap_emp_num']}[0] ?? ''; - $snipeUser['lastname'] = $user->{$this->ldapSettings['ldap_lname_field']}[0] ?? ''; - $snipeUser['firstname'] = $user->{$this->ldapSettings['ldap_fname_field']}[0] ?? ''; - $snipeUser['email'] = $user->{$this->ldapSettings['ldap_email']}[0] ?? ''; - $snipeUser['title'] = $user->getTitle() ?? ''; - $snipeUser['telephonenumber'] = $user->getTelephoneNumber() ?? ''; - - /* - * $locationId being 'null' means we have no per-OU location information, - * but instead of explicitly setting it to null - which would override any admin-generated - * location assignments - we just don't set it at all. For a brand new User, the 'default null' - * on the column will cover us. For an already existing user, this will not override any - * locations that were explicitly chosen by the administrators. - * - * When syncing with a particular 'default location' in mind, those should still be respected - * and it *will* override the administrators previous choices. I think this is a fair compromise. - */ - $locationId = $this->getLocationId($user, $defaultLocation, $mappedLocations); - if ($locationId !== null) { - $snipeUser['location_id'] = $locationId; - } - - $activeStatus = $this->getActiveStatus($user); - if ($activeStatus !== null) { - $snipeUser['activated'] = $activeStatus; - } - - return $this->setUserModel($snipeUser); - } - - /** - * Set the User model information. - * - * @author Wes Hulette - * - * @since 5.0.0 - * - * @param array $userInfo The user info to save to the database - * - * @return \App\Models\User - */ - public function setUserModel(array $userInfo): User - { - // If the username exists, return the user object, otherwise create a new user object - $user = User::firstOrNew([ - 'username' => $userInfo['username'], - ]); - $user->username = $user->username ?? trim($userInfo['username']); - $user->password = $user->password ?? Helper::generateEncyrptedPassword(); - $user->first_name = trim($userInfo['firstname']); - $user->last_name = trim($userInfo['lastname']); - $user->email = trim($userInfo['email']); - $user->employee_num = trim($userInfo['employee_number']); - $user->jobtitle = trim($userInfo['title']); - $user->phone = trim($userInfo['telephonenumber']); - if (array_key_exists('activated', $userInfo)) { - $user->activated = $userInfo['activated']; - } elseif (! $user->exists) { // no 'activated' flag was set or unset, *AND* this user is new - activate by default. - $user->activated = 1; - } - if (array_key_exists('location_id', $userInfo)) { - $user->location_id = $userInfo['location_id']; - } - - // this is a new user - if (! isset($user->id)) { - $user->notes = 'Imported from LDAP'; - } - - $user->ldap_import = 1; - - return $user; - } - - /** - * Sync a user who has logged in by LDAP. - * - * @author Wes Hulette - * - * @since 5.0.0 - * - * @param \Adldap\Models\User $record - * @param string $password - * - * @throws Exception - */ - private function syncUserLdapLogin(AdldapUser $record, string $password): void - { - $user = $this->processUser($record); - - if (is_null($user->last_login)) { - $user->notes = 'Imported on first login from LDAP2'; - } - - if ($this->ldapSettings['ldap_pw_sync']) { - Log::debug('Syncing users password with LDAP directory.'); - $user->password = bcrypt($password); - } - - if (! $user->save()) { - Log::debug('Could not save user. '.$user->getErrors()); - throw new Exception('Could not save user: '.$user->getErrors()); - } - } - - /** - * Check to see if we should sync the user with the LDAP directory. - * - * @author Wes Hulette - * - * @since 5.0.0 - * - * @param \Adldap\Models\User $user - * - * @return bool - */ - private function isLdapSync(AdldapUser $user): bool - { - if (! $this->ldapSettings['ldap_active_flag']) { - return true; // always sync if you didn't define an 'active' flag - } - - if ($user->{$this->ldapSettings['ldap_active_flag']} && // if your LDAP user has the aforementioned flag as an attribute *AND* - count($user->{$this->ldapSettings['ldap_active_flag']}) == 1 && // if that attribute has exactly one value *AND* - strtolower($user->{$this->ldapSettings['ldap_active_flag']}[0]) == 'false') { // that value is the string 'false' (regardless of case), - return false; // then your user is *INACTIVE* - return false - } - // otherwise, return true - return true; - } - - /** - * Set the active status of the user. - * Returns 0 or 1 if the user is deactivated or activated - * or returns null if we just don't know - * - * @author Wes Hulette - * - * @since 5.0.0 - * - * @param \Adldap\Models\User $user - * - * @return int (or null) - */ - private function getActiveStatus(AdldapUser $user): ?int - { - /* - * Check to see if we are connected to an AD server - * if so, check the Active Directory User Account Control Flags - * If the admin has set their own 'active flag' - respect that instead - * (this may work to allow AD users to ignore the built-in UAC stuff that AD does) - */ - if ($user->hasAttribute($user->getSchema()->userAccountControl()) && ! $this->ldapSettings['ldap_active_flag']) { - \Log::debug('This is AD - userAccountControl is'.$user->getSchema()->userAccountControl()); - $activeStatus = (in_array($user->getUserAccountControl(), self::AD_USER_ACCOUNT_CONTROL_FLAGS)) ? 1 : 0; - } else { - - //\Log::debug('This looks like LDAP (or an AD where the UAC is disabled)'); - // If there is no activated flag, then we can't make any determination about activated/deactivated - if (false == $this->ldapSettings['ldap_active_flag']) { - \Log::debug('ldap_active_flag is false - no ldap_active_flag is set'); - - return null; - } - - // If there *is* an activated flag, then respect it *only* if it is actually present. If it's not there, ignore it. - if (! $user->hasAttribute($this->ldapSettings['ldap_active_flag'])) { - return null; // 'active' flag is defined, but does not exist on returned user record. So we don't know if they're active or not. - } - - // if $user has the flag *AND* that flag has exactly one value - - if ($user->{$this->ldapSettings['ldap_active_flag']} && count($user->{$this->ldapSettings['ldap_active_flag']}) == 1) { - $active_flag_value = $user->{$this->ldapSettings['ldap_active_flag']}[0]; - - // if the value of that flag is case-insensitively the string 'false' or boolean false - if (strcasecmp($active_flag_value, 'false') == 0 || $active_flag_value === false) { - return 0; // then make them INACTIVE - } else { - return 1; // otherwise active - } - } - - return 1; // fail 'open' (active) if we have the attribute and it's multivalued or empty; that's weird - } - - return $activeStatus; - } - - /** - * Get a default selected location, or a OU mapped location if available. - * - * @author Wes Hulette - * - * @since 5.0.0 - * - * @param \Adldap\Models\User $user - * @param Collection|null $defaultLocation - * @param Collection|null $mappedLocations - * - * @return null|int - */ - private function getLocationId(AdldapUser $user, ?Collection $defaultLocation, ?Collection $mappedLocations): ?int - { - $locationId = null; - // Set the users default locations, if set - if ($defaultLocation) { - $locationId = $defaultLocation->keys()->first(); - } - - // Check to see if the user is in a mapped location - if ($mappedLocations) { - $location = $mappedLocations->filter(function ($value, $key) use ($user) { - //if ($user->inOu($value)) { // <----- *THIS* seems not to be working, and it seems more 'intelligent' - but it's literally just a strpos() call, and it doesn't work quite right against plain strings - $user_ou = substr($user->getDn(), -strlen($value)); // get the LAST chars of the user's DN, the count of those chars being the length of the thing we're checking against - if (strcasecmp($user_ou, $value) === 0) { // case *IN*sensitive comparision - some people say OU=blah, some say ou=blah. returns 0 when strings are identical (which is a little odd, yeah) - return $key; // WARNING: we are doing a 'filter' - not a regular for-loop. So the answer(s) get "return"ed into the $location array - } - }); - - if ($location->count() > 0) { - $locationId = $location->keys()->first(); // from the returned $location array from the ->filter() method above, we return the first match - there should be only one - } - } - - return $locationId; - } - - /** - * Get the base dn for the query. - * - * @author Wes Hulette - * - * @since 5.0.0 - * - * @return string - */ - private function getBaseDn(): string - { - if (! is_null($this->baseDn)) { - return $this->baseDn; - } - - return $this->ldapSettings['ldap_basedn']; - } - - /** - * Format the ldap filter if needed. - * - * @author Wes Hulette - * - * @since 5.0.0 - * - * @return null|string - */ - private function getFilter(): ?string - { - $filter = $this->ldapSettings['ldap_filter']; - if (! $filter) { - return null; - } - // Add surrounding parentheses as needed - $paren = mb_substr($filter, 0, 1, 'utf-8'); - if ('(' !== $paren) { - return '('.$filter.')'; - } - - return $filter; - } - - /** - * Get the selected fields to return - * This should help with memory on large result sets as we are not returning all fields. - * - * @author Wes Hulette - * - * @since 5.0.0 - * - * @return array - */ - private function getSelectedFields(): array - { - /** @var Schema $schema */ - $schema = new $this->ldapConfig['schema']; - - return array_values(array_filter([ - $this->ldapSettings['ldap_username_field'], - $this->ldapSettings['ldap_fname_field'], - $this->ldapSettings['ldap_lname_field'], - $this->ldapSettings['ldap_email'], - $this->ldapSettings['ldap_emp_num'], - $this->ldapSettings['ldap_active_flag'], - $schema->memberOf(), - $schema->userAccountControl(), - $schema->title(), - $schema->telephone(), - ])); - } - - /** - * Test the bind user connection. - * - * @author Wes Hulette - * @throws \Exception - * @since 5.0.0 - */ - public function testLdapAdBindConnection(): void - { - try { - $this->ldap->search()->ous()->get()->count(); //it's saying this is null? - } catch (Exception $th) { - Log::error($th->getMessage()); - throw new Exception('Unable to search LDAP directory!'); - } - } - - /** - * Test the user can connect to the LDAP server. - * - * @author Wes Hulette - * @throws \Exception - * @since 5.0.0 - */ - public function testLdapAdUserConnection(): void - { - try { - $this->ldap->connect(); - } catch (\Exception $e) { - Log::debug('LDAP ERROR: '.$e->getMessage()); - throw new Exception($e->getMessage()); - } - } - - /** - * Test the LDAP configuration by returning up to 10 users. - * - * @author Wes Hulette - * - * @since 5.0.0 - * - * @return Collection - */ - public function testUserImportSync(): Collection - { - $testUsers = collect($this->getLdapUsers()->getResults())->chunk(10)->first(); - if ($testUsers) { - return $testUsers->map(function ($item) { - return (object) [ - 'username' => $item->{$this->ldapSettings['ldap_username_field']}[0] ?? null, - 'employee_number' => $item->{$this->ldapSettings['ldap_emp_num']}[0] ?? null, - 'lastname' => $item->{$this->ldapSettings['ldap_lname_field']}[0] ?? null, - 'firstname' => $item->{$this->ldapSettings['ldap_fname_field']}[0] ?? null, - 'email' => $item->{$this->ldapSettings['ldap_email']}[0] ?? null, - ]; - }); - } - - return collect(); - } - - /** - * Query the LDAP server to get the users to process and return a page set. - * - * @author Wes Hulette - * - * @since 5.0.0 - * - * @return \Adldap\Query\Paginator - */ - public function getLdapUsers(): Paginator - { - $search = $this->ldap->search()->users()->in($this->getBaseDn()); //this looks wrong; we should instead have a passable parameter that does this, and use this as a 'sane' default, yeah? - - $filter = $this->getFilter(); - if (! is_null($filter)) { - $search = $search->rawFilter($filter); - } - //I think it might be possible to potentially do our own paging here? - - return $search->select($this->getSelectedFields()) - ->paginate(self::PAGE_SIZE); - } -} diff --git a/app/Services/LdapAdConfiguration.php b/app/Services/LdapAdConfiguration.php deleted file mode 100644 index 25f0fba372..0000000000 --- a/app/Services/LdapAdConfiguration.php +++ /dev/null @@ -1,311 +0,0 @@ - - * - * @since 5.0.0 - */ -class LdapAdConfiguration -{ - const LDAP_PORT = 389; - const CONNECTION_TIMEOUT = 5; - const DEFAULT_LDAP_VERSION = 3; - const LDAP_BOOLEAN_SETTINGS = [ - 'ldap_enabled', - 'ldap_server_cert_ignore', - 'ldap_tls', - 'ldap_tls', - 'ldap_pw_sync', - 'is_ad', - 'ad_append_domain', - ]; - - /** - * Ldap Settings. - * - * @var Collection - */ - public $ldapSettings; - - /** - * LDAP Config. - * - * @var array - */ - public $ldapConfig; - - /** - * Initialize LDAP from user settings - * - * @since 5.0.0 - */ - public function init() - { - - // This try/catch is dumb, but is necessary to run initial migrations, since - // this service provider is booted even during migrations. :( - snipe - try { - $this->ldapSettings = $this->getSnipeItLdapSettings(); - if ($this->isLdapEnabled()) { - $this->setSnipeItConfig(); - } - } catch (\Exception $e) { - \Log::debug($e); - $this->ldapSettings = null; - } - } - - /** - * Merge the default Adlap config with the SnipeIT config. - * - * @author Wes Hulette - * - * @since 5.0.0 - */ - private function setSnipeItConfig() - { - $this->ldapConfig = $this->setLdapConnectionConfiguration(); - $this->certificateCheck(); - } - - /** - * Get the LDAP settings from the Settings model. - * - * @author Wes Hulette - * - * @since 5.0.0 - * - * @return \Illuminate\Support\Collection - */ - private function getSnipeItLdapSettings(): Collection - { - $ldapSettings = collect(); - if (Setting::first()) { // during early migration steps, there may be no settings table entry to start with - $ldapSettings = Setting::getLdapSettings() - ->map(function ($item, $key) { - // Trim the items - if (is_string($item)) { - $item = trim($item); - } - // Get the boolean value of the LDAP setting, makes it easier to work with them - if (in_array($key, self::LDAP_BOOLEAN_SETTINGS)) { - return boolval($item); - } - - // Decrypt the admin password - if ('ldap_pword' === $key && ! empty($item)) { - try { - return decrypt($item); - } catch (Exception $e) { - throw new Exception('Your app key has changed! Could not decrypt LDAP password using your current app key, so LDAP authentication has been disabled. Login with a local account, update the LDAP password and re-enable it in Admin > Settings.'); - } - } - - if ($item && 'ldap_server' === $key) { - return collect(parse_url($item)); - } - - return $item; - }); - } - - return $ldapSettings; - } - - /** - * Set the server certificate environment variable. - * - * @author Wes Hulette - * - * @since 5.0.0 - */ - private function certificateCheck(): void - { - // If we are ignoring the SSL cert we need to setup the environment variable - // before we create the connection - if ($this->ldapSettings['ldap_server_cert_ignore']) { - putenv('LDAPTLS_REQCERT=never'); - } - - // If the user specifies where CA Certs are, make sure to use them - if (env('LDAPTLS_CACERT')) { - putenv('LDAPTLS_CACERT='.env('LDAPTLS_CACERT')); - } - } - - /** - * Set the Adlap2 connection configuration values based on SnipeIT settings. - * - * @author Wes Hulette - * - * @since 5.0.0 - * - * @return array - */ - private function setLdapConnectionConfiguration(): array - { - // Create the configuration array. - $ldap_settings = [ - // Mandatory Configuration Options - 'hosts' => $this->getServerUrlBase(), - 'base_dn' => $this->ldapSettings['ldap_basedn'], - 'username' => $this->ldapSettings['ldap_uname'], - 'password' => $this->ldapSettings['ldap_pword'], - - // Optional Configuration Options - 'schema' => $this->getSchema(), // FIXME - we probably ought not to be using this, right? - 'account_prefix' => '', - 'account_suffix' => '', - 'port' => $this->getPort(), - 'follow_referrals' => false, - 'use_ssl' => $this->isSsl(), - 'use_tls' => $this->ldapSettings['ldap_tls'], - 'version' => $this->ldapSettings['ldap_version'] ?? self::DEFAULT_LDAP_VERSION, - 'timeout' => self::CONNECTION_TIMEOUT, - - // Custom LDAP Options - 'custom_options' => [ - // See: http://php.net/ldap_set_option - // LDAP_OPT_X_TLS_REQUIRE_CERT => LDAP_OPT_X_TLS_HARD, - ], - ]; - - if($this->ldapSettings['ldap_client_tls_cert'] || $this->ldapSettings['ldap_client_tls_key']) { - $ldap_settings['custom_options'] = [ - LDAP_OPT_X_TLS_CERTFILE => Setting::get_client_side_cert_path(), - LDAP_OPT_X_TLS_KEYFILE => Setting::get_client_side_key_path() - ]; - } - return $ldap_settings; - } - - /** - * Get the schema to use for the connection. - * - * @author Wes Hulette - * - * @since 5.0.0 - * - * @return string - */ - private function getSchema(): string //wait, what? This is a little weird, since we have completely separate variables for this; we probably shoulnd't be using any 'schema' at all - { - $schema = \Adldap\Schemas\OpenLDAP::class; - if ($this->ldapSettings['is_ad']) { - $schema = \Adldap\Schemas\ActiveDirectory::class; - } - - return $schema; - } - - /** - * Get the port number from the connection url. - * - * @author Wes Hulette - * - * @since 5.0.0 - * - * @return int - */ - private function getPort(): int - { - $port = $this->getLdapServerData('port'); - if ($port && is_int($port)) { - return $port; - } - - return self::LDAP_PORT; - } - - /** - * Get ldap scheme from url to determin ssl use. - * - * @author Wes Hulette - * - * @since 5.0.0 - * - * @return bool - */ - private function isSsl(): bool - { - $scheme = $this->getLdapServerData('scheme'); - if ($scheme && 'ldaps' === strtolower($scheme)) { - return true; - } - - return false; - } - - /** - * Return the base url to the LDAP server. - * - * @author Wes Hulette - * - * @since 5.0.0 - * - * @return array - */ - private function getServerUrlBase(): array - { - /* if ($this->ldapSettings['is_ad']) { - return collect(explode(',', $this->ldapSettings['ad_domain']))->map(function ($item) { - return trim($item); - })->toArray(); - } */ // <- this was the *original* intent of the PR for AdLdap2, but we've been moving away from having - // two separate fields - one for "ldap_host" and one for "ad_domain" - towards just using "ldap_host" - // ad_domain for us just means "append this domain to your usernames for login, if you click that checkbox" - // that's all, nothing more (I hope). - - $url = $this->getLdapServerData('host'); - - return $url ? [$url] : []; - } - - /** - * Get ldap enabled setting - * - * @author Steffen Buehl - * - * @since 5.0.0 - * - * @return bool - */ - public function isLdapEnabled(): bool - { - return $this->ldapSettings && $this->ldapSettings->get('ldap_enabled'); - } - - /** - * Get parsed ldap server information - * - * @author Steffen Buehl - * - * @since 5.0.0 - * - * @param $key - * @return mixed|null - */ - protected function getLdapServerData($key) - { - if ($this->ldapSettings) { - $ldapServer = $this->ldapSettings->get('ldap_server'); - if ($ldapServer && $ldapServer instanceof Collection) { - return $ldapServer->get($key); - } - } - - return null; - } -} diff --git a/composer.json b/composer.json index e27a0cd1e9..ee500769a2 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,6 @@ "ext-json": "*", "ext-mbstring": "*", "ext-pdo": "*", - "adldap2/adldap2": "^10.2", "alek13/slack": "^2.0", "bacon/bacon-qr-code": "^1.0", "barryvdh/laravel-debugbar": "^3.6", diff --git a/composer.lock b/composer.lock index aa4d99d39b..3dce273326 100644 --- a/composer.lock +++ b/composer.lock @@ -4,73 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "64dee2cbecb92c4250bb11ffe23f2ed0", + "content-hash": "f67d64a4e9f3ea8ce9c340527e498d97", "packages": [ - { - "name": "adldap2/adldap2", - "version": "v10.3.3", - "source": { - "type": "git", - "url": "https://github.com/Adldap2/Adldap2.git", - "reference": "c2a8f72455d3438377d955fc0f4b9ed836b47463" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Adldap2/Adldap2/zipball/c2a8f72455d3438377d955fc0f4b9ed836b47463", - "reference": "c2a8f72455d3438377d955fc0f4b9ed836b47463", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-ldap": "*", - "illuminate/contracts": "~5.0|~6.0|~7.0|~8.0", - "php": ">=7.0", - "psr/log": "~1.0", - "psr/simple-cache": "~1.0", - "tightenco/collect": "~5.0|~6.0|~7.0|~8.0" - }, - "require-dev": { - "mockery/mockery": "~1.0", - "phpunit/phpunit": "~6.0|~7.0|~8.0" - }, - "suggest": { - "ext-fileinfo": "fileinfo is required when retrieving user encoded thumbnails" - }, - "type": "library", - "autoload": { - "psr-4": { - "Adldap\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Steve Bauman", - "email": "steven_bauman@outlook.com", - "role": "Developer" - } - ], - "description": "A PHP LDAP Package for humans.", - "keywords": [ - "active directory", - "ad", - "adLDAP", - "adldap2", - "directory", - "ldap", - "windows" - ], - "support": { - "docs": "https://github.com/Adldap2/Adldap2/blob/master/readme.md", - "email": "steven_bauman@outlook.com", - "issues": "https://github.com/Adldap2/Adldap2/issues", - "source": "https://github.com/Adldap2/Adldap2" - }, - "time": "2021-08-09T15:22:35+00:00" - }, { "name": "alek13/slack", "version": "2.1.1", @@ -10401,60 +10336,6 @@ ], "time": "2021-02-07T13:13:45+00:00" }, - { - "name": "tightenco/collect", - "version": "v8.34.0", - "source": { - "type": "git", - "url": "https://github.com/tighten/collect.git", - "reference": "b069783ab0c547bb894ebcf8e7f6024bb401f9d2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/tighten/collect/zipball/b069783ab0c547bb894ebcf8e7f6024bb401f9d2", - "reference": "b069783ab0c547bb894ebcf8e7f6024bb401f9d2", - "shasum": "" - }, - "require": { - "php": "^7.2|^8.0", - "symfony/var-dumper": "^3.4 || ^4.0 || ^5.0" - }, - "require-dev": { - "mockery/mockery": "^1.0", - "nesbot/carbon": "^2.23.0", - "phpunit/phpunit": "^8.3" - }, - "type": "library", - "autoload": { - "files": [ - "src/Collect/Support/helpers.php", - "src/Collect/Support/alias.php" - ], - "psr-4": { - "Tightenco\\Collect\\": "src/Collect" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" - } - ], - "description": "Collect - Illuminate Collections as a separate package.", - "keywords": [ - "collection", - "laravel" - ], - "support": { - "issues": "https://github.com/tighten/collect/issues", - "source": "https://github.com/tighten/collect/tree/v8.34.0" - }, - "time": "2021-03-29T21:29:00+00:00" - }, { "name": "tightenco/ziggy", "version": "v1.2.0", diff --git a/config/app.php b/config/app.php index e8d1ebae49..ab6d62004a 100755 --- a/config/app.php +++ b/config/app.php @@ -345,7 +345,6 @@ return [ * Custom service provider */ App\Providers\MacroServiceProvider::class, - App\Providers\LdapServiceProvider::class, App\Providers\SamlServiceProvider::class, ], From b784e63aa8bb1150ee4ebc23191e271edcf5b202 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?W=C3=A4chtler=2C=20Yannick?= Date: Tue, 2 Nov 2021 10:13:22 +0100 Subject: [PATCH 03/46] Added localized strings for account --- resources/lang/en/general.php | 11 ++++++++++- resources/views/account/accept-asset.blade.php | 2 +- resources/views/account/accept/create.blade.php | 10 +++++----- resources/views/account/accept/index.blade.php | 5 +++-- resources/views/account/api.blade.php | 17 ++++++++--------- .../views/account/change-password.blade.php | 6 +++--- resources/views/account/profile.blade.php | 2 +- .../views/account/requestable-assets.blade.php | 2 +- resources/views/account/requested.blade.php | 10 +++++----- resources/views/account/view-assets.blade.php | 4 ++-- 10 files changed, 39 insertions(+), 30 deletions(-) diff --git a/resources/lang/en/general.php b/resources/lang/en/general.php index 942947e6c1..bd59be9506 100644 --- a/resources/lang/en/general.php +++ b/resources/lang/en/general.php @@ -6,6 +6,7 @@ 'accessory' => 'Accessory', 'accessory_report' => 'Accessory Report', 'action' => 'Action', + 'actions' => 'Actions', 'activity_report' => 'Activity Report', 'address' => 'Address', 'admin' => 'Admin', @@ -62,6 +63,7 @@ 'updated_at' => 'Updated at', 'currency' => '$', // this is deprecated 'current' => 'Current', + 'current_password' => 'Current Password', 'custom_report' => 'Custom Asset Report', 'dashboard' => 'Dashboard', 'days' => 'days', @@ -104,9 +106,10 @@ 'file_type' => 'File Type', 'file_uploads' => 'File Uploads', 'generate' => 'Generate', - 'github_markdown' => 'This field accepts Github flavored markdown.', + 'github_markdown' => 'This field accepts Github flavored markdown.', 'groups' => 'Groups', 'gravatar_email' => 'Gravatar Email Address', + 'gravatar_url' => 'Change your avatar at Gravatar.com.', 'history' => 'History', 'history_for' => 'History for', 'id' => 'ID', @@ -122,6 +125,7 @@ 'asset_maintenance_report' => 'Asset Maintenance Report', 'asset_maintenances' => 'Asset Maintenances', 'item' => 'Item', + 'item_name' => 'Item Name', 'insufficient_permissions' => 'Insufficient permissions!', 'kits' => 'Predefined Kits', 'language' => 'Language', @@ -151,6 +155,7 @@ 'months' => 'months', 'moreinfo' => 'More Info', 'name' => 'Name', + 'new_password' => 'New Password', 'next' => 'Next', 'next_audit_date' => 'Next Audit Date', 'last_audit' => 'Last Audit', @@ -178,7 +183,10 @@ 'reports' => 'Reports', 'restored' => 'restored', 'restore' => 'Restore', + 'requestable_models' => 'Requestable Models', 'requested' => 'Requested', + 'requested_date' => 'Requested Date', + 'requested_assets' => 'Requested Assets', 'request_canceled' => 'Request Canceled', 'save' => 'Save', 'select' => 'Select', @@ -231,6 +239,7 @@ 'users' => 'Users', 'viewall' => 'View All', 'viewassets' => 'View Assigned Assets', + 'viewassetsfor' => 'View Assets for :name', 'website' => 'Website', 'welcome' => 'Welcome, :name', 'years' => 'years', diff --git a/resources/views/account/accept-asset.blade.php b/resources/views/account/accept-asset.blade.php index cb4956a95f..e9034c7100 100644 --- a/resources/views/account/accept-asset.blade.php +++ b/resources/views/account/accept-asset.blade.php @@ -2,7 +2,7 @@ {{-- Page title --}} @section('title') - {{trans('general.accept', ['asset' => $item->present()->name()])}} + {{ trans('general.accept', ['asset' => $item->present()->name()]) }} @parent @stop diff --git a/resources/views/account/accept/create.blade.php b/resources/views/account/accept/create.blade.php index 816c0cb2bd..defba995b0 100644 --- a/resources/views/account/accept/create.blade.php +++ b/resources/views/account/accept/create.blade.php @@ -2,7 +2,7 @@ {{-- Page title --}} @section('title') - Accept {{ $acceptance->checkoutable->present()->name() }} + {{ trans('general.accept', array('asset' => $acceptance->checkoutable->present()->name())) }} @parent @stop @@ -47,14 +47,14 @@
@@ -69,7 +69,7 @@ @if ($snipeSettings->require_accept_signature=='1')
-

Sign below to indicate that you agree to the terms of service:

+

{{ trans('general.sign_tos') }}

@@ -77,7 +77,7 @@
- +
diff --git a/resources/views/account/accept/index.blade.php b/resources/views/account/accept/index.blade.php index aeab72a299..273feab95a 100755 --- a/resources/views/account/accept/index.blade.php +++ b/resources/views/account/accept/index.blade.php @@ -2,6 +2,7 @@ {{-- Page title --}} @section('title') +//TODO: Debug page as it is not viewable in browser due to crash Accept assets {{ $user->present()->fullName() }} @parent @stop @@ -34,8 +35,8 @@ Accept assets {{ $user->present()->fullName() }} }'> - Name - Actions + {{ trans('general.name')}} + {{ trans('general.actions')}} diff --git a/resources/views/account/api.blade.php b/resources/views/account/api.blade.php index a91eb94cba..d54b1cc9fd 100644 --- a/resources/views/account/api.blade.php +++ b/resources/views/account/api.blade.php @@ -2,7 +2,7 @@ {{-- Page title --}} @section('title') - Personal API Keys + {{ trans('account/api.personal_api_keys') }} @parent @stop @@ -24,18 +24,17 @@
- When generating an API token, be sure to copy it down immediately as they - will not be visible to you again.
+ {{ trans('account/api.api_key_warning') }} +
-

Your API base url is located at:
- {{ url('/api/v1') }}/<endpoint>

+

{{ trans('account/api.api_base_url') }}
+ {{ url('/api/v1') }}{{!! trans('account/api.api_base_url_endpoint') !!}}

-

API tokens are set to expire in: - {{ config('passport.expiration_years') }} years.

+

{{ trans('account/api.api_token_expiration_time') }} + {{ config('passport.expiration_years') }} {{ trans('general.years') }} .

-

Please check the API reference to - find specific API endpoints and additional API documentation.

+

{{!! trans('account/api.api_reference') !!}}

diff --git a/resources/views/account/change-password.blade.php b/resources/views/account/change-password.blade.php index 0a4ef26831..9899a9734e 100755 --- a/resources/views/account/change-password.blade.php +++ b/resources/views/account/change-password.blade.php @@ -20,7 +20,7 @@
-
@@ -32,7 +32,7 @@
- +
{!! $errors->first('password', '') !!} @@ -44,7 +44,7 @@
- +
{!! $errors->first('password_confirmation', '') !!} diff --git a/resources/views/account/profile.blade.php b/resources/views/account/profile.blade.php index 4650340628..7efb62681a 100755 --- a/resources/views/account/profile.blade.php +++ b/resources/views/account/profile.blade.php @@ -97,7 +97,7 @@ {!! $errors->first('gravatar', '') !!}

{{ $user->present()->fullName() }} avatar image - Change your avatar at Gravatar.com. + {{!! trans('general.gravatar_url') !!}}

diff --git a/resources/views/account/requestable-assets.blade.php b/resources/views/account/requestable-assets.blade.php index b0b8a0f4f6..039d0fb3bd 100644 --- a/resources/views/account/requestable-assets.blade.php +++ b/resources/views/account/requestable-assets.blade.php @@ -72,7 +72,7 @@
@if ($models->count() > 0) -

Requestable Models

+

{{ trans('general.requestable_models') }}

- - - + + + - +
ImageItem NameType{{ trans('general.image') }}{{ trans('general.item_name') }}{{ trans('general.type') }} {{ trans('general.qty') }} {{ trans('admin/hardware/table.location') }} {{ trans('admin/hardware/form.expected_checkin') }}Requested Date {{ trans('general.requested_date') }}
diff --git a/resources/views/account/view-assets.blade.php b/resources/views/account/view-assets.blade.php index e50986470b..dfbc19b960 100755 --- a/resources/views/account/view-assets.blade.php +++ b/resources/views/account/view-assets.blade.php @@ -2,7 +2,7 @@ {{-- Page title --}} @section('title') -View Assets for {{ $user->present()->fullName() }} +{{ trans('general.viewassetsfor', array('name' => $user->fullName)) }} @parent @stop @@ -294,7 +294,7 @@ View Assets for {{ $user->present()->fullName() }} @if ($user->id)
-

History

+

{{ trans('general.history') }}

@endif From 433d6fd3e0391e7e76b843c427f447422acc6026 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?W=C3=A4chtler=2C=20Yannick?= Date: Tue, 2 Nov 2021 10:23:15 +0100 Subject: [PATCH 04/46] Added localized strings for admin/companies --- resources/lang/en/admin/companies/general.php | 2 ++ resources/views/companies/index.blade.php | 6 ++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/lang/en/admin/companies/general.php b/resources/lang/en/admin/companies/general.php index 318d188e3b..37781012ba 100644 --- a/resources/lang/en/admin/companies/general.php +++ b/resources/lang/en/admin/companies/general.php @@ -2,4 +2,6 @@ return [ 'select_company' => 'Select Company', + 'about_companies' => 'About Companies', + 'about_companies_description' => ' You can use companies as a simple informative field, or you can use them to restrict asset visibility and availability to users with a specific company by enabling Full Company Support in your Admin Settings.', ]; diff --git a/resources/views/companies/index.blade.php b/resources/views/companies/index.blade.php index 7407f2a084..d7a55367b9 100644 --- a/resources/views/companies/index.blade.php +++ b/resources/views/companies/index.blade.php @@ -44,10 +44,8 @@
-

About Companies

-

- You can use companies as a simple informative field, or you can use them to restrict asset visibility and availability to users with a specific company by enabling Full Company Support in your Admin Settings. -

+

{{ trans('admin/companies/general.about_companies') }}

+

{{ trans('admin/companies/general.about_companies_description') }}

@stop From c11af0e22213a203a74dddbbc8916e595530ed27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?W=C3=A4chtler=2C=20Yannick?= Date: Tue, 2 Nov 2021 10:40:41 +0100 Subject: [PATCH 05/46] Added missing localized strings for account/accept/index.blade.php and view-assets.blade.php --- resources/lang/en/general.php | 4 +++- resources/views/account/accept/index.blade.php | 5 ++--- resources/views/account/view-assets.blade.php | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/resources/lang/en/general.php b/resources/lang/en/general.php index bd59be9506..9b6c4d4dfd 100644 --- a/resources/lang/en/general.php +++ b/resources/lang/en/general.php @@ -20,7 +20,8 @@ 'asset' => 'Asset', 'asset_report' => 'Asset Report', 'asset_tag' => 'Asset Tag', - 'assets_available' => 'assets available', + 'assets_available' => 'Assets available', + 'accept_assets' => 'Accept Assets :name', 'audit' => 'Audit', 'audit_report' => 'Audit Log', 'assets' => 'Assets', @@ -253,6 +254,7 @@ 'accept' => 'Accept :asset', 'i_accept' => 'I accept', 'i_decline' => 'I decline', + 'accept_decline' => 'Accept/Decline', 'sign_tos' => 'Sign below to indicate that you agree to the terms of service:', 'clear_signature' => 'Clear Signature', 'show_help' => 'Show help', diff --git a/resources/views/account/accept/index.blade.php b/resources/views/account/accept/index.blade.php index 273feab95a..17997be6e5 100755 --- a/resources/views/account/accept/index.blade.php +++ b/resources/views/account/accept/index.blade.php @@ -2,8 +2,7 @@ {{-- Page title --}} @section('title') -//TODO: Debug page as it is not viewable in browser due to crash -Accept assets {{ $user->present()->fullName() }} +{{ trans('general.accept_assets', array('name' => $user->present()->fullName())) }} @parent @stop @@ -43,7 +42,7 @@ Accept assets {{ $user->present()->fullName() }} @foreach ($acceptances as $acceptance) {{ ($acceptance->checkoutable) ? $acceptance->checkoutable->present()->name : '' }} - Accept/Decline + {{ trans('general.accept_decline') }} @endforeach diff --git a/resources/views/account/view-assets.blade.php b/resources/views/account/view-assets.blade.php index dfbc19b960..f5dc07eb84 100755 --- a/resources/views/account/view-assets.blade.php +++ b/resources/views/account/view-assets.blade.php @@ -2,7 +2,7 @@ {{-- Page title --}} @section('title') -{{ trans('general.viewassetsfor', array('name' => $user->fullName)) }} +{{ trans('general.viewassetsfor', array('name' => $user->present()->fullName())) }} @parent @stop From a96c53784cc570e0a6a639380e62fb033e008c25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?W=C3=A4chtler=2C=20Yannick?= Date: Tue, 2 Nov 2021 11:27:53 +0100 Subject: [PATCH 06/46] Added localized strings for custom_fields --- .../lang/en/admin/custom_fields/general.php | 13 ++++++++++ resources/lang/en/button.php | 1 + resources/lang/en/general.php | 3 ++- .../views/account/accept/index.blade.php | 2 +- .../views/custom_fields/fields/edit.blade.php | 8 +++--- .../custom_fields/fieldsets/edit.blade.php | 4 +-- .../custom_fields/fieldsets/view.blade.php | 14 +++++----- resources/views/custom_fields/index.blade.php | 26 +++++++++---------- 8 files changed, 43 insertions(+), 28 deletions(-) diff --git a/resources/lang/en/admin/custom_fields/general.php b/resources/lang/en/admin/custom_fields/general.php index 0fb90a5079..8483c67c69 100644 --- a/resources/lang/en/admin/custom_fields/general.php +++ b/resources/lang/en/admin/custom_fields/general.php @@ -2,6 +2,7 @@ return [ 'custom_fields' => 'Custom Fields', + 'manage' => 'Manage', 'field' => 'Field', 'about_fieldsets_title' => 'About Fieldsets', 'about_fieldsets_text' => 'Fieldsets allow you to create groups of custom fields that are frequently re-used for specific asset model types.', @@ -26,7 +27,19 @@ return [ 'used_by_models' => 'Used By Models', 'order' => 'Order', 'create_fieldset' => 'New Fieldset', + 'create_fieldset_title' => 'Create a new fieldset', 'create_field' => 'New Custom Field', + 'create_field_title' => 'Create a new custom field', 'value_encrypted' => 'The value of this field is encrypted in the database. Only admin users will be able to view the decrypted value', 'show_in_email' => 'Include the value of this field in checkout emails sent to the user? Encrypted fields cannot be included in emails.', + 'help_text' => 'Help Text', + 'help_text_description' => 'This is optional text that will appear below the form elements while editing an asset to provide context on the field.', + 'about_custom_fields_title' => 'About Custom Fields', + 'about_custom_fields_text' => 'Custom fields allow you to add arbitrary attributes to assets.', + 'add_field_to_fieldset' => 'Add Field to Fieldset', + 'make_optional' => 'Required - click to make optional', + 'make_required' => 'Optional - click to make required', + 'reorder' => 'Reorder', + 'db_field' => 'DB Field', + 'db_convert_warning' => 'WARNING. This field is in the custom fields table as :db_column but should be :expected .' ]; diff --git a/resources/lang/en/button.php b/resources/lang/en/button.php index 12bda167b3..ac1e6aa429 100644 --- a/resources/lang/en/button.php +++ b/resources/lang/en/button.php @@ -8,6 +8,7 @@ return [ 'delete' => 'Delete', 'edit' => 'Edit', 'restore' => 'Restore', + 'remove' => 'Remove', 'request' => 'Request', 'submit' => 'Submit', 'upload' => 'Upload', diff --git a/resources/lang/en/general.php b/resources/lang/en/general.php index 9b6c4d4dfd..5cf5d88445 100644 --- a/resources/lang/en/general.php +++ b/resources/lang/en/general.php @@ -6,7 +6,6 @@ 'accessory' => 'Accessory', 'accessory_report' => 'Accessory Report', 'action' => 'Action', - 'actions' => 'Actions', 'activity_report' => 'Activity Report', 'address' => 'Address', 'admin' => 'Admin', @@ -261,4 +260,6 @@ 'hide_help' => 'Hide help', 'view_all' => 'view all', 'hide_deleted' => 'Hide Deleted', + 'email' => 'Email', + 'Help' ]; diff --git a/resources/views/account/accept/index.blade.php b/resources/views/account/accept/index.blade.php index 17997be6e5..7370c3a38a 100755 --- a/resources/views/account/accept/index.blade.php +++ b/resources/views/account/accept/index.blade.php @@ -35,7 +35,7 @@ {{ trans('general.name')}} - {{ trans('general.actions')}} + {{ trans('button.actions')}} diff --git a/resources/views/custom_fields/fields/edit.blade.php b/resources/views/custom_fields/fields/edit.blade.php index a28a58f62c..fd9e78ee3a 100644 --- a/resources/views/custom_fields/fields/edit.blade.php +++ b/resources/views/custom_fields/fields/edit.blade.php @@ -96,11 +96,11 @@
{{ Form::text('help_text', old('help_text', $field->help_text), array('class' => 'form-control', 'aria-label'=>'help_text')) }} -

This is optional text that will appear below the form elements while editing an asset to provide context on the field.

+

{{ trans('admin/custom_fields/general.help_text_description') }}

{!! $errors->first('help_text', '') !!}
@@ -147,8 +147,8 @@
-

About Custom Fields

-

Custom fields allow you to add arbitrary attributes to assets.

+

{{ trans('admin/custom_fields/general.about_custom_fields_title') }}

+

{{ trans('admin/custom_fields/general.about_custom_fields_text') }}

diff --git a/resources/views/custom_fields/fieldsets/edit.blade.php b/resources/views/custom_fields/fieldsets/edit.blade.php index 99a614d83a..04885891ec 100644 --- a/resources/views/custom_fields/fieldsets/edit.blade.php +++ b/resources/views/custom_fields/fieldsets/edit.blade.php @@ -42,8 +42,8 @@ {{ Form::close() }}
-

About Fieldsets

-

Fieldsets work like containers of the custom fields you've created. This allows you to group commonly used custom attributes together for easy associations.

+

{{ trans('admin/custom_fields/general.about_fieldsets_title') }}

+

{{ trans('admin/custom_fields/general.about_fieldsets_text') }}

@stop diff --git a/resources/views/custom_fields/fieldsets/view.blade.php b/resources/views/custom_fields/fieldsets/view.blade.php index da08f7ab61..82b9498fa7 100644 --- a/resources/views/custom_fields/fieldsets/view.blade.php +++ b/resources/views/custom_fields/fieldsets/view.blade.php @@ -27,7 +27,7 @@ {{-- Hide the sorting handle if we can't update the fieldset --}} @can('update', $custom_fieldset) - Reorder + {{ trans('admin/custom_fields/general.reorder') }} @endcan {{ trans('admin/custom_fields/general.order') }} {{ trans('admin/custom_fields/general.field_name') }} @@ -35,7 +35,7 @@ {{ trans('admin/custom_fields/general.field_element') }} {{ trans('admin/custom_fields/general.encrypted') }} {{ trans('admin/custom_fields/general.required') }} - Remove + {{ trans('button.remove') }} @@ -60,18 +60,18 @@ @if ($field->pivot->required) - Required - click to make optional + {{ trans('admin/custom_fields/general.make_optional') }} @else - Optional - click to make required + {{ trans('admin/custom_fields/general.make_required') }} @endif @can('update', $custom_fieldset) - Remove + {{ trans('button.remove') }} @endcan @@ -89,7 +89,7 @@
{{ Form::select("field_id",$custom_fields_list,"",['aria-label'=>'field_id', 'class'=>'select2']) }} @@ -106,7 +106,7 @@
{{ Form::text('order', $maxid, array('class' => 'form-control col-sm-1 col-md-1', 'style'=> 'width: 80px; padding-;right: 10px;', 'aria-label'=>'order', 'maxlength'=>'3', 'size'=>'3')) }} - +
diff --git a/resources/views/custom_fields/index.blade.php b/resources/views/custom_fields/index.blade.php index 434bd78a94..351e27cf5d 100644 --- a/resources/views/custom_fields/index.blade.php +++ b/resources/views/custom_fields/index.blade.php @@ -6,7 +6,7 @@ {{-- Page title --}} @section('title') - Manage {{ trans('admin/custom_fields/general.custom_fields') }} + {{ trans('admin/custom_fields/general.manage') }} {{ trans('admin/custom_fields/general.custom_fields') }} @parent @stop @@ -21,7 +21,7 @@

{{ trans('admin/custom_fields/general.fieldsets') }}

@@ -48,7 +48,7 @@ {{ trans('general.name') }} {{ trans('admin/custom_fields/general.qty_fields') }} {{ trans('admin/custom_fields/general.used_by_models') }} - Actions + {{ trans('button.actions') }} @@ -100,7 +100,7 @@

{{ trans('admin/custom_fields/general.custom_fields') }}

@@ -127,13 +127,13 @@ {{ trans('general.name') }} - Help Text - Email - DB Field + {{ trans('admin/custom_fields/general.help_text')}} + {{ trans('general.email') }} + {{ trans('admin/custom_fields/general.db_field') }} {{ trans('admin/custom_fields/general.field_format') }} {{ trans('admin/custom_fields/general.field_element_short') }} {{ trans('admin/custom_fields/general.fieldsets') }} - Actions + {{ trans('button.actions') }} @@ -145,7 +145,7 @@ {{ $field->convertUnicodeDbSlug() }} @if ($field->convertUnicodeDbSlug()!=$field->db_column) -
WARNING. This field is in the custom fields table as {{ $field->db_column }} but should be {{ $field->convertUnicodeDbSlug() }}. +
{{!! trans('admin/custom_fields/general.db_convert_warning', array('db_column' => $field->db_column, 'expected' => $field->convertUnicodeDbSlug())) !!}} @endif {{ $field->format }} @@ -160,19 +160,19 @@ @can('update', $field) - Edit + {{ trans('button.edit') }} - @endcan + @endcan @can('delete', $field) {{ Form::open(array('route' => array('fields.destroy', $field->id), 'method' => 'delete', 'style' => 'display:inline-block')) }} @if($field->fieldset->count()>0) + {{ trans('button.delete') }} @else @endif {{ Form::close() }} From e825fa81aa7dc4eec9078e228b8330ade6b54dfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?W=C3=A4chtler=2C=20Yannick?= Date: Tue, 2 Nov 2021 11:50:56 +0100 Subject: [PATCH 07/46] Added localized strings for depreciations --- resources/lang/en/admin/depreciations/general.php | 3 +-- resources/lang/en/button.php | 3 ++- resources/lang/en/general.php | 10 +++++++--- resources/views/depreciations/index.blade.php | 2 +- resources/views/depreciations/view.blade.php | 8 ++++---- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/resources/lang/en/admin/depreciations/general.php b/resources/lang/en/admin/depreciations/general.php index e188b2cc1a..1e536085fa 100644 --- a/resources/lang/en/admin/depreciations/general.php +++ b/resources/lang/en/admin/depreciations/general.php @@ -9,6 +9,5 @@ return [ 'depreciation_min' => 'Floor Value of Depreciation', 'number_of_months' => 'Number of Months', 'update' => 'Update Depreciation', - 'depreciation_min' => 'Minimum Value after Depreciation' - + 'depreciation_min' => 'Minimum Value after Depreciation', ]; diff --git a/resources/lang/en/button.php b/resources/lang/en/button.php index ac1e6aa429..1be2a483a3 100644 --- a/resources/lang/en/button.php +++ b/resources/lang/en/button.php @@ -15,5 +15,6 @@ return [ 'select_file' => 'Select File...', 'select_files' => 'Select Files...', 'generate_labels' => '{1} Generate Label|[2,*] Generate Labels', - 'send_password_link' => 'Send Password Reset Link', + 'send_password_link' => 'Send Password Reset Link', + 'go' => 'Go', ]; diff --git a/resources/lang/en/general.php b/resources/lang/en/general.php index 5cf5d88445..e11a0a0bab 100644 --- a/resources/lang/en/general.php +++ b/resources/lang/en/general.php @@ -31,6 +31,9 @@ 'bulkaudit' => 'Bulk Audit', 'bulkaudit_status' => 'Audit Status', 'bulk_checkout' => 'Bulk Checkout', + 'bulk_edit' => 'Bulk Edit', + 'bulk_delete' => 'Bulk Delete', + 'bulk_actions' => 'Bulk Actions', 'bystatus' => 'by Status', 'cancel' => 'Cancel', 'categories' => 'Categories', @@ -77,13 +80,14 @@ 'delete_seats' => 'Deleted Seats', 'deletion_failed' => 'Deletion failed', 'departments' => 'Departments', - 'department' => 'Department', + 'department' => 'Department', 'deployed' => 'Deployed', + 'depreciation' => 'Depreciation', + 'depreciations' => 'Depreciations', 'depreciation_report' => 'Depreciation Report', 'details' => 'Details', 'download' => 'Download', - 'download_all' => 'Download All', - 'depreciation' => 'Depreciation', + 'download_all' => 'Download All', 'editprofile' => 'Edit Your Profile', 'eol' => 'EOL', 'email_domain' => 'Email Domain', diff --git a/resources/views/depreciations/index.blade.php b/resources/views/depreciations/index.blade.php index bfbed2ca6b..e71063771f 100755 --- a/resources/views/depreciations/index.blade.php +++ b/resources/views/depreciations/index.blade.php @@ -2,7 +2,7 @@ {{-- Page title --}} @section('title') - Depreciations + {{ trans('general.depreciations')}} @parent @stop diff --git a/resources/views/depreciations/view.blade.php b/resources/views/depreciations/view.blade.php index c0263fda93..d075a31e95 100644 --- a/resources/views/depreciations/view.blade.php +++ b/resources/views/depreciations/view.blade.php @@ -111,12 +111,12 @@ ) }}
- + - +
From 167bf97d46e3a6f5cee42a450d2cf70d37af9fa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?W=C3=A4chtler=2C=20Yannick?= Date: Tue, 2 Nov 2021 12:03:41 +0100 Subject: [PATCH 08/46] Added localized strings for groups --- resources/lang/en/admin/groups/titles.php | 4 +++- resources/lang/en/general.php | 1 - resources/views/account/accept/index.blade.php | 2 +- resources/views/custom_fields/index.blade.php | 2 +- resources/views/groups/edit.blade.php | 18 +++++++++--------- resources/views/groups/view.blade.php | 2 +- 6 files changed, 15 insertions(+), 14 deletions(-) diff --git a/resources/lang/en/admin/groups/titles.php b/resources/lang/en/admin/groups/titles.php index 8807f5e54a..d875f190d7 100644 --- a/resources/lang/en/admin/groups/titles.php +++ b/resources/lang/en/admin/groups/titles.php @@ -10,5 +10,7 @@ return [ 'group_admin' => 'Group Admin', 'allow' => 'Allow', 'deny' => 'Deny', - + 'permission' => 'Permission', + 'grant' => 'Grant', + 'no_permissions' => 'This group has no permissions.' ]; diff --git a/resources/lang/en/general.php b/resources/lang/en/general.php index e11a0a0bab..d3aff38869 100644 --- a/resources/lang/en/general.php +++ b/resources/lang/en/general.php @@ -265,5 +265,4 @@ 'view_all' => 'view all', 'hide_deleted' => 'Hide Deleted', 'email' => 'Email', - 'Help' ]; diff --git a/resources/views/account/accept/index.blade.php b/resources/views/account/accept/index.blade.php index 7370c3a38a..f97c6c5644 100755 --- a/resources/views/account/accept/index.blade.php +++ b/resources/views/account/accept/index.blade.php @@ -35,7 +35,7 @@ {{ trans('general.name')}} - {{ trans('button.actions')}} + {{ trans('table.actions')}} diff --git a/resources/views/custom_fields/index.blade.php b/resources/views/custom_fields/index.blade.php index 351e27cf5d..01314fb7b7 100644 --- a/resources/views/custom_fields/index.blade.php +++ b/resources/views/custom_fields/index.blade.php @@ -48,7 +48,7 @@ {{ trans('general.name') }} {{ trans('admin/custom_fields/general.qty_fields') }} {{ trans('admin/custom_fields/general.used_by_models') }} - {{ trans('button.actions') }} + {{ trans('table.actions') }} diff --git a/resources/views/groups/edit.blade.php b/resources/views/groups/edit.blade.php index 8f280dfe9a..3c8769f56a 100755 --- a/resources/views/groups/edit.blade.php +++ b/resources/views/groups/edit.blade.php @@ -65,9 +65,9 @@ - - - + + + @foreach ($permissions as $area => $area_permission) @@ -87,11 +87,11 @@ @endunless @@ -108,11 +108,11 @@ @@ -128,11 +128,11 @@ {{ $this_permission['label'] }} diff --git a/resources/views/groups/view.blade.php b/resources/views/groups/view.blade.php index 84e91c9dde..9b6c098638 100644 --- a/resources/views/groups/view.blade.php +++ b/resources/views/groups/view.blade.php @@ -57,7 +57,7 @@ @else -

This group has no permissions.

+

{{ trans('admin/groups/title.no_permissions') }}

@endif From c16ade2d87d3dd4ed63c33ad07b20c18b4effc78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?W=C3=A4chtler=2C=20Yannick?= Date: Tue, 2 Nov 2021 14:02:48 +0100 Subject: [PATCH 09/46] Added localized strings for hardware --- resources/lang/en/admin/hardware/form.php | 6 ++++ resources/lang/en/admin/hardware/general.php | 19 +++++++++++ resources/lang/en/admin/hardware/table.php | 8 +++-- resources/lang/en/button.php | 2 ++ resources/lang/en/general.php | 4 +++ resources/views/hardware/audit.blade.php | 2 +- .../views/hardware/bulk-delete.blade.php | 10 +++--- resources/views/hardware/bulk.blade.php | 10 +++--- resources/views/hardware/checkout.blade.php | 2 +- resources/views/hardware/edit.blade.php | 4 +-- resources/views/hardware/history.blade.php | 34 ++++++++----------- resources/views/hardware/index.blade.php | 6 ++-- resources/views/hardware/quickscan.blade.php | 4 +-- resources/views/hardware/requested.blade.php | 4 +-- resources/views/hardware/view.blade.php | 16 ++++----- 15 files changed, 80 insertions(+), 51 deletions(-) diff --git a/resources/lang/en/admin/hardware/form.php b/resources/lang/en/admin/hardware/form.php index 86a40a5fa2..0c1a3167be 100644 --- a/resources/lang/en/admin/hardware/form.php +++ b/resources/lang/en/admin/hardware/form.php @@ -40,4 +40,10 @@ return [ 'warranty' => 'Warranty', 'warranty_expires' => 'Warranty Expires', 'years' => 'years', + 'asset_location' => 'Update Asset Location', + 'asset_location_update_default_current' => 'Update default location AND actual location', + 'asset_location_update_default' => 'Update only default location', + 'asset_not_deployable' => 'That asset status is not deployable. This asset cannot be checked out.', + 'asset_deployable' => 'That status is deployable. This asset can be checked out.', + 'processing_spinner' => 'Processing...', ]; diff --git a/resources/lang/en/admin/hardware/general.php b/resources/lang/en/admin/hardware/general.php index 80a2c14e50..655696956f 100644 --- a/resources/lang/en/admin/hardware/general.php +++ b/resources/lang/en/admin/hardware/general.php @@ -19,4 +19,23 @@ return [ 'pending' => 'Pending', 'undeployable' => 'Undeployable', 'view' => 'View Asset', + 'csv_error' => 'You have an error in your CSV file:', + 'import_text' => ' +

+ Upload a CSV that contains asset history. The assets and users MUST already exist in the system, or they will be skipped. Matching assets for history import happens against the asset tag. We will try to find a matching user based on the user\'s name you provide, and the criteria you select below. If you do not select any criteria below, it will simply try to match on the username format you configured in the Admin > General Settings. +

+ +

Fields included in the CSV must match the headers: Asset Tag, Name, Checkout Date, Checkin Date. Any additional fields will be ignored.

+ +

Checkin Date: blank or future checkin dates will checkout items to associated user. Excluding the Checkin Date column will create a checkin date with todays date.

+ ', + 'csv_import_match_f-l' => 'Try to match users by firstname.lastname (jane.smith) format', + 'csv_import_match_initial_last' => 'Try to match users by first initial last name (jsmith) format', + 'csv_import_match_first' => 'Try to match users by first name (jane) format', + 'csv_import_match_email' => 'Try to match users by email as username', + 'csv_import_match_username' => 'Try to match users by username', + 'error_messages' => 'Error messages:', + 'success_messages' => 'Success messages:', + 'alert_details' => 'Please see below for details.', + 'custom_export' => 'Custom Export' ]; diff --git a/resources/lang/en/admin/hardware/table.php b/resources/lang/en/admin/hardware/table.php index 828990b6e4..6166ba8045 100644 --- a/resources/lang/en/admin/hardware/table.php +++ b/resources/lang/en/admin/hardware/table.php @@ -19,8 +19,12 @@ return [ 'serial' => 'Serial', 'status' => 'Status', 'title' => 'Asset ', - 'image' => 'Device Image', + 'image' => 'Device Image', 'days_without_acceptance' => 'Days Without Acceptance', 'monthly_depreciation' => 'Monthly Depreciation', - + 'assigned_to' => 'Assigned To', + 'requesting_user' => 'Requesting User', + 'requested_date' => 'Requested Date', + 'changed' => 'Changed', + 'icon' => 'Icon', ]; diff --git a/resources/lang/en/button.php b/resources/lang/en/button.php index 1be2a483a3..b39d0c0545 100644 --- a/resources/lang/en/button.php +++ b/resources/lang/en/button.php @@ -17,4 +17,6 @@ return [ 'generate_labels' => '{1} Generate Label|[2,*] Generate Labels', 'send_password_link' => 'Send Password Reset Link', 'go' => 'Go', + 'bulk_actions' => 'Bulk Actions', + 'add_maintenance' => 'Add Maintenance', ]; diff --git a/resources/lang/en/general.php b/resources/lang/en/general.php index d3aff38869..d5d24afafa 100644 --- a/resources/lang/en/general.php +++ b/resources/lang/en/general.php @@ -88,6 +88,7 @@ 'details' => 'Details', 'download' => 'Download', 'download_all' => 'Download All', + 'edit' => 'Edit', 'editprofile' => 'Edit Your Profile', 'eol' => 'EOL', 'email_domain' => 'Email Domain', @@ -110,6 +111,7 @@ 'file_type' => 'File Type', 'file_uploads' => 'File Uploads', 'generate' => 'Generate', + 'generate_labels' => 'Generate Labels', 'github_markdown' => 'This field accepts Github flavored markdown.', 'groups' => 'Groups', 'gravatar_email' => 'Gravatar Email Address', @@ -213,6 +215,7 @@ 'sign_in' => 'Sign in', 'signature' => 'Signature', 'skin' => 'Skin', + 'slack_msg_note' => 'A slack message will be sent', 'slack_test_msg' => 'Oh hai! Looks like your Slack integration with Snipe-IT is working!', 'some_features_disabled' => 'DEMO MODE: Some features are disabled for this installation.', 'site_name' => 'Site Name', @@ -265,4 +268,5 @@ 'view_all' => 'view all', 'hide_deleted' => 'Hide Deleted', 'email' => 'Email', + 'do_not_change' => 'Do Not Change', ]; diff --git a/resources/views/hardware/audit.blade.php b/resources/views/hardware/audit.blade.php index ed395ec128..3ab2fbfc96 100644 --- a/resources/views/hardware/audit.blade.php +++ b/resources/views/hardware/audit.blade.php @@ -57,7 +57,7 @@
@include ('partials.more-info', ['helpText' => trans('help.audit_help'), 'helpPosition' => 'right']) diff --git a/resources/views/hardware/bulk-delete.blade.php b/resources/views/hardware/bulk-delete.blade.php index ed36296605..df19c9005f 100644 --- a/resources/views/hardware/bulk-delete.blade.php +++ b/resources/views/hardware/bulk-delete.blade.php @@ -29,10 +29,10 @@
- - - - + + + + @@ -59,7 +59,7 @@ diff --git a/resources/views/hardware/bulk.blade.php b/resources/views/hardware/bulk.blade.php index ae84e9008a..b073a3b74c 100755 --- a/resources/views/hardware/bulk.blade.php +++ b/resources/views/hardware/bulk.blade.php @@ -75,12 +75,12 @@
@@ -137,13 +137,13 @@
diff --git a/resources/views/hardware/checkout.blade.php b/resources/views/hardware/checkout.blade.php index 8608fd6273..9841e134ee 100755 --- a/resources/views/hardware/checkout.blade.php +++ b/resources/views/hardware/checkout.blade.php @@ -124,7 +124,7 @@ @if ($snipeSettings->slack_endpoint!='') - A slack message will be sent + {{ trans('general.slack_msg_note')}} @endif diff --git a/resources/views/hardware/edit.blade.php b/resources/views/hardware/edit.blade.php index 9f24460ef4..20e93f0677 100755 --- a/resources/views/hardware/edit.blade.php +++ b/resources/views/hardware/edit.blade.php @@ -181,7 +181,7 @@ $("#selected_status_status").removeClass('text-danger'); $("#selected_status_status").removeClass('text-warning'); $("#selected_status_status").addClass('text-success'); - $("#selected_status_status").html(' That status is deployable. This asset can be checked out.'); + $("#selected_status_status").html(' {{ trans('admin/hardware/form.asset_deployable')}}'); } else { @@ -189,7 +189,7 @@ $("#selected_status_status").removeClass('text-danger'); $("#selected_status_status").removeClass('text-success'); $("#selected_status_status").addClass('text-warning'); - $("#selected_status_status").html(' That asset status is not deployable. This asset cannot be checked out. '); + $("#selected_status_status").html(' {{ trans('admin/hardware/form.asset_not_deployable')}} '); } } }); diff --git a/resources/views/hardware/history.blade.php b/resources/views/hardware/history.blade.php index 9a8bcdda49..349dc8da38 100644 --- a/resources/views/hardware/history.blade.php +++ b/resources/views/hardware/history.blade.php @@ -2,7 +2,7 @@ {{-- Page title --}} @section('title') - Import History + {{ trans('general.import-history') }} @parent @stop @@ -22,8 +22,8 @@
- {{ count($status['error']) }} Error Messagess: - Please see below for errors. + {{ count($status['error']) }} {{ trans('admin/hardware/general.error_messages') }} + {{ trans('admin/hardware/general.alert_details') }}
@@ -35,8 +35,8 @@
- {{ count($status['success']) }} Success Messages: - Please see below for details. + {{ count($status['success']) }} {{ trans('admin/hardware/general.success_messages') }} + {{ trans('admin/hardware/general.alert_details') }}
@@ -55,18 +55,12 @@ @if (Session::get('message'))

- You have an error in your CSV file:
+ {{ trans('admin/hardware/general.csv_error') }}
{{ Session::get('message') }}

@endif -

- Upload a CSV that contains asset history. The assets and users MUST already exist in the system, or they will be skipped. Matching assets for history import happens against the asset tag. We will try to find a matching user based on the user's name you provide, and the criteria you select below. If you do not select any criteria below, it will simply try to match on the username format you configured in the Admin > General Settings. -

- -

Fields included in the CSV must match the headers: Asset Tag, Name, Checkout Date, Checkin Date. Any additional fields will be ignored.

- -

Checkin Date: blank or future checkin dates will checkout items to associated user. Excluding the Checkin Date column will create a checkin date with todays date.

+ {!! trans('admin/hardware/general.import_text') !!}
@@ -86,7 +80,7 @@
- {{ Form::checkbox('match_firstnamelastname', '1', Request::old('match_firstnamelastname')) }} Try to match users by firstname.lastname (jane.smith) format + {{ Form::checkbox('match_firstnamelastname', '1', Request::old('match_firstnamelastname')) }} {{ trans('admin/hardware/general.csv_import_match_f-l') }}
@@ -95,7 +89,7 @@
- {{ Form::checkbox('match_flastname', '1', Request::old('match_flastname')) }} Try to match users by first initial last name (jsmith) format + {{ Form::checkbox('match_flastname', '1', Request::old('match_flastname')) }} {{ trans('admin/hardware/general.csv_import_match_initial_last') }}
@@ -104,7 +98,7 @@
- {{ Form::checkbox('match_firstname', '1', Request::old('match_firstname')) }} Try to match users by first name (jane) format + {{ Form::checkbox('match_firstname', '1', Request::old('match_firstname')) }} {{ trans('admin/hardware/general.csv_import_match_first') }}
@@ -113,7 +107,7 @@
- {{ Form::checkbox('match_email', '1', Request::old('match_email')) }} Try to match users by email as username + {{ Form::checkbox('match_email', '1', Request::old('match_email')) }} {{ trans('admin/hardware/general.csv_import_match_email') }}
@@ -122,7 +116,7 @@
- {{ Form::checkbox('match_username', '1', Request::old('match_username')) }} Try to match users by username + {{ Form::checkbox('match_username', '1', Request::old('match_username')) }} {{ trans('admin/hardware/general.csv_import_match_username') }}
@@ -158,7 +152,7 @@
-

{{ count($status['error']) }} Error Messages

+

{{ count($status['error']) }} {{ trans('admin/hardware/general.error_messages') }}

@@ -185,7 +179,7 @@
-

{{ count($status['success']) }} Success Messages

+

{{ count($status['success']) }} {{ trans('admin/hardware/general.success_messages') }}

diff --git a/resources/views/hardware/index.blade.php b/resources/views/hardware/index.blade.php index 267b68a56c..d4bd6fc88a 100755 --- a/resources/views/hardware/index.blade.php +++ b/resources/views/hardware/index.blade.php @@ -43,7 +43,7 @@ @section('header_right') - Custom Export + {{ trans('admin/hardware/general.custom_export') }} @can('create', \App\Models\Asset::class) {{ trans('general.create') }} @endcan @@ -73,14 +73,14 @@ 'id' => 'bulkForm']) }} - + - + {{ Form::close() }}
diff --git a/resources/views/hardware/quickscan.blade.php b/resources/views/hardware/quickscan.blade.php index 2b81d858f3..5b2e09b947 100644 --- a/resources/views/hardware/quickscan.blade.php +++ b/resources/views/hardware/quickscan.blade.php @@ -51,7 +51,7 @@
@@ -112,7 +112,7 @@
diff --git a/resources/views/hardware/requested.blade.php b/resources/views/hardware/requested.blade.php index f86675663d..901356e69c 100644 --- a/resources/views/hardware/requested.blade.php +++ b/resources/views/hardware/requested.blade.php @@ -49,8 +49,8 @@ - - + + diff --git a/resources/views/hardware/view.blade.php b/resources/views/hardware/view.blade.php index 63ef534087..79e8301d76 100755 --- a/resources/views/hardware/view.blade.php +++ b/resources/views/hardware/view.blade.php @@ -972,13 +972,13 @@ 'class' => 'form-inline', 'id' => 'bulkForm']) }}
- + - +
@@ -1028,7 +1028,7 @@
@can('update', \App\Models\Asset::class) @endcan @@ -1083,7 +1083,7 @@ data-cookie="true">
- + @@ -1094,7 +1094,7 @@ @endif - +
PermissionGrantDeny{{ trans('admin/groups/titles.permission')}}{{ trans('admin/groups/titles.grant')}}{{ trans('admin/groups/titles.deny')}}
- + {{ Form::radio('permission['.$localPermission['permission'].']', '1',(array_key_exists($localPermission['permission'], $groupPermissions) ? $groupPermissions[$localPermission['permission'] ] == '1' : null),['value'=>"grant", 'class'=>'minimal', 'aria-label'=> 'permission['.$localPermission['permission'].']']) }} - + {{ Form::radio('permission['.$localPermission['permission'].']', '0',(array_key_exists($localPermission['permission'], $groupPermissions) ? $groupPermissions[$localPermission['permission'] ] == '0' : null),['value'=>"grant", 'class'=>'minimal', 'aria-label'=> 'permission['.$localPermission['permission'].']']) }}
- + {{ Form::radio("$area", '1',false,['value'=>"grant", 'class'=>'minimal', 'data-checker-group' => str_slug($area), 'aria-label'=> $area]) }} - + {{ Form::radio("$area", '0',false,['value'=>"deny", 'class'=>'minimal', 'data-checker-group' => str_slug($area), 'aria-label'=> $area]) }}
- + {{ Form::radio('permission['.$this_permission['permission'].']', '1',(array_key_exists($this_permission['permission'], $groupPermissions) ? $groupPermissions[$this_permission['permission'] ] == '1' : null),['class'=>'minimal radiochecker-'.str_slug($area), 'aria-label'=>'permission['.$this_permission['permission'].']']) }} - + {{ Form::radio('permission['.$this_permission['permission'].']', '0',(array_key_exists($this_permission['permission'], $groupPermissions) ? $groupPermissions[$this_permission['permission'] ] == '0' : null),['class'=>'minimal radiochecker-'.str_slug($area), 'aria-label'=>'permission['.$this_permission['permission'].']']) }}
IDNameLocationAssigned To{{ trans('admin/hardware/table.id') }}{{ trans('admin/hardware/table.name') }}{{ trans('admin/hardware/table.location')}}{{ trans('admin/hardware/table.assigned_to') }}
Item Name {{ trans('admin/hardware/table.location') }} {{ trans('admin/hardware/form.expected_checkin') }}Requesting UserRequested Date{{ trans('admin/hardware/form.requesting_user') }}{{ trans('admin/hardware/form.requested_date') }}
{{ trans('general.date') }} {{ trans('general.admin') }} {{ trans('general.action') }}{{ trans('general.signature') }}{{ trans('general.download') }}Changed{{ trans('admin/hardware/table.changed')}}
From 26e056fb3c15396f069f4ced5abede3b258e4a7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?W=C3=A4chtler=2C=20Yannick?= Date: Tue, 2 Nov 2021 14:09:22 +0100 Subject: [PATCH 10/46] Added localized strings for improter, added en structure --- resources/views/importer/import.blade.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/resources/views/importer/import.blade.php b/resources/views/importer/import.blade.php index 54c1c90be4..ca585d1f48 100644 --- a/resources/views/importer/import.blade.php +++ b/resources/views/importer/import.blade.php @@ -42,9 +42,9 @@ @if (!config('app.lock_passwords')) - Select Import File... + {{ trans('admin/importer/general.select_import_file') }} - + @endif @@ -67,11 +67,11 @@ class="col-md-12 table table-striped snipe-table"> - File - Created - Size - Process - Delete + {{ trans('admin/importer/table.file') }} + {{ trans('admin/importer/table.created') }} + {{ trans('admin/importer/table.size') }} + {{ trans('admin/importer/table.process') }} + {{ trans('admin/importer/table.delete') }}