Skip to content
GitLab
Explore
Sign in
libre.sh
scim
Nextcloud SCIM
Compare revisions
735f664e06dcc410980a79d4d7217a5e6d170095 to 50266601a7118281005a5d3dabec183158d3c312
Hide whitespace changes
Inline
Side-by-side
lib/Repositories/Groups/NextcloudGroupRepository.php
0 → 100644
View file @
50266601
<?php
namespace
OCA\SCIMServiceProvider\Repositories\Groups
;
use
Opf\Models\SCIM\Standard\Groups\CoreGroup
;
use
Opf\Repositories\Repository
;
use
Opf\Util\Filters\FilterUtil
;
use
Psr\Container\ContainerInterface
;
use
Psr\Log\LoggerInterface
;
class
NextcloudGroupRepository
extends
Repository
{
/** @var Psr\Log\LoggerInterface */
private
$logger
;
public
function
__construct
(
ContainerInterface
$container
)
{
parent
::
__construct
(
$container
);
$this
->
dataAccess
=
$container
->
get
(
'GroupDataAccess'
);
$this
->
adapter
=
$container
->
get
(
'GroupAdapter'
);
$this
->
logger
=
$container
->
get
(
LoggerInterface
::
class
);
}
/**
* Read all groups in SCIM format
*/
public
function
getAll
(
$filter
=
''
,
$startIndex
=
0
,
$count
=
0
,
$attributes
=
[],
$excludedAttributes
=
[]
):
array
{
$this
->
logger
->
info
(
"["
.
NextcloudGroupRepository
::
class
.
"] reading all groups"
);
// Read all NC groups
$ncGroups
=
$this
->
dataAccess
->
getAll
();
$scimGroups
=
[];
$this
->
logger
->
info
(
"["
.
NextcloudGroupRepository
::
class
.
"] fetched "
.
count
(
$ncGroups
)
.
" NC groups"
);
foreach
(
$ncGroups
as
$ncGroup
)
{
$scimGroup
=
$this
->
adapter
->
getCoreGroup
(
$ncGroup
);
$scimGroups
[]
=
$scimGroup
;
}
$this
->
logger
->
info
(
"["
.
NextcloudGroupRepository
::
class
.
"] transformed "
.
count
(
$scimGroups
)
.
" SCIM groups"
);
if
(
isset
(
$filter
)
&&
!
empty
(
$filter
))
{
$scimGroupsToFilter
=
[];
foreach
(
$scimGroups
as
$scimGroup
)
{
$scimGroupsToFilter
[]
=
$scimGroup
->
toSCIM
(
false
);
}
$filteredScimData
=
FilterUtil
::
performFiltering
(
$filter
,
$scimGroupsToFilter
);
$scimGroups
=
[];
foreach
(
$filteredScimData
as
$filteredScimGroup
)
{
$scimGroup
=
new
CoreGroup
();
$scimGroup
->
fromSCIM
(
$filteredScimGroup
);
$scimGroups
[]
=
$scimGroup
;
}
return
$scimGroups
;
}
return
$scimGroups
;
}
/**
* Read a single group by ID in SCIM format
*/
public
function
getOneById
(
string
$id
,
$filter
=
''
,
$startIndex
=
0
,
$count
=
0
,
$attributes
=
[],
$excludedAttributes
=
[]
):
?CoreGroup
{
$this
->
logger
->
info
(
"["
.
NextcloudGroupRepository
::
class
.
"] reading group with ID: "
.
$id
);
$ncGroup
=
$this
->
dataAccess
->
getOneById
(
$id
);
return
$this
->
adapter
->
getCoreGroup
(
$ncGroup
);
}
/**
* Create a group from SCIM data
*/
public
function
create
(
$object
):
?CoreGroup
{
$scimGroupToCreate
=
new
CoreGroup
();
$scimGroupToCreate
->
fromSCIM
(
$object
);
$displayName
=
$scimGroupToCreate
->
getDisplayName
();
$ncGroupCreated
=
$this
->
dataAccess
->
create
(
$displayName
);
$this
->
logger
->
info
(
"["
.
NextcloudGroupRepository
::
class
.
"] creating group with displayName: "
.
$displayName
);
if
(
isset
(
$ncGroupCreated
))
{
// Set the rest of the properties of the NC group with the adapter
$ncGroupCreated
=
$this
->
adapter
->
getNCGroup
(
$scimGroupToCreate
,
$ncGroupCreated
);
return
$this
->
adapter
->
getCoreGroup
(
$ncGroupCreated
);
}
$this
->
logger
->
error
(
"["
.
NextcloudGroupRepository
::
class
.
"] creation of group with displayName: "
.
$displayName
.
" failed"
);
return
null
;
}
/**
* Update a group by ID from SCIM data
*/
public
function
update
(
string
$id
,
$object
):
?CoreGroup
{
$this
->
logger
->
info
(
"["
.
NextcloudGroupRepository
::
class
.
"] updating group with ID: "
.
$id
);
$scimGroupToUpdate
=
new
CoreGroup
();
$scimGroupToUpdate
->
fromSCIM
(
$object
);
$ncGroup
=
$this
->
dataAccess
->
getOneById
(
$id
);
if
(
isset
(
$ncGroup
))
{
$ncGroupToUpdate
=
$this
->
adapter
->
getNCGroup
(
$scimGroupToUpdate
,
$ncGroup
);
$ncGroupUpdated
=
$this
->
dataAccess
->
update
(
$id
,
$ncGroupToUpdate
);
if
(
isset
(
$ncGroupUpdated
))
{
return
$this
->
adapter
->
getCoreGroup
(
$ncGroupUpdated
);
}
}
$this
->
logger
->
error
(
"["
.
NextcloudGroupRepository
::
class
.
"] update of group with ID: "
.
$id
.
" failed"
);
return
null
;
}
/**
* Delete a group by ID
*/
public
function
delete
(
string
$id
):
bool
{
$this
->
logger
->
info
(
"["
.
NextcloudGroupRepository
::
class
.
"] deleting group with ID: "
.
$id
);
return
$this
->
dataAccess
->
delete
(
$id
);
}
}
lib/Repositories/Users/NextcloudUserRepository.php
0 → 100644
View file @
50266601
<?php
namespace
OCA\SCIMServiceProvider\Repositories\Users
;
use
Opf\Models\SCIM\Standard\Users\CoreUser
;
use
Opf\Repositories\Repository
;
use
Opf\Util\Filters\FilterUtil
;
use
Psr\Container\ContainerInterface
;
use
Psr\Log\LoggerInterface
;
class
NextcloudUserRepository
extends
Repository
{
/** @var Psr\Log\LoggerInterface */
private
$logger
;
public
function
__construct
(
ContainerInterface
$container
)
{
parent
::
__construct
(
$container
);
$this
->
dataAccess
=
$container
->
get
(
'UserDataAccess'
);
$this
->
adapter
=
$container
->
get
(
'UserAdapter'
);
$this
->
logger
=
$container
->
get
(
LoggerInterface
::
class
);
}
/**
* Read all users in SCIM format
*/
public
function
getAll
(
$filter
=
''
,
$startIndex
=
0
,
$count
=
0
,
$attributes
=
[],
$excludedAttributes
=
[]
):
array
{
$this
->
logger
->
info
(
"["
.
NextcloudUserRepository
::
class
.
"] reading all users"
);
// Read all NC users
$ncUsers
=
$this
->
dataAccess
->
getAll
();
$scimUsers
=
[];
$this
->
logger
->
info
(
"["
.
NextcloudUserRepository
::
class
.
"] fetched "
.
count
(
$ncUsers
)
.
" NC users"
);
foreach
(
$ncUsers
as
$ncUser
)
{
$scimUser
=
$this
->
adapter
->
getCoreUser
(
$ncUser
);
$scimUsers
[]
=
$scimUser
;
}
$this
->
logger
->
info
(
"["
.
NextcloudUserRepository
::
class
.
"] transformed "
.
count
(
$scimUsers
)
.
" SCIM users"
);
if
(
isset
(
$filter
)
&&
!
empty
(
$filter
))
{
$scimUsersToFilter
=
[];
foreach
(
$scimUsers
as
$scimUser
)
{
$scimUsersToFilter
[]
=
$scimUser
->
toSCIM
(
false
);
}
$filteredScimData
=
FilterUtil
::
performFiltering
(
$filter
,
$scimUsersToFilter
);
$scimUsers
=
[];
foreach
(
$filteredScimData
as
$filteredScimUser
)
{
$scimUser
=
new
CoreUser
();
$scimUser
->
fromSCIM
(
$filteredScimUser
);
$scimUsers
[]
=
$scimUser
;
}
return
$scimUsers
;
}
return
$scimUsers
;
}
/**
* Read a single user by ID in SCIM format
*/
public
function
getOneById
(
string
$id
,
$filter
=
''
,
$startIndex
=
0
,
$count
=
0
,
$attributes
=
[],
$excludedAttributes
=
[]
):
?CoreUser
{
$this
->
logger
->
info
(
"["
.
NextcloudUserRepository
::
class
.
"] reading user with ID: "
.
$id
);
$ncUser
=
$this
->
dataAccess
->
getOneById
(
$id
);
$scimUser
=
$this
->
adapter
->
getCoreUser
(
$ncUser
);
if
(
isset
(
$filter
)
&&
!
empty
(
$filter
))
{
$scimUsersToFilter
=
array
(
$scimUser
->
toSCIM
(
false
));
$filteredScimData
=
FilterUtil
::
performFiltering
(
$filter
,
$scimUsersToFilter
);
if
(
!
empty
(
$filteredScimData
))
{
$scimUser
=
new
CoreUser
();
$scimUser
->
fromSCIM
(
$filteredScimData
[
0
]);
return
$scimUser
;
}
}
return
$scimUser
;
}
/**
* Create a user from SCIM data
*/
public
function
create
(
$object
):
?CoreUser
{
$scimUserToCreate
=
new
CoreUser
();
$scimUserToCreate
->
fromSCIM
(
$object
);
$username
=
$scimUserToCreate
->
getUserName
();
$ncUserCreated
=
$this
->
dataAccess
->
create
(
$username
);
$this
->
logger
->
info
(
"["
.
NextcloudUserRepository
::
class
.
"] creating user with userName: "
.
$username
);
if
(
isset
(
$ncUserCreated
))
{
// Set the rest of the properties of the NC user via the adapter
$ncUserCreated
=
$this
->
adapter
->
getNCUser
(
$scimUserToCreate
,
$ncUserCreated
);
return
$this
->
adapter
->
getCoreUser
(
$ncUserCreated
);
}
$this
->
logger
->
error
(
"["
.
NextcloudUserRepository
::
class
.
"] creation of user with username: "
.
$username
.
" failed"
);
return
null
;
}
/**
* Update a user by ID from SCIM data
*/
public
function
update
(
string
$id
,
$object
):
?CoreUser
{
$this
->
logger
->
info
(
"["
.
NextcloudUserRepository
::
class
.
"] updating user with ID: "
.
$id
);
$scimUserToUpdate
=
new
CoreUser
();
$scimUserToUpdate
->
fromSCIM
(
$object
);
$ncUser
=
$this
->
dataAccess
->
getOneById
(
$id
);
if
(
isset
(
$ncUser
))
{
$ncUserToUpdate
=
$this
->
adapter
->
getNCUser
(
$scimUserToUpdate
,
$ncUser
);
$ncUserUpdated
=
$this
->
dataAccess
->
update
(
$id
,
$ncUserToUpdate
);
if
(
isset
(
$ncUserUpdated
))
{
return
$this
->
adapter
->
getCoreUser
(
$ncUserUpdated
);
}
}
$this
->
logger
->
error
(
"["
.
NextcloudUserRepository
::
class
.
"] update of user with ID: "
.
$id
.
" failed"
);
return
null
;
}
/**
* Delete a user by ID
*/
public
function
delete
(
string
$id
):
bool
{
$this
->
logger
->
info
(
"["
.
NextcloudUserRepository
::
class
.
"] deleting user with ID: "
.
$id
);
return
$this
->
dataAccess
->
delete
(
$id
);
}
}
lib/Service/GroupService.php
0 → 100644
View file @
50266601
<?php
declare
(
strict_types
=
1
);
namespace
OCA\SCIMServiceProvider\Service
;
use
Exception
;
use
OCA\SCIMServiceProvider\Responses\SCIMErrorResponse
;
use
OCA\SCIMServiceProvider\Responses\SCIMJSONResponse
;
use
OCA\SCIMServiceProvider\Responses\SCIMListResponse
;
use
OCA\SCIMServiceProvider\Util\Util
;
use
OCP\AppFramework\Http\Response
;
use
OCP\IGroupManager
;
use
OCP\IRequest
;
use
Psr\Container\ContainerInterface
;
use
Psr\Log\LoggerInterface
;
class
GroupService
{
/** @var LoggerInterface */
private
$logger
;
/** @var \OCA\SCIMServiceProvider\Repositories\Groups\NextcloudGroupRepository */
private
$repository
;
/** @var IGroupManager */
private
$groupManager
;
/** @var IRequest */
private
$request
;
public
function
__construct
(
ContainerInterface
$container
)
{
$this
->
logger
=
$container
->
get
(
LoggerInterface
::
class
);
$this
->
repository
=
$container
->
get
(
'GroupRepository'
);
$this
->
groupManager
=
$container
->
get
(
IGroupManager
::
class
);
$this
->
request
=
$container
->
get
(
IRequest
::
class
);
}
public
function
getAll
(
string
$filter
=
''
):
SCIMListResponse
{
$this
->
logger
->
info
(
"Reading all groups"
);
$baseUrl
=
$this
->
request
->
getServerProtocol
()
.
"://"
.
$this
->
request
->
getServerHost
()
.
Util
::
SCIM_APP_URL_PATH
;
$groups
=
$this
->
repository
->
getAll
(
$filter
);
$scimGroups
=
[];
if
(
!
empty
(
$groups
))
{
foreach
(
$groups
as
$group
)
{
$scimGroups
[]
=
$group
->
toSCIM
(
false
,
$baseUrl
);
}
}
return
new
SCIMListResponse
(
$scimGroups
);
}
public
function
getOneById
(
string
$id
):
SCIMJSONResponse
{
$this
->
logger
->
info
(
"Reading group with ID: "
.
$id
);
$baseUrl
=
$this
->
request
->
getServerProtocol
()
.
"://"
.
$this
->
request
->
getServerHost
()
.
Util
::
SCIM_APP_URL_PATH
;
$group
=
$this
->
repository
->
getOneById
(
$id
);
if
(
!
isset
(
$group
)
||
empty
(
$group
))
{
$this
->
logger
->
error
(
"Group with ID "
.
$id
.
" not found"
);
return
new
SCIMErrorResponse
([
'message'
=>
'Group not found'
],
404
);
}
return
new
SCIMJSONResponse
(
$group
->
toSCIM
(
false
,
$baseUrl
));
}
public
function
create
(
string
$displayName
=
''
,
array
$members
=
[]):
SCIMJSONResponse
{
$id
=
urlencode
(
$displayName
);
// Validate name
if
(
empty
(
$id
))
{
$this
->
logger
->
error
(
'Group name not supplied'
,
[
'app'
=>
'provisioning_api'
]);
return
new
SCIMErrorResponse
([
'message'
=>
'Invalid group name'
],
400
);
}
// Check if it exists
if
(
$this
->
groupManager
->
groupExists
(
$id
))
{
$this
->
logger
->
error
(
"Group to be created already exists"
);
return
new
SCIMErrorResponse
([
'message'
=>
'Group exists'
],
409
);
}
try
{
$this
->
logger
->
info
(
"Creating group with displayName: "
.
$displayName
);
$baseUrl
=
$this
->
request
->
getServerProtocol
()
.
"://"
.
$this
->
request
->
getServerHost
()
.
Util
::
SCIM_APP_URL_PATH
;
$data
=
[
'displayName'
=>
$displayName
,
'members'
=>
$members
];
$createdGroup
=
$this
->
repository
->
create
(
$data
);
if
(
isset
(
$createdGroup
)
&&
!
empty
(
$createdGroup
))
{
return
new
SCIMJSONResponse
(
$createdGroup
->
toSCIM
(
false
,
$baseUrl
),
201
);
}
else
{
$this
->
logger
->
error
(
"Creating group failed"
);
return
new
SCIMErrorResponse
([
'message'
=>
'Creating group failed'
],
400
);
}
}
catch
(
Exception
$e
)
{
$this
->
logger
->
warning
(
'Failed createGroup attempt with SCIMException exception.'
,
[
'app'
=>
'SCIMServiceProvider'
]);
throw
$e
;
}
}
public
function
update
(
string
$id
,
string
$displayName
=
''
,
array
$members
=
[]):
SCIMJSONResponse
{
$this
->
logger
->
info
(
"Updating group with ID: "
.
$id
);
$baseUrl
=
$this
->
request
->
getServerProtocol
()
.
"://"
.
$this
->
request
->
getServerHost
()
.
Util
::
SCIM_APP_URL_PATH
;
$group
=
$this
->
repository
->
getOneById
(
$id
);
if
(
!
isset
(
$group
)
||
empty
(
$group
))
{
$this
->
logger
->
error
(
"Group with ID "
.
$id
.
" not found for update"
);
return
new
SCIMErrorResponse
([
'message'
=>
'Group not found'
],
404
);
}
$data
=
[
'displayName'
=>
$displayName
,
'members'
=>
$members
];
$updatedGroup
=
$this
->
repository
->
update
(
$id
,
$data
);
if
(
isset
(
$updatedGroup
)
&&
!
empty
(
$updatedGroup
))
{
return
new
SCIMJSONResponse
(
$updatedGroup
->
toSCIM
(
false
,
$baseUrl
));
}
else
{
$this
->
logger
->
error
(
"Updating group with ID "
.
$id
.
" failed"
);
return
new
SCIMErrorResponse
([
'message'
=>
'Updating group failed'
],
400
);
}
}
public
function
destroy
(
string
$id
):
Response
{
$this
->
logger
->
info
(
"Deleting group with ID: "
.
$id
);
if
(
$id
===
'admin'
)
{
// Cannot delete admin group
$this
->
logger
->
error
(
"Deleting admin group is not allowed"
);
return
new
SCIMErrorResponse
([
'message'
=>
'Can\'t delete admin group'
],
403
);
}
$deleteRes
=
$this
->
repository
->
delete
(
$id
);
if
(
$deleteRes
)
{
$response
=
new
Response
();
$response
->
setStatus
(
204
);
return
$response
;
}
else
{
$this
->
logger
->
error
(
"Deletion of group with ID "
.
$id
.
" failed"
);
return
new
SCIMErrorResponse
([
'message'
=>
'Couldn\'t delete group'
],
503
);
}
}
}
lib/Service/UserService.php
0 → 100644
View file @
50266601
<?php
declare
(
strict_types
=
1
);
namespace
OCA\SCIMServiceProvider\Service
;
use
Exception
;
use
OCA\SCIMServiceProvider\Responses\SCIMErrorResponse
;
use
OCA\SCIMServiceProvider\Responses\SCIMJSONResponse
;
use
OCA\SCIMServiceProvider\Responses\SCIMListResponse
;
use
OCA\SCIMServiceProvider\Util\Util
;
use
OCP\AppFramework\Http\Response
;
use
OCP\IRequest
;
use
Psr\Container\ContainerInterface
;
use
Psr\Log\LoggerInterface
;
class
UserService
{
/** @var LoggerInterface */
private
$logger
;
/** @var \OCA\SCIMServiceProvider\Repositories\Users\NextcloudUserRepository */
private
$repository
;
/** @var IRequest */
private
$request
;
public
function
__construct
(
ContainerInterface
$container
)
{
$this
->
logger
=
$container
->
get
(
LoggerInterface
::
class
);
$this
->
repository
=
$container
->
get
(
'UserRepository'
);
$this
->
request
=
$container
->
get
(
IRequest
::
class
);
}
public
function
getAll
(
string
$filter
=
''
):
SCIMListResponse
{
$this
->
logger
->
info
(
"Reading all users"
);
$baseUrl
=
$this
->
request
->
getServerProtocol
()
.
"://"
.
$this
->
request
->
getServerHost
()
.
Util
::
SCIM_APP_URL_PATH
;
$users
=
$this
->
repository
->
getAll
(
$filter
);
$scimUsers
=
[];
if
(
!
empty
(
$users
))
{
foreach
(
$users
as
$user
)
{
$scimUsers
[]
=
$user
->
toSCIM
(
false
,
$baseUrl
);
}
}
return
new
SCIMListResponse
(
$scimUsers
);
}
public
function
getOneById
(
string
$id
):
SCIMJSONResponse
{
$this
->
logger
->
info
(
"Reading user with ID: "
.
$id
);
$baseUrl
=
$this
->
request
->
getServerProtocol
()
.
"://"
.
$this
->
request
->
getServerHost
()
.
Util
::
SCIM_APP_URL_PATH
;
$user
=
$this
->
repository
->
getOneById
(
$id
);
if
(
!
isset
(
$user
)
||
empty
(
$user
))
{
$this
->
logger
->
error
(
"User with ID "
.
$id
.
" not found"
);
return
new
SCIMErrorResponse
([
'message'
=>
'User not found'
],
404
);
}
return
new
SCIMJSONResponse
(
$user
->
toSCIM
(
false
,
$baseUrl
));
}
public
function
create
(
bool
$active
=
true
,
string
$displayName
=
''
,
array
$emails
=
[],
string
$externalId
=
''
,
string
$userName
=
''
):
SCIMJSONResponse
{
try
{
$this
->
logger
->
info
(
"Creating user with userName: "
.
$userName
);
$baseUrl
=
$this
->
request
->
getServerProtocol
()
.
"://"
.
$this
->
request
->
getServerHost
()
.
Util
::
SCIM_APP_URL_PATH
;
$data
=
[
'active'
=>
$active
,
'displayName'
=>
$displayName
,
'emails'
=>
$emails
,
'externalId'
=>
$externalId
,
'userName'
=>
$userName
];
$createdUser
=
$this
->
repository
->
create
(
$data
);
if
(
isset
(
$createdUser
)
&&
!
empty
(
$createdUser
))
{
return
new
SCIMJSONResponse
(
$createdUser
->
toSCIM
(
false
,
$baseUrl
),
201
);
}
else
{
$this
->
logger
->
error
(
"Creating user failed"
);
return
new
SCIMErrorResponse
([
'message'
=>
'Creating user failed'
],
400
);
}
}
catch
(
Exception
$e
)
{
$this
->
logger
->
warning
(
'Failed createUser attempt with SCIMException exeption.'
,
[
'app'
=>
'SCIMServiceProvider'
]);
throw
$e
;
}
}
public
function
update
(
string
$id
,
bool
$active
,
string
$displayName
=
''
,
array
$emails
=
[]
):
SCIMJSONResponse
{
$this
->
logger
->
info
(
"Updating user with ID: "
.
$id
);
$baseUrl
=
$this
->
request
->
getServerProtocol
()
.
"://"
.
$this
->
request
->
getServerHost
()
.
Util
::
SCIM_APP_URL_PATH
;
$user
=
$this
->
repository
->
getOneById
(
$id
);
if
(
!
isset
(
$user
)
||
empty
(
$user
))
{
$this
->
logger
->
error
(
"User with ID "
.
$id
.
" not found for update"
);
return
new
SCIMErrorResponse
([
'message'
=>
'User not found'
],
404
);
}
$data
=
[
'active'
=>
$active
,
'displayName'
=>
$displayName
,
'emails'
=>
$emails
];
$updatedUser
=
$this
->
repository
->
update
(
$id
,
$data
);
if
(
isset
(
$updatedUser
)
&&
!
empty
(
$updatedUser
))
{
return
new
SCIMJSONResponse
(
$updatedUser
->
toSCIM
(
false
,
$baseUrl
));
}
else
{
$this
->
logger
->
error
(
"Updating user with ID "
.
$id
.
" failed"
);
return
new
SCIMErrorResponse
([
'message'
=>
'Updating user failed'
],
400
);
}
}
public
function
destroy
(
string
$id
):
Response
{
$this
->
logger
->
info
(
"Deleting user with ID: "
.
$id
);
$deleteRes
=
$this
->
repository
->
delete
(
$id
);
if
(
$deleteRes
)
{
$response
=
new
Response
();
$response
->
setStatus
(
204
);
return
$response
;
}
else
{
$this
->
logger
->
error
(
"Deletion of user with ID "
.
$id
.
" failed"
);
return
new
SCIMErrorResponse
([
'message'
=>
'Couldn\'t delete user'
],
503
);
}
}
}
lib/Util/Authentication/BearerAuthenticator.php
0 → 100644
View file @
50266601
<?php
namespace
OCA\SCIMServiceProvider\Util\Authentication
;
use
Exception
;
use
Opf\ScimServerPhp\Firebase\JWT\JWT
;
use
Opf\ScimServerPhp\Firebase\JWT\Key
;
use
OCA\SCIMServiceProvider\Util\Util
;
use
OCP\IUserManager
;
use
Opf\Util\Authentication\AuthenticatorInterface
;
use
Psr\Container\ContainerInterface
;
use
Psr\Log\LoggerInterface
;
class
BearerAuthenticator
implements
AuthenticatorInterface
{
/** @var \Psr\Log\LoggerInterface */
private
LoggerInterface
$logger
;
/** @var \OCP\IUserManager */
private
IUserManager
$userManager
;
public
function
__construct
(
ContainerInterface
$container
)
{
$this
->
logger
=
$container
->
get
(
LoggerInterface
::
class
);
$this
->
userManager
=
$container
->
get
(
IUserManager
::
class
);
}
public
function
authenticate
(
string
$credentials
,
array
$authorizationInfo
):
bool
{
$jwtPayload
=
[];
$jwtSecret
=
Util
::
getConfigFile
()[
'jwt'
][
'secret'
];
try
{
$jwtPayload
=
(
array
)
JWT
::
decode
(
$credentials
,
new
Key
(
$jwtSecret
,
'HS256'
));
}
catch
(
Exception
$e
)
{
$this
->
logger
->
error
(
$e
->
getMessage
());
return
false
;
}
// If the 'user' claim is missing from the JWT, then auth is considered to have failed
if
(
!
isset
(
$jwtPayload
[
'user'
])
||
empty
(
$jwtPayload
[
'user'
]))
{
$this
->
logger
->
error
(
"No
\"
user
\"
claim found in JWT"
);
return
false
;
}
$username
=
$jwtPayload
[
'user'
];
// If we managed to find a user with that username, then auth succeeded
$user
=
$this
->
userManager
->
get
(
$username
);
if
(
$user
!==
null
)
{
return
true
;
}
$this
->
logger
->
error
(
"User with this username doesn't exist"
);
return
false
;
}
}
lib/Util/Util.php
0 → 100644
View file @
50266601
<?php
namespace
OCA\SCIMServiceProvider\Util
;
class
Util
{
public
const
SCIM_APP_URL_PATH
=
"index.php/apps/scimserviceprovider"
;
public
static
function
getConfigFile
()
{
$configFilePath
=
dirname
(
__DIR__
)
.
'/Config/config.php'
;
$config
=
require
(
$configFilePath
);
return
$config
;
}
}
tests/postman/api_tests.postman_collection.json
0 → 100644
View file @
50266601
{
"info"
:
{
"_postman_id"
:
"65bcae79-ee78-4eb8-92cc-f23f21913bb9"
,
"name"
:
"SCIM Nextcloud App Collection"
,
"schema"
:
"https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item"
:
[
{
"name"
:
"Groups"
,
"item"
:
[
{
"name"
:
"Create a single group"
,
"event"
:
[
{
"listen"
:
"test"
,
"script"
:
{
"exec"
:
[
"pm.test(
\"
Response status code is 201
\"
, () => {"
,
" pm.response.to.have.status(201);"
,
"});"
,
""
,
"pm.test(
\"
Response body is not empty
\"
, () => {"
,
" pm.expect(pm.response.json()).to.not.be.empty;"
,
"});"
,
""
,
"pm.test(
\"
Response body contains group with displayName
\\\"
createdtestgroup
\\\"\"
, () => {"
,
" pm.expect(pm.response.json().displayName).to.eql(
\"
createdtestgroup
\"
);"
,
"});"
,
""
,
"pm.test(
\"
Response body contains a valid non-null group ID (the ID of the group which was created)
\"
, () => {"
,
" pm.expect(pm.response.json().id).to.not.be.null;"
,
"});"
,
""
,
"pm.collectionVariables.set(
\"
testGroupId
\"
, pm.response.json().id);"
],
"type"
:
"text/javascript"
}
}
],
"request"
:
{
"method"
:
"POST"
,
"header"
:
[
{
"key"
:
"Content-Type"
,
"value"
:
"application/json"
,
"type"
:
"default"
}
],
"body"
:
{
"mode"
:
"raw"
,
"raw"
:
"{
\n
\"
displayName
\"
:
\"
createdtestgroup
\"
,
\n
\"
members
\"
: []
\n
}"
,
"options"
:
{
"raw"
:
{
"language"
:
"json"
}
}
},
"url"
:
{
"raw"
:
"{{url}}/Groups"
,
"host"
:
[
"{{url}}"
],
"path"
:
[
"Groups"
]
}
},
"response"
:
[]
},
{
"name"
:
"Read a single group"
,
"event"
:
[
{
"listen"
:
"test"
,
"script"
:
{
"exec"
:
[
"pm.test(
\"
Response status code is 200
\"
, () => {"
,
" pm.response.to.have.status(200);"
,
"});"
,
""
,
"pm.test(
\"
Response body is not empty
\"
, () => {"
,
" pm.expect(pm.response.json()).to.not.be.empty;"
,
"});"
,
""
,
"pm.test(
\"
Response body contains the group ID of the group we want to read
\"
, () => {"
,
" pm.expect(pm.response.json().id).to.eql(pm.collectionVariables.get('testGroupId'));"
,
"});"
,
""
,
"pm.test(
\"
Response body contains group with displayName
\\\"
createdtestgroup
\\\"\"
, () => {"
,
" pm.expect(pm.response.json().displayName).to.eql(
\"
createdtestgroup
\"
);"
,
"});"
],
"type"
:
"text/javascript"
}
}
],
"request"
:
{
"method"
:
"GET"
,
"header"
:
[],
"url"
:
{
"raw"
:
"{{url}}/Groups/{{testGroupId}}"
,
"host"
:
[
"{{url}}"
],
"path"
:
[
"Groups"
,
"{{testGroupId}}"
]
}
},
"response"
:
[]
},
{
"name"
:
"Read all groups"
,
"event"
:
[
{
"listen"
:
"test"
,
"script"
:
{
"exec"
:
[
"pm.test(
\"
Response status code is 200
\"
, () => {"
,
" pm.response.to.have.status(200);"
,
"});"
,
""
,
"pm.test(
\"
Response body is not empty
\"
, () => {"
,
" pm.expect(pm.response.json().Resources).to.not.be.empty;"
,
"});"
,
""
,
"pm.test(
\"
Response body contains group with displayName
\\\"
createdtestgroup
\\\"\"
, () => {"
,
" var resources = pm.response.json().Resources.map(x => x.displayName);"
,
" pm.expect(resources).to.contain(
\"
createdtestgroup
\"
);"
,
"});"
],
"type"
:
"text/javascript"
}
}
],
"request"
:
{
"method"
:
"GET"
,
"header"
:
[],
"url"
:
{
"raw"
:
"{{url}}/Groups"
,
"host"
:
[
"{{url}}"
],
"path"
:
[
"Groups"
]
}
},
"response"
:
[]
},
{
"name"
:
"Update a single group"
,
"event"
:
[
{
"listen"
:
"test"
,
"script"
:
{
"exec"
:
[
"pm.test(
\"
Response status code is 200
\"
, () => {"
,
" pm.response.to.have.status(200);"
,
"});"
,
""
,
"pm.test(
\"
Response body is not empty
\"
, () => {"
,
" pm.expect(pm.response.json()).to.not.be.empty;"
,
"});"
,
""
,
"pm.test(
\"
Response body contains the group ID of the group we want to read
\"
, () => {"
,
" pm.expect(pm.response.json().id).to.eql(pm.collectionVariables.get('testGroupId'));"
,
"});"
,
""
,
"pm.test(
\"
Response body contains group with displayName
\\\"
updatedtestgroup
\\\"\"
, () => {"
,
" pm.expect(pm.response.json().displayName).to.eql(
\"
updatedtestgroup
\"
);"
,
"});"
],
"type"
:
"text/javascript"
}
}
],
"request"
:
{
"method"
:
"PUT"
,
"header"
:
[],
"body"
:
{
"mode"
:
"raw"
,
"raw"
:
"{
\n
\"
displayName
\"
:
\"
updatedtestgroup
\"
,
\n
\"
members
\"
: []
\n
}"
,
"options"
:
{
"raw"
:
{
"language"
:
"json"
}
}
},
"url"
:
{
"raw"
:
"{{url}}/Groups/{{testGroupId}}"
,
"host"
:
[
"{{url}}"
],
"path"
:
[
"Groups"
,
"{{testGroupId}}"
]
}
},
"response"
:
[]
},
{
"name"
:
"Delete a single group"
,
"event"
:
[
{
"listen"
:
"test"
,
"script"
:
{
"exec"
:
[
"pm.test(
\"
Response status code is 204
\"
, () => {"
,
" pm.response.to.have.status(204);"
,
"});"
],
"type"
:
"text/javascript"
}
}
],
"request"
:
{
"method"
:
"DELETE"
,
"header"
:
[],
"url"
:
{
"raw"
:
"{{url}}/Groups/{{testGroupId}}"
,
"host"
:
[
"{{url}}"
],
"path"
:
[
"Groups"
,
"{{testGroupId}}"
]
}
},
"response"
:
[]
}
],
"auth"
:
{
"type"
:
"basic"
,
"basic"
:
[
{
"key"
:
"password"
,
"value"
:
"admin"
,
"type"
:
"string"
},
{
"key"
:
"username"
,
"value"
:
"admin"
,
"type"
:
"string"
}
]
},
"event"
:
[
{
"listen"
:
"prerequest"
,
"script"
:
{
"type"
:
"text/javascript"
,
"exec"
:
[
""
]
}
},
{
"listen"
:
"test"
,
"script"
:
{
"type"
:
"text/javascript"
,
"exec"
:
[
""
]
}
}
]
},
{
"name"
:
"ResourceTypes"
,
"item"
:
[
{
"name"
:
"Read all ResourceTypes"
,
"event"
:
[
{
"listen"
:
"test"
,
"script"
:
{
"exec"
:
[
"pm.test(
\"
Response status code is 200
\"
, () => {"
,
" pm.response.to.have.status(200);"
,
"});"
,
""
,
"pm.test(
\"
Response body is not empty
\"
, () => {"
,
" pm.expect(pm.response.json().Resources).to.not.be.empty;"
,
"});"
,
""
,
"pm.test(
\"
Response body contains exactly one entry
\"
, () => {"
,
" pm.expect(pm.response.json().Resources.length).to.eql(2);"
,
"});"
,
""
,
"pm.test(
\"
Response body contains ResourceType with id
\\\"
User
\\\"\"
, () => {"
,
" pm.expect(pm.response.json().Resources[0].id).to.eql(
\"
User
\"
);"
,
"});"
,
""
,
"pm.test(
\"
Response body contains ResourceType with id
\\\"
Group
\\\"\"
, () => {"
,
" pm.expect(pm.response.json().Resources[1].id).to.eql(
\"
Group
\"
);"
,
"});"
],
"type"
:
"text/javascript"
}
}
],
"request"
:
{
"method"
:
"GET"
,
"header"
:
[
{
"key"
:
"Authorization"
,
"value"
:
"Bearer: {{jwt_token}}"
,
"type"
:
"default"
}
],
"url"
:
{
"raw"
:
"{{url}}/ResourceTypes"
,
"host"
:
[
"{{url}}"
],
"path"
:
[
"ResourceTypes"
]
}
},
"response"
:
[]
}
]
},
{
"name"
:
"Schemas"
,
"item"
:
[
{
"name"
:
"Read all Schemas"
,
"event"
:
[
{
"listen"
:
"test"
,
"script"
:
{
"exec"
:
[
"pm.test(
\"
Response status code is 200
\"
, () => {"
,
" pm.response.to.have.status(200);"
,
"});"
,
""
,
"pm.test(
\"
Response body is not empty
\"
, () => {"
,
" pm.expect(pm.response.json().Resources).to.not.be.empty;"
,
"});"
,
""
,
"pm.test(
\"
Response body contains exactly four entries
\"
, () => {"
,
" pm.expect(pm.response.json().Resources.length).to.eql(4);"
,
"});"
,
""
,
"pm.test(
\"
Response body contains Schema with id
\\\"
urn:ietf:params:scim:schemas:core:2.0:Group
\\\"\"
, () => {"
,
" pm.expect(pm.response.json().Resources[0].id).to.eql(
\"
urn:ietf:params:scim:schemas:core:2.0:Group
\"
);"
,
"});"
,
""
,
"pm.test(
\"
Response body contains Schema with id
\\\"
urn:ietf:params:scim:schemas:core:2.0:ResourceType
\\\"\"
, () => {"
,
" pm.expect(pm.response.json().Resources[1].id).to.eql(
\"
urn:ietf:params:scim:schemas:core:2.0:ResourceType
\"
);"
,
"});"
,
""
,
"pm.test(
\"
Response body contains Schema with id
\\\"
urn:ietf:params:scim:schemas:core:2.0:User
\\\"\"
, () => {"
,
" pm.expect(pm.response.json().Resources[2].id).to.eql(
\"
urn:ietf:params:scim:schemas:core:2.0:User
\"
);"
,
"});"
,
""
,
"pm.test(
\"
Response body contains Schema with id
\\\"
urn:ietf:params:scim:schemas:core:2.0:Schema
\\\"\"
, () => {"
,
" pm.expect(pm.response.json().Resources[3].id).to.eql(
\"
urn:ietf:params:scim:schemas:core:2.0:Schema
\"
);"
,
"});"
],
"type"
:
"text/javascript"
}
}
],
"request"
:
{
"method"
:
"GET"
,
"header"
:
[
{
"key"
:
"Authorization"
,
"value"
:
"Bearer: {{jwt_token}}"
,
"type"
:
"default"
}
],
"url"
:
{
"raw"
:
"{{url}}/Schemas"
,
"host"
:
[
"{{url}}"
],
"path"
:
[
"Schemas"
]
}
},
"response"
:
[]
}
]
},
{
"name"
:
"ServiceProviderConfigs"
,
"item"
:
[
{
"name"
:
"Read all ServiceProviderConfigs"
,
"event"
:
[
{
"listen"
:
"test"
,
"script"
:
{
"exec"
:
[
"pm.test(
\"
Response status code is 200
\"
, () => {"
,
" pm.response.to.have.status(200);"
,
"});"
,
""
,
"pm.test(
\"
Response body is not empty
\"
, () => {"
,
" pm.expect(pm.response.json()).to.not.be.empty;"
,
"});"
,
""
,
"pm.test(
\"
Response body contains a ServiceProviderConfig with a correct schema
\"
, () => {"
,
" pm.expect(pm.response.json().schemas).to.include(
\"
urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig
\"
);"
,
"});"
],
"type"
:
"text/javascript"
}
}
],
"request"
:
{
"method"
:
"GET"
,
"header"
:
[
{
"key"
:
"Authorization"
,
"value"
:
"Bearer: {{jwt_token}}"
,
"type"
:
"default"
}
],
"url"
:
{
"raw"
:
"{{url}}/ServiceProviderConfig"
,
"host"
:
[
"{{url}}"
],
"path"
:
[
"ServiceProviderConfig"
]
}
},
"response"
:
[]
}
]
},
{
"name"
:
"Users"
,
"item"
:
[
{
"name"
:
"Create a single user"
,
"event"
:
[
{
"listen"
:
"test"
,
"script"
:
{
"exec"
:
[
"pm.test(
\"
Response status code is 201
\"
, () => {"
,
" pm.response.to.have.status(201);"
,
"});"
,
""
,
"pm.test(
\"
Response body is not empty
\"
, () => {"
,
" pm.expect(pm.response.json()).to.not.be.empty;"
,
"});"
,
""
,
"pm.test(
\"
Response body contains user with userName
\\\"
createdtestuser
\\\"\"
, () => {"
,
" pm.expect(pm.response.json().userName).to.eql(
\"
createdtestuser
\"
);"
,
"});"
,
""
,
"pm.test(
\"
Response body contains a valid non-null user ID (the ID of the user which was created)
\"
, () => {"
,
" pm.expect(pm.response.json().id).to.not.be.null;"
,
"});"
,
""
,
"pm.collectionVariables.set(
\"
testUserId
\"
, pm.response.json().id);"
],
"type"
:
"text/javascript"
}
}
],
"request"
:
{
"method"
:
"POST"
,
"header"
:
[
{
"key"
:
"Content-Type"
,
"value"
:
"application/json"
,
"type"
:
"default"
}
],
"body"
:
{
"mode"
:
"raw"
,
"raw"
:
"{
\n
\"
userName
\"
:
\"
createdtestuser
\"\n
}"
,
"options"
:
{
"raw"
:
{
"language"
:
"json"
}
}
},
"url"
:
{
"raw"
:
"{{url}}/Users"
,
"host"
:
[
"{{url}}"
],
"path"
:
[
"Users"
]
}
},
"response"
:
[]
},
{
"name"
:
"Read a single user"
,
"event"
:
[
{
"listen"
:
"test"
,
"script"
:
{
"exec"
:
[
"pm.test(
\"
Response status code is 200
\"
, () => {"
,
" pm.response.to.have.status(200);"
,
"});"
,
""
,
"pm.test(
\"
Response body is not empty
\"
, () => {"
,
" pm.expect(pm.response.json()).to.not.be.empty;"
,
"});"
,
""
,
"pm.test(
\"
Response body contains the user ID of the user we want to read
\"
, () => {"
,
" pm.expect(pm.response.json().id).to.eql(pm.collectionVariables.get('testUserId'));"
,
"});"
,
""
,
"pm.test(
\"
Response body contains user with userName
\\\"
createdtestuser
\\\"\"
, () => {"
,
" pm.expect(pm.response.json().userName).to.eql(
\"
createdtestuser
\"
);"
,
"});"
],
"type"
:
"text/javascript"
}
}
],
"request"
:
{
"method"
:
"GET"
,
"header"
:
[],
"url"
:
{
"raw"
:
"{{url}}/Users/{{testUserId}}"
,
"host"
:
[
"{{url}}"
],
"path"
:
[
"Users"
,
"{{testUserId}}"
]
}
},
"response"
:
[]
},
{
"name"
:
"Read all users"
,
"event"
:
[
{
"listen"
:
"test"
,
"script"
:
{
"exec"
:
[
"pm.test(
\"
Response status code is 200
\"
, () => {"
,
" pm.response.to.have.status(200);"
,
"});"
,
""
,
"pm.test(
\"
Response body is not empty
\"
, () => {"
,
" pm.expect(pm.response.json().Resources).to.not.be.empty;"
,
"});"
,
""
,
"pm.test(
\"
Response body contains user with userName
\\\"
createdtestuser
\\\"\"
, () => {"
,
" var resources = pm.response.json().Resources.map(x => x.userName);"
,
" pm.expect(resources).to.contain(
\"
createdtestuser
\"
);"
,
"});"
],
"type"
:
"text/javascript"
}
}
],
"request"
:
{
"method"
:
"GET"
,
"header"
:
[],
"url"
:
{
"raw"
:
"{{url}}/Users"
,
"host"
:
[
"{{url}}"
],
"path"
:
[
"Users"
]
}
},
"response"
:
[]
},
{
"name"
:
"Update a single user"
,
"event"
:
[
{
"listen"
:
"test"
,
"script"
:
{
"exec"
:
[
"pm.test(
\"
Response status code is 200
\"
, () => {"
,
" pm.response.to.have.status(200);"
,
"});"
,
""
,
"pm.test(
\"
Response body is not empty
\"
, () => {"
,
" pm.expect(pm.response.json()).to.not.be.empty;"
,
"});"
,
""
,
"pm.test(
\"
Response body contains the user ID of the user we want to read
\"
, () => {"
,
" pm.expect(pm.response.json().id).to.eql(pm.collectionVariables.get('testUserId'));"
,
"});"
,
""
,
"pm.test(
\"
Response body contains user with displayName
\\\"
updatedtestuser
\\\"\"
, () => {"
,
" pm.expect(pm.response.json().displayName).to.eql(
\"
updatedtestuser
\"
);"
,
"});"
],
"type"
:
"text/javascript"
}
}
],
"request"
:
{
"method"
:
"PUT"
,
"header"
:
[
{
"key"
:
"Content-Type"
,
"value"
:
"application/json"
,
"type"
:
"default"
}
],
"body"
:
{
"mode"
:
"raw"
,
"raw"
:
"{
\n
\"
displayName
\"
:
\"
updatedtestuser
\"
,
\n
\"
active
\"
: false
\n
}"
,
"options"
:
{
"raw"
:
{
"language"
:
"json"
}
}
},
"url"
:
{
"raw"
:
"{{url}}/Users/{{testUserId}}"
,
"host"
:
[
"{{url}}"
],
"path"
:
[
"Users"
,
"{{testUserId}}"
]
}
},
"response"
:
[]
},
{
"name"
:
"Delete a single user"
,
"event"
:
[
{
"listen"
:
"test"
,
"script"
:
{
"exec"
:
[
"pm.test(
\"
Response status code is 204
\"
, () => {"
,
" pm.response.to.have.status(204);"
,
"});"
],
"type"
:
"text/javascript"
}
}
],
"request"
:
{
"method"
:
"DELETE"
,
"header"
:
[
{
"key"
:
"Content-Type"
,
"value"
:
"application/json"
,
"type"
:
"default"
}
],
"body"
:
{
"mode"
:
"raw"
,
"raw"
:
"{
\n
\"
userName
\"
:
\"
updatedtestuser
\"\n
}"
,
"options"
:
{
"raw"
:
{
"language"
:
"json"
}
}
},
"url"
:
{
"raw"
:
"{{url}}/Users/{{testUserId}}"
,
"host"
:
[
"{{url}}"
],
"path"
:
[
"Users"
,
"{{testUserId}}"
]
}
},
"response"
:
[]
}
],
"auth"
:
{
"type"
:
"basic"
,
"basic"
:
[
{
"key"
:
"password"
,
"value"
:
"admin"
,
"type"
:
"string"
},
{
"key"
:
"username"
,
"value"
:
"admin"
,
"type"
:
"string"
}
]
},
"event"
:
[
{
"listen"
:
"prerequest"
,
"script"
:
{
"type"
:
"text/javascript"
,
"exec"
:
[
""
]
}
},
{
"listen"
:
"test"
,
"script"
:
{
"type"
:
"text/javascript"
,
"exec"
:
[
""
]
}
}
]
}
],
"auth"
:
{
"type"
:
"basic"
,
"basic"
:
[
{
"key"
:
"password"
,
"value"
:
"admin"
,
"type"
:
"string"
},
{
"key"
:
"username"
,
"value"
:
"admin"
,
"type"
:
"string"
}
]
},
"event"
:
[
{
"listen"
:
"prerequest"
,
"script"
:
{
"type"
:
"text/javascript"
,
"exec"
:
[
""
]
}
},
{
"listen"
:
"test"
,
"script"
:
{
"type"
:
"text/javascript"
,
"exec"
:
[
""
]
}
}
],
"variable"
:
[
{
"key"
:
"testUserId"
,
"value"
:
""
},
{
"key"
:
"testGroupId"
,
"value"
:
""
},
{
"key"
:
"url"
,
"value"
:
"http://localhost:8888/index.php/apps/scimserviceprovider"
,
"type"
:
"default"
}
]
}
\ No newline at end of file
tests/postman/bearer_token_api_tests.postman_collection.json
0 → 100644
View file @
50266601
{
"info"
:
{
"_postman_id"
:
"606af599-3dec-46c8-9464-f52a7fd8f5b7"
,
"name"
:
"SCIM Nextcloud App Collection (Bearer Token)"
,
"schema"
:
"https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item"
:
[
{
"name"
:
"Users"
,
"item"
:
[
{
"name"
:
"Create a single user"
,
"event"
:
[
{
"listen"
:
"test"
,
"script"
:
{
"exec"
:
[
"pm.test(
\"
Response status code is 201
\"
, () => {"
,
" pm.response.to.have.status(201);"
,
"});"
,
""
,
"pm.test(
\"
Response body is not empty
\"
, () => {"
,
" pm.expect(pm.response.json()).to.not.be.empty;"
,
"});"
,
""
,
"pm.test(
\"
Response body contains user with userName
\\\"
createdtestuser
\\\"\"
, () => {"
,
" pm.expect(pm.response.json().userName).to.eql(
\"
createdtestuser
\"
);"
,
"});"
,
""
,
"pm.test(
\"
Response body contains a valid non-null user ID (the ID of the user which was created)
\"
, () => {"
,
" pm.expect(pm.response.json().id).to.not.be.null;"
,
"});"
,
""
,
"pm.collectionVariables.set(
\"
testUserId
\"
, pm.response.json().id);"
],
"type"
:
"text/javascript"
}
}
],
"request"
:
{
"method"
:
"POST"
,
"header"
:
[
{
"key"
:
"Content-Type"
,
"value"
:
"application/json"
,
"type"
:
"default"
}
],
"body"
:
{
"mode"
:
"raw"
,
"raw"
:
"{
\n
\"
userName
\"
:
\"
createdtestuser
\"\n
}"
,
"options"
:
{
"raw"
:
{
"language"
:
"json"
}
}
},
"url"
:
{
"raw"
:
"{{url}}/bearer/Users"
,
"host"
:
[
"{{url}}"
],
"path"
:
[
"bearer"
,
"Users"
]
}
},
"response"
:
[]
},
{
"name"
:
"Read a single user"
,
"event"
:
[
{
"listen"
:
"test"
,
"script"
:
{
"exec"
:
[
"pm.test(
\"
Response status code is 200
\"
, () => {"
,
" pm.response.to.have.status(200);"
,
"});"
,
""
,
"pm.test(
\"
Response body is not empty
\"
, () => {"
,
" pm.expect(pm.response.json()).to.not.be.empty;"
,
"});"
,
""
,
"pm.test(
\"
Response body contains the user ID of the user we want to read
\"
, () => {"
,
" pm.expect(pm.response.json().id).to.eql(pm.collectionVariables.get('testUserId'));"
,
"});"
,
""
,
"pm.test(
\"
Response body contains user with userName
\\\"
createdtestuser
\\\"\"
, () => {"
,
" pm.expect(pm.response.json().userName).to.eql(
\"
createdtestuser
\"
);"
,
"});"
],
"type"
:
"text/javascript"
}
}
],
"request"
:
{
"method"
:
"GET"
,
"header"
:
[],
"url"
:
{
"raw"
:
"{{url}}/bearer/Users/{{testUserId}}"
,
"host"
:
[
"{{url}}"
],
"path"
:
[
"bearer"
,
"Users"
,
"{{testUserId}}"
]
}
},
"response"
:
[]
},
{
"name"
:
"Read all users"
,
"event"
:
[
{
"listen"
:
"test"
,
"script"
:
{
"exec"
:
[
"pm.test(
\"
Response status code is 200
\"
, () => {"
,
" pm.response.to.have.status(200);"
,
"});"
,
""
,
"pm.test(
\"
Response body is not empty
\"
, () => {"
,
" pm.expect(pm.response.json().Resources).to.not.be.empty;"
,
"});"
,
""
,
"pm.test(
\"
Response body contains user with userName
\\\"
createdtestuser
\\\"\"
, () => {"
,
" var resources = pm.response.json().Resources.map(x => x.userName);"
,
" pm.expect(resources).to.contain(
\"
createdtestuser
\"
);"
,
"});"
],
"type"
:
"text/javascript"
}
}
],
"request"
:
{
"method"
:
"GET"
,
"header"
:
[],
"url"
:
{
"raw"
:
"{{url}}/bearer/Users"
,
"host"
:
[
"{{url}}"
],
"path"
:
[
"bearer"
,
"Users"
]
}
},
"response"
:
[]
},
{
"name"
:
"Update a single user"
,
"event"
:
[
{
"listen"
:
"test"
,
"script"
:
{
"exec"
:
[
"pm.test(
\"
Response status code is 200
\"
, () => {"
,
" pm.response.to.have.status(200);"
,
"});"
,
""
,
"pm.test(
\"
Response body is not empty
\"
, () => {"
,
" pm.expect(pm.response.json()).to.not.be.empty;"
,
"});"
,
""
,
"pm.test(
\"
Response body contains the user ID of the user we want to read
\"
, () => {"
,
" pm.expect(pm.response.json().id).to.eql(pm.collectionVariables.get('testUserId'));"
,
"});"
,
""
,
"pm.test(
\"
Response body contains user with displayName
\\\"
updatedtestuser
\\\"\"
, () => {"
,
" pm.expect(pm.response.json().displayName).to.eql(
\"
updatedtestuser
\"
);"
,
"});"
],
"type"
:
"text/javascript"
}
}
],
"request"
:
{
"method"
:
"PUT"
,
"header"
:
[
{
"key"
:
"Content-Type"
,
"value"
:
"application/json"
,
"type"
:
"default"
}
],
"body"
:
{
"mode"
:
"raw"
,
"raw"
:
"{
\n
\"
displayName
\"
:
\"
updatedtestuser
\"
,
\n
\"
active
\"
: false
\n
}"
,
"options"
:
{
"raw"
:
{
"language"
:
"json"
}
}
},
"url"
:
{
"raw"
:
"{{url}}/bearer/Users/{{testUserId}}"
,
"host"
:
[
"{{url}}"
],
"path"
:
[
"bearer"
,
"Users"
,
"{{testUserId}}"
]
}
},
"response"
:
[]
},
{
"name"
:
"Delete a single user"
,
"event"
:
[
{
"listen"
:
"test"
,
"script"
:
{
"exec"
:
[
"pm.test(
\"
Response status code is 204
\"
, () => {"
,
" pm.response.to.have.status(204);"
,
"});"
],
"type"
:
"text/javascript"
}
}
],
"request"
:
{
"method"
:
"DELETE"
,
"header"
:
[
{
"key"
:
"Content-Type"
,
"value"
:
"application/json"
,
"type"
:
"default"
}
],
"body"
:
{
"mode"
:
"raw"
,
"raw"
:
"{
\n
\"
userName
\"
:
\"
updatedtestuser
\"\n
}"
,
"options"
:
{
"raw"
:
{
"language"
:
"json"
}
}
},
"url"
:
{
"raw"
:
"{{url}}/bearer/Users/{{testUserId}}"
,
"host"
:
[
"{{url}}"
],
"path"
:
[
"bearer"
,
"Users"
,
"{{testUserId}}"
]
}
},
"response"
:
[]
}
],
"event"
:
[
{
"listen"
:
"prerequest"
,
"script"
:
{
"type"
:
"text/javascript"
,
"exec"
:
[
""
]
}
},
{
"listen"
:
"test"
,
"script"
:
{
"type"
:
"text/javascript"
,
"exec"
:
[
""
]
}
}
]
},
{
"name"
:
"Groups"
,
"item"
:
[
{
"name"
:
"Create a single group"
,
"event"
:
[
{
"listen"
:
"test"
,
"script"
:
{
"exec"
:
[
"pm.test(
\"
Response status code is 201
\"
, () => {"
,
" pm.response.to.have.status(201);"
,
"});"
,
""
,
"pm.test(
\"
Response body is not empty
\"
, () => {"
,
" pm.expect(pm.response.json()).to.not.be.empty;"
,
"});"
,
""
,
"pm.test(
\"
Response body contains group with displayName
\\\"
createdtestgroup
\\\"\"
, () => {"
,
" pm.expect(pm.response.json().displayName).to.eql(
\"
createdtestgroup
\"
);"
,
"});"
,
""
,
"pm.test(
\"
Response body contains a valid non-null group ID (the ID of the group which was created)
\"
, () => {"
,
" pm.expect(pm.response.json().id).to.not.be.null;"
,
"});"
,
""
,
"pm.collectionVariables.set(
\"
testGroupId
\"
, pm.response.json().id);"
],
"type"
:
"text/javascript"
}
}
],
"request"
:
{
"method"
:
"POST"
,
"header"
:
[
{
"key"
:
"Content-Type"
,
"value"
:
"application/json"
,
"type"
:
"default"
}
],
"body"
:
{
"mode"
:
"raw"
,
"raw"
:
"{
\n
\"
displayName
\"
:
\"
createdtestgroup
\"
,
\n
\"
members
\"
: []
\n
}"
,
"options"
:
{
"raw"
:
{
"language"
:
"json"
}
}
},
"url"
:
{
"raw"
:
"{{url}}/bearer/Groups"
,
"host"
:
[
"{{url}}"
],
"path"
:
[
"bearer"
,
"Groups"
]
}
},
"response"
:
[]
},
{
"name"
:
"Read a single group"
,
"event"
:
[
{
"listen"
:
"test"
,
"script"
:
{
"exec"
:
[
"pm.test(
\"
Response status code is 200
\"
, () => {"
,
" pm.response.to.have.status(200);"
,
"});"
,
""
,
"pm.test(
\"
Response body is not empty
\"
, () => {"
,
" pm.expect(pm.response.json()).to.not.be.empty;"
,
"});"
,
""
,
"pm.test(
\"
Response body contains the group ID of the group we want to read
\"
, () => {"
,
" pm.expect(pm.response.json().id).to.eql(pm.collectionVariables.get('testGroupId'));"
,
"});"
,
""
,
"pm.test(
\"
Response body contains group with displayName
\\\"
createdtestgroup
\\\"\"
, () => {"
,
" pm.expect(pm.response.json().displayName).to.eql(
\"
createdtestgroup
\"
);"
,
"});"
],
"type"
:
"text/javascript"
}
}
],
"request"
:
{
"method"
:
"GET"
,
"header"
:
[],
"url"
:
{
"raw"
:
"{{url}}/bearer/Groups/{{testGroupId}}"
,
"host"
:
[
"{{url}}"
],
"path"
:
[
"bearer"
,
"Groups"
,
"{{testGroupId}}"
]
}
},
"response"
:
[]
},
{
"name"
:
"Read all groups"
,
"event"
:
[
{
"listen"
:
"test"
,
"script"
:
{
"exec"
:
[
"pm.test(
\"
Response status code is 200
\"
, () => {"
,
" pm.response.to.have.status(200);"
,
"});"
,
""
,
"pm.test(
\"
Response body is not empty
\"
, () => {"
,
" pm.expect(pm.response.json().Resources).to.not.be.empty;"
,
"});"
,
""
,
"pm.test(
\"
Response body contains group with displayName
\\\"
createdtestgroup
\\\"\"
, () => {"
,
" var resources = pm.response.json().Resources.map(x => x.displayName);"
,
" pm.expect(resources).to.contain(
\"
createdtestgroup
\"
);"
,
"});"
],
"type"
:
"text/javascript"
}
}
],
"request"
:
{
"method"
:
"GET"
,
"header"
:
[],
"url"
:
{
"raw"
:
"{{url}}/bearer/Groups"
,
"host"
:
[
"{{url}}"
],
"path"
:
[
"bearer"
,
"Groups"
]
}
},
"response"
:
[]
},
{
"name"
:
"Update a single group"
,
"event"
:
[
{
"listen"
:
"test"
,
"script"
:
{
"exec"
:
[
"pm.test(
\"
Response status code is 200
\"
, () => {"
,
" pm.response.to.have.status(200);"
,
"});"
,
""
,
"pm.test(
\"
Response body is not empty
\"
, () => {"
,
" pm.expect(pm.response.json()).to.not.be.empty;"
,
"});"
,
""
,
"pm.test(
\"
Response body contains the group ID of the group we want to read
\"
, () => {"
,
" pm.expect(pm.response.json().id).to.eql(pm.collectionVariables.get('testGroupId'));"
,
"});"
,
""
,
"pm.test(
\"
Response body contains group with displayName
\\\"
updatedtestgroup
\\\"\"
, () => {"
,
" pm.expect(pm.response.json().displayName).to.eql(
\"
updatedtestgroup
\"
);"
,
"});"
],
"type"
:
"text/javascript"
}
}
],
"request"
:
{
"method"
:
"PUT"
,
"header"
:
[],
"body"
:
{
"mode"
:
"raw"
,
"raw"
:
"{
\n
\"
displayName
\"
:
\"
updatedtestgroup
\"
,
\n
\"
members
\"
: []
\n
}"
,
"options"
:
{
"raw"
:
{
"language"
:
"json"
}
}
},
"url"
:
{
"raw"
:
"{{url}}/bearer/Groups/{{testGroupId}}"
,
"host"
:
[
"{{url}}"
],
"path"
:
[
"bearer"
,
"Groups"
,
"{{testGroupId}}"
]
}
},
"response"
:
[]
},
{
"name"
:
"Delete a single group"
,
"event"
:
[
{
"listen"
:
"test"
,
"script"
:
{
"exec"
:
[
"pm.test(
\"
Response status code is 204
\"
, () => {"
,
" pm.response.to.have.status(204);"
,
"});"
],
"type"
:
"text/javascript"
}
}
],
"request"
:
{
"method"
:
"DELETE"
,
"header"
:
[],
"url"
:
{
"raw"
:
"{{url}}/bearer/Groups/{{testGroupId}}"
,
"host"
:
[
"{{url}}"
],
"path"
:
[
"bearer"
,
"Groups"
,
"{{testGroupId}}"
]
}
},
"response"
:
[]
}
],
"event"
:
[
{
"listen"
:
"prerequest"
,
"script"
:
{
"type"
:
"text/javascript"
,
"exec"
:
[
""
]
}
},
{
"listen"
:
"test"
,
"script"
:
{
"type"
:
"text/javascript"
,
"exec"
:
[
""
]
}
}
]
}
],
"auth"
:
{
"type"
:
"bearer"
,
"bearer"
:
[
{
"key"
:
"token"
,
"value"
:
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYWRtaW4ifQ.Oetm7xvhkYbiItRiqNx-z7LZ6ZkmDe1z_95igbPUSjA"
,
"type"
:
"string"
}
]
},
"event"
:
[
{
"listen"
:
"prerequest"
,
"script"
:
{
"type"
:
"text/javascript"
,
"exec"
:
[
""
]
}
},
{
"listen"
:
"test"
,
"script"
:
{
"type"
:
"text/javascript"
,
"exec"
:
[
""
]
}
}
],
"variable"
:
[
{
"key"
:
"testUserId"
,
"value"
:
null
},
{
"key"
:
"testGroupId"
,
"value"
:
null
},
{
"key"
:
"url"
,
"value"
:
"http://localhost:8888/index.php/apps/scimserviceprovider"
,
"type"
:
"default"
}
]
}
\ No newline at end of file
Prev
1
2
Next