mirror of
https://github.com/snipe/snipe-it.git
synced 2024-12-26 06:04:08 -08:00
251 lines
11 KiB
PHP
251 lines
11 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Helper;
|
|
use ArieTimmerman\Laravel\SCIMServer\SCIM\Schema;
|
|
use ArieTimmerman\Laravel\SCIMServer\Attribute\AttributeMapping;
|
|
|
|
|
|
class SnipeSCIMConfig extends \ArieTimmerman\Laravel\SCIMServer\SCIMConfig
|
|
{
|
|
public function getUserConfig()
|
|
{
|
|
// Much of this is copied verbatim from the library, then adjusted for our needs
|
|
|
|
/*
|
|
more snipe-it attributes I'd like to check out (to map to 'enterprise' maybe?):
|
|
- website
|
|
- notes?
|
|
- remote???
|
|
- location_id ?
|
|
- company_id to "organization?"
|
|
*/
|
|
|
|
|
|
$user_prefix = 'urn:ietf:params:scim:schemas:core:2.0:User:';
|
|
$enterprise_prefix = 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:';
|
|
|
|
return [
|
|
|
|
// Set to 'null' to make use of auth.providers.users.model (App\User::class)
|
|
'class' => SCIMUser::class,
|
|
|
|
'validations' => [
|
|
$user_prefix . 'userName' => 'required',
|
|
$user_prefix . 'name.givenName' => 'required',
|
|
$user_prefix . 'name.familyName' => 'nullable|string',
|
|
$user_prefix . 'externalId' => 'nullable|string',
|
|
$user_prefix . 'emails' => 'nullable|array',
|
|
$user_prefix . 'emails.*.value' => 'nullable|email',
|
|
$user_prefix . 'active' => 'boolean',
|
|
$user_prefix . 'phoneNumbers' => 'nullable|array',
|
|
$user_prefix . 'phoneNumbers.*.value' => 'nullable|string',
|
|
$user_prefix . 'addresses' => 'nullable|array',
|
|
$user_prefix . 'addresses.*.streetAddress' => 'nullable|string',
|
|
$user_prefix . 'addresses.*.locality' => 'nullable|string',
|
|
$user_prefix . 'addresses.*.region' => 'nullable|string',
|
|
$user_prefix . 'addresses.*.postalCode' => 'nullable|string',
|
|
$user_prefix . 'addresses.*.country' => 'nullable|string',
|
|
$user_prefix . 'title' => 'nullable|string',
|
|
$user_prefix . 'preferredLanguage' => 'nullable|string',
|
|
|
|
// Enterprise validations:
|
|
$enterprise_prefix . 'employeeNumber' => 'nullable|string',
|
|
$enterprise_prefix . 'department' => 'nullable|string',
|
|
$enterprise_prefix . 'manager' => 'nullable',
|
|
$enterprise_prefix . 'manager.value' => 'nullable|string'
|
|
],
|
|
|
|
'singular' => 'User',
|
|
'schema' => [Schema::SCHEMA_USER],
|
|
|
|
//eager loading
|
|
'withRelations' => [],
|
|
'map_unmapped' => false,
|
|
// 'unmapped_namespace' => 'urn:ietf:params:scim:schemas:laravel:unmapped',
|
|
'description' => 'User Account',
|
|
|
|
// Map a SCIM attribute to an attribute of the object.
|
|
'mapping' => [
|
|
|
|
'id' => (new AttributeMapping())->setRead(
|
|
function (&$object) {
|
|
return (string)$object->id;
|
|
}
|
|
)->disableWrite(),
|
|
|
|
'externalId' => AttributeMapping::eloquent('scim_externalid'), // FIXME - I have a PR that changes a lot of this.
|
|
|
|
'meta' => [
|
|
'created' => AttributeMapping::eloquent("created_at")->disableWrite(),
|
|
'lastModified' => AttributeMapping::eloquent("updated_at")->disableWrite(),
|
|
|
|
'location' => (new AttributeMapping())->setRead(
|
|
function ($object) {
|
|
return route(
|
|
'scim.resource',
|
|
[
|
|
'resourceType' => 'Users',
|
|
'resourceObject' => $object->id
|
|
]
|
|
);
|
|
}
|
|
)->disableWrite(),
|
|
|
|
'resourceType' => AttributeMapping::constant("User")
|
|
],
|
|
|
|
'schemas' => AttributeMapping::constant(
|
|
[
|
|
'urn:ietf:params:scim:schemas:core:2.0:User',
|
|
'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User'
|
|
]
|
|
)->ignoreWrite(),
|
|
|
|
'urn:ietf:params:scim:schemas:core:2.0:User' => [
|
|
|
|
'userName' => AttributeMapping::eloquent("username"),
|
|
|
|
'name' => [
|
|
'formatted' => (new AttributeMapping())->ignoreWrite()->setRead(
|
|
function (&$object) {
|
|
return $object->getFullNameAttribute();
|
|
}
|
|
),
|
|
'familyName' => AttributeMapping::eloquent("last_name"),
|
|
'givenName' => AttributeMapping::eloquent("first_name"),
|
|
'middleName' => null,
|
|
'honorificPrefix' => null,
|
|
'honorificSuffix' => null
|
|
],
|
|
|
|
'displayName' => null,
|
|
'nickName' => null,
|
|
'profileUrl' => null,
|
|
'title' => AttributeMapping::eloquent('jobtitle'),
|
|
'userType' => null,
|
|
'preferredLanguage' => AttributeMapping::eloquent('locale'), // Section 5.3.5 of [RFC7231]
|
|
'locale' => null, // see RFC5646
|
|
'timezone' => null, // see RFC6557
|
|
'active' => (new AttributeMapping())->setAdd(
|
|
function ($value, &$object) {
|
|
$object->activated = $value;
|
|
}
|
|
)->setReplace(
|
|
function ($value, &$object) {
|
|
$object->activated = $value;
|
|
}
|
|
)->setRead(
|
|
// this works as specified.
|
|
function (&$object) {
|
|
return (bool)$object->activated;
|
|
}
|
|
),
|
|
'password' => AttributeMapping::eloquent('password')->disableRead(),
|
|
|
|
// Multi-Valued Attributes
|
|
'emails' => [[
|
|
"value" => AttributeMapping::eloquent("email"),
|
|
"display" => null,
|
|
"type" => AttributeMapping::constant("work")->ignoreWrite(),
|
|
"primary" => AttributeMapping::constant(true)->ignoreWrite()
|
|
]],
|
|
|
|
'phoneNumbers' => [[
|
|
"value" => AttributeMapping::eloquent("phone"),
|
|
"display" => null,
|
|
"type" => AttributeMapping::constant("work")->ignoreWrite(),
|
|
"primary" => AttributeMapping::constant(true)->ignoreWrite()
|
|
]],
|
|
|
|
'ims' => [[
|
|
"value" => null,
|
|
"display" => null,
|
|
"type" => null,
|
|
"primary" => null
|
|
]], // Instant messaging addresses for the User
|
|
|
|
'photos' => [[
|
|
"value" => null,
|
|
"display" => null,
|
|
"type" => null,
|
|
"primary" => null
|
|
]],
|
|
|
|
'addresses' => [[
|
|
'type' => AttributeMapping::constant("work")->ignoreWrite(),
|
|
'formatted' => AttributeMapping::constant("n/a")->ignoreWrite(), // TODO - is this right? This doesn't look right.
|
|
'streetAddress' => AttributeMapping::eloquent("address"),
|
|
'locality' => AttributeMapping::eloquent("city"),
|
|
'region' => AttributeMapping::eloquent("state"),
|
|
'postalCode' => AttributeMapping::eloquent("zip"),
|
|
'country' => AttributeMapping::eloquent("country"),
|
|
'primary' => AttributeMapping::constant(true)->ignoreWrite() //this isn't in the example?
|
|
]],
|
|
|
|
'groups' => [[
|
|
'value' => null,
|
|
'$ref' => null,
|
|
'display' => null,
|
|
'type' => null,
|
|
]],
|
|
|
|
'entitlements' => null,
|
|
'roles' => null,
|
|
'x509Certificates' => null
|
|
],
|
|
|
|
'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User' => [
|
|
'employeeNumber' => AttributeMapping::eloquent('employee_num'),
|
|
'department' => (new AttributeMapping())->setAdd( // FIXME parent?
|
|
function ($value, &$object) {
|
|
$department = Department::where("name", $value)->first();
|
|
if ($department) {
|
|
$object->department_id = $department->id;
|
|
}
|
|
}
|
|
)->setReplace(
|
|
function ($value, &$object) {
|
|
$department = Department::where("name", $value)->first();
|
|
if ($department) {
|
|
$object->department_id = $department->id;
|
|
}
|
|
}
|
|
)->setRead(
|
|
function (&$object) {
|
|
return $object->department ? $object->department->name : null;
|
|
}
|
|
),
|
|
'manager' => [
|
|
// FIXME - manager writes are disabled. This kinda works but it leaks errors all over the place. Not cool.
|
|
// '$ref' => (new AttributeMapping())->ignoreWrite()->ignoreRead(),
|
|
// 'displayName' => (new AttributeMapping())->ignoreWrite()->ignoreRead(),
|
|
// NOTE: you could probably do a 'plain' Eloquent mapping here, but we don't for future-proofing
|
|
'value' => (new AttributeMapping())->setAdd(
|
|
function ($value, &$object) {
|
|
$manager = User::find($value);
|
|
if ($manager) {
|
|
$object->manager_id = $manager->id;
|
|
}
|
|
}
|
|
)->setReplace(
|
|
function ($value, &$object) {
|
|
$manager = User::find($value);
|
|
if ($manager) {
|
|
$object->manager_id = $manager->id;
|
|
}
|
|
}
|
|
)->setRead(
|
|
function (&$object) {
|
|
return $object->manager_id;
|
|
}
|
|
),
|
|
]
|
|
]
|
|
]
|
|
];
|
|
}
|
|
}
|