Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
anis
anis-server
Commits
ed671c57
Commit
ed671c57
authored
Nov 13, 2020
by
François Agneray
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add admin middleware (protect metamodel routes)
parent
f932b53a
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
77 additions
and
324 deletions
+77
-324
app/dependencies.php
app/dependencies.php
+0
-8
app/routes.php
app/routes.php
+36
-26
src/Action/UserAction.php
src/Action/UserAction.php
+0
-94
src/Action/UserListAction.php
src/Action/UserListAction.php
+0
-80
src/Entity/Group.php
src/Entity/Group.php
+1
-30
src/Entity/User.php
src/Entity/User.php
+0
-85
src/Middleware/AdminMiddleware.php
src/Middleware/AdminMiddleware.php
+39
-0
src/Middleware/AuthorizationMiddleware.php
src/Middleware/AuthorizationMiddleware.php
+1
-1
No files found.
app/dependencies.php
View file @
ed671c57
...
...
@@ -76,14 +76,6 @@ $container->set('App\Action\ProjectAction', function (ContainerInterface $c) {
return
new
App\Action\ProjectAction
(
$c
->
get
(
'em'
));
});
$container
->
set
(
'App\Action\UserListAction'
,
function
(
ContainerInterface
$c
)
{
return
new
App\Action\UserListAction
(
$c
->
get
(
'em'
));
});
$container
->
set
(
'App\Action\UserAction'
,
function
(
ContainerInterface
$c
)
{
return
new
App\Action\UserAction
(
$c
->
get
(
'em'
));
});
$container
->
set
(
'App\Action\GroupListAction'
,
function
(
ContainerInterface
$c
)
{
return
new
App\Action\GroupListAction
(
$c
->
get
(
'em'
));
});
...
...
app/routes.php
View file @
ed671c57
...
...
@@ -13,31 +13,41 @@ declare(strict_types=1);
use
Slim\Routing\RouteCollectorProxy
;
$app
->
get
(
'/'
,
App\Action\RootAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
,
POST
],
'/database'
,
App\Action\DatabaseListAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
,
PUT
,
DELETE
],
'/database/{id}'
,
App\Action\DatabaseAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
],
'/database/{id}/table'
,
App\Action\TableListAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
,
POST
],
'/project'
,
App\Action\ProjectListAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
,
PUT
,
DELETE
],
'/project/{name}'
,
App\Action\ProjectAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
,
POST
],
'/user'
,
App\Action\UserListAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
,
PUT
,
DELETE
],
'/user/{email}'
,
App\Action\UserAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
,
POST
],
'/group'
,
App\Action\GroupListAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
,
PUT
,
DELETE
],
'/group/{id}'
,
App\Action\GroupAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
,
POST
],
'/instance'
,
App\Action\InstanceListAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
,
PUT
,
DELETE
],
'/instance/{name}'
,
App\Action\InstanceAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
,
POST
],
'/instance/{name}/dataset-family'
,
App\Action\DatasetFamilyListAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
],
'/instance/{name}/dataset'
,
App\Action\DatasetListByInstanceAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
,
PUT
,
DELETE
],
'/dataset-family/{id}'
,
App\Action\DatasetFamilyAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
,
POST
],
'/dataset-family/{id}/dataset'
,
App\Action\DatasetListAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
,
PUT
,
DELETE
],
'/dataset/{name}'
,
App\Action\DatasetAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
,
POST
],
'/dataset/{name}/criteria-family'
,
App\Action\CriteriaFamilyListAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
,
PUT
,
DELETE
],
'/criteria-family/{id}'
,
App\Action\CriteriaFamilyAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
,
POST
],
'/dataset/{name}/output-family'
,
App\Action\OutputFamilyListAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
,
PUT
,
DELETE
],
'/output-family/{id}'
,
App\Action\OutputFamilyAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
],
'/dataset/{name}/output-category'
,
App\Action\OutputCategoryListByDatasetAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
,
POST
],
'/output-family/{id}/output-category'
,
App\Action\OutputCategoryListAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
,
PUT
,
DELETE
],
'/output-category/{id}'
,
App\Action\OutputCategoryAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
],
'/dataset/{name}/attribute'
,
App\Action\AttributeListAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
,
PUT
],
'/dataset/{name}/attribute/{id}'
,
App\Action\AttributeAction
::
class
);
$app
->
map
([
OPTIONS
,
GET
,
PUT
],
'/dataset/{name}/attribute/{id}/distinct'
,
App\Action\AttributeDistinctAction
::
class
);
$app
->
group
(
''
,
function
(
RouteCollectorProxy
$group
)
{
$group
->
map
([
OPTIONS
,
GET
,
POST
],
'/database'
,
App\Action\DatabaseListAction
::
class
);
$group
->
map
([
OPTIONS
,
GET
,
PUT
,
DELETE
],
'/database/{id}'
,
App\Action\DatabaseAction
::
class
);
$group
->
map
([
OPTIONS
,
GET
],
'/database/{id}/table'
,
App\Action\TableListAction
::
class
);
$group
->
map
([
OPTIONS
,
GET
,
POST
],
'/project'
,
App\Action\ProjectListAction
::
class
);
$group
->
map
([
OPTIONS
,
GET
,
PUT
,
DELETE
],
'/project/{name}'
,
App\Action\ProjectAction
::
class
);
$group
->
map
([
OPTIONS
,
GET
,
POST
],
'/group'
,
App\Action\GroupListAction
::
class
);
$group
->
map
([
OPTIONS
,
GET
,
PUT
,
DELETE
],
'/group/{id}'
,
App\Action\GroupAction
::
class
);
$group
->
map
([
OPTIONS
,
GET
,
POST
],
'/instance'
,
App\Action\InstanceListAction
::
class
);
$group
->
map
([
OPTIONS
,
GET
,
PUT
,
DELETE
],
'/instance/{name}'
,
App\Action\InstanceAction
::
class
);
$group
->
map
([
OPTIONS
,
GET
,
POST
],
'/instance/{name}/dataset-family'
,
App\Action\DatasetFamilyListAction
::
class
);
$group
->
map
([
OPTIONS
,
GET
],
'/instance/{name}/dataset'
,
App\Action\DatasetListByInstanceAction
::
class
);
$group
->
map
([
OPTIONS
,
GET
,
PUT
,
DELETE
],
'/dataset-family/{id}'
,
App\Action\DatasetFamilyAction
::
class
);
$group
->
map
([
OPTIONS
,
GET
,
POST
],
'/dataset-family/{id}/dataset'
,
App\Action\DatasetListAction
::
class
);
$group
->
map
([
OPTIONS
,
GET
,
PUT
,
DELETE
],
'/dataset/{name}'
,
App\Action\DatasetAction
::
class
);
$group
->
map
([
OPTIONS
,
GET
,
POST
],
'/dataset/{name}/criteria-family'
,
App\Action\CriteriaFamilyListAction
::
class
);
$group
->
map
([
OPTIONS
,
GET
,
PUT
,
DELETE
],
'/criteria-family/{id}'
,
App\Action\CriteriaFamilyAction
::
class
);
$group
->
map
([
OPTIONS
,
GET
,
POST
],
'/dataset/{name}/output-family'
,
App\Action\OutputFamilyListAction
::
class
);
$group
->
map
([
OPTIONS
,
GET
,
PUT
,
DELETE
],
'/output-family/{id}'
,
App\Action\OutputFamilyAction
::
class
);
$group
->
map
([
OPTIONS
,
GET
],
'/dataset/{name}/output-category'
,
App\Action\OutputCategoryListByDatasetAction
::
class
);
$group
->
map
(
[
OPTIONS
,
GET
,
POST
],
'/output-family/{id}/output-category'
,
App\Action\OutputCategoryListAction
::
class
);
$group
->
map
([
OPTIONS
,
GET
,
PUT
,
DELETE
],
'/output-category/{id}'
,
App\Action\OutputCategoryAction
::
class
);
$group
->
map
([
OPTIONS
,
GET
],
'/dataset/{name}/attribute'
,
App\Action\AttributeListAction
::
class
);
$group
->
map
([
OPTIONS
,
GET
,
PUT
],
'/dataset/{name}/attribute/{id}'
,
App\Action\AttributeAction
::
class
);
$group
->
map
(
[
OPTIONS
,
GET
,
PUT
],
'/dataset/{name}/attribute/{id}/distinct'
,
App\Action\AttributeDistinctAction
::
class
);
})
->
add
(
new
App\Middleware\AdminMiddleware
());
$app
->
get
(
'/search/{dname}'
,
App\Action\SearchAction
::
class
);
$app
->
get
(
'/download-file/{dname}/[{fpath:.*}]'
,
App\Action\DownloadFileAction
::
class
);
src/Action/UserAction.php
deleted
100644 → 0
View file @
f932b53a
<?php
/*
* This file is part of Anis Server.
*
* (c) Laboratoire d'Astrophysique de Marseille / CNRS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare
(
strict_types
=
1
);
namespace
App\Action
;
use
Psr\Http\Message\ServerRequestInterface
as
Request
;
use
Psr\Http\Message\ResponseInterface
as
Response
;
use
Slim\Exception\HttpBadRequestException
;
use
Slim\Exception\HttpNotFoundException
;
use
App\Entity\User
;
final
class
UserAction
extends
AbstractAction
{
/**
* `GET` Returns the user found
* `PUT` Full update the user and returns the new version
* `DELETE` Delete the user found and return a confirmation message
*
* @param ServerRequestInterface $request PSR-7 This object represents the HTTP request
* @param ResponseInterface $response PSR-7 This object represents the HTTP response
* @param string[] $args This table contains information transmitted in the URL (see routes.php)
*
* @return ResponseInterface
*/
public
function
__invoke
(
Request
$request
,
Response
$response
,
array
$args
):
Response
{
if
(
$request
->
getMethod
()
===
OPTIONS
)
{
return
$response
->
withHeader
(
'Access-Control-Allow-Methods'
,
'GET, PUT, DELETE, OPTIONS'
);
}
// Search the correct user with primary key
$user
=
$this
->
em
->
find
(
'App\Entity\User'
,
$args
[
'email'
]);
// If user is not found 404
if
(
is_null
(
$user
))
{
throw
new
HttpNotFoundException
(
$request
,
'User with email '
.
$args
[
'email'
]
.
' is not found'
);
}
if
(
$request
->
getMethod
()
===
GET
)
{
$payload
=
json_encode
(
$user
);
}
if
(
$request
->
getMethod
()
===
PUT
)
{
$parsedBody
=
$request
->
getParsedBody
();
// If mandatories empty fields 400
foreach
(
array
(
'role'
)
as
$a
)
{
if
(
$this
->
isEmptyField
(
$a
,
$parsedBody
))
{
throw
new
HttpBadRequestException
(
$request
,
'Param '
.
$a
.
' needed to edit the user'
);
}
}
$this
->
editUser
(
$user
,
$parsedBody
);
$payload
=
json_encode
(
$user
);
}
if
(
$request
->
getMethod
()
===
DELETE
)
{
$email
=
$user
->
getEmail
();
$this
->
em
->
remove
(
$user
);
$this
->
em
->
flush
();
$payload
=
json_encode
(
array
(
'message'
=>
'User with email '
.
$email
.
' is removed!'
));
}
$response
->
getBody
()
->
write
(
$payload
);
return
$response
;
}
/**
* Update user object with setters
*
* @param User $user The user to update
* @param array $parsedBody Contains the new values of the user
*/
private
function
editUser
(
User
$user
,
array
$parsedBody
):
void
{
$user
->
setRole
(
$parsedBody
[
'role'
]);
$this
->
em
->
flush
();
}
}
src/Action/UserListAction.php
deleted
100644 → 0
View file @
f932b53a
<?php
/*
* This file is part of Anis Server.
*
* (c) Laboratoire d'Astrophysique de Marseille / CNRS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare
(
strict_types
=
1
);
namespace
App\Action
;
use
Psr\Http\Message\ServerRequestInterface
as
Request
;
use
Psr\Http\Message\ResponseInterface
as
Response
;
use
Slim\Exception\HttpBadRequestException
;
use
App\Entity\User
;
final
class
UserListAction
extends
AbstractAction
{
/**
* `GET` Returns a list of all users listed in the metamodel
* `POST` Add a new user
*
* @param ServerRequestInterface $request PSR-7 This object represents the HTTP request
* @param ResponseInterface $response PSR-7 This object represents the HTTP response
* @param string[] $args This table contains information transmitted in the URL (see routes.php)
*
* @return ResponseInterface
*/
public
function
__invoke
(
Request
$request
,
Response
$response
,
array
$args
):
Response
{
if
(
$request
->
getMethod
()
===
OPTIONS
)
{
return
$response
->
withHeader
(
'Access-Control-Allow-Methods'
,
'GET, POST, OPTIONS'
);
}
if
(
$request
->
getMethod
()
===
GET
)
{
$users
=
$this
->
em
->
getRepository
(
'App\Entity\User'
)
->
findAll
();
$payload
=
json_encode
(
$users
);
}
if
(
$request
->
getMethod
()
===
POST
)
{
$parsedBody
=
$request
->
getParsedBody
();
// To work this action needs user information
foreach
(
array
(
'email'
)
as
$a
)
{
if
(
$this
->
isEmptyField
(
$a
,
$parsedBody
))
{
throw
new
HttpBadRequestException
(
$request
,
'Param '
.
$a
.
' needed to add a new user'
);
}
}
$user
=
$this
->
postUser
(
$parsedBody
);
$payload
=
json_encode
(
$user
);
$response
=
$response
->
withStatus
(
201
);
}
$response
->
getBody
()
->
write
(
$payload
);
return
$response
;
}
/**
* Add a new user into the metamodel
*
* @param array $parsedBody Contains the values of the new user
*/
private
function
postUser
(
array
$parsedBody
):
User
{
$user
=
new
User
(
$parsedBody
[
'email'
]);
$user
->
setRole
(
'user'
);
$this
->
em
->
persist
(
$user
);
$this
->
em
->
flush
();
return
$user
;
}
}
src/Entity/Group.php
View file @
ed671c57
...
...
@@ -37,18 +37,6 @@ class Group implements \JsonSerializable
*/
protected
$label
;
/**
* Many Groups have Many Users.
*
* @ManyToMany(targetEntity="User", inversedBy="groups")
* @JoinTable(
* name="groups_users",
* joinColumns={@JoinColumn(name="group_id", referencedColumnName="id")},
* inverseJoinColumns={@JoinColumn(name="user_email", referencedColumnName="email")}
* )
*/
protected
$users
;
/**
* Many Groups have Many Datasets privileges.
*
...
...
@@ -61,9 +49,8 @@ class Group implements \JsonSerializable
*/
protected
$datasets
;
public
function
__construct
(
array
$users
,
array
$datasets
)
public
function
__construct
(
array
$datasets
)
{
$this
->
users
=
new
ArrayCollection
(
$users
);
$this
->
datasets
=
new
ArrayCollection
(
$datasets
);
}
...
...
@@ -82,16 +69,6 @@ class Group implements \JsonSerializable
$this
->
label
=
$label
;
}
public
function
getUsers
()
{
return
$this
->
users
;
}
public
function
setUsers
(
$users
)
{
$this
->
users
=
$users
;
}
public
function
getDatasets
()
{
return
$this
->
datasets
;
...
...
@@ -104,11 +81,6 @@ class Group implements \JsonSerializable
public
function
jsonSerialize
()
{
$users
=
array
();
foreach
(
$this
->
getUsers
()
as
$user
)
{
$users
[]
=
$user
->
getEmail
();
}
$datasets
=
array
();
foreach
(
$this
->
getDatasets
()
as
$dataset
)
{
$datasets
[]
=
$dataset
->
getName
();
...
...
@@ -117,7 +89,6 @@ class Group implements \JsonSerializable
return
[
'id'
=>
$this
->
getId
(),
'label'
=>
$this
->
getLabel
(),
'users'
=>
$users
,
'datasets'
=>
$datasets
];
}
...
...
src/Entity/User.php
deleted
100644 → 0
View file @
f932b53a
<?php
/*
* This file is part of Anis Server.
*
* (c) Laboratoire d'Astrophysique de Marseille / CNRS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare
(
strict_types
=
1
);
namespace
App\Entity
;
use
Doctrine\Common\Collections\Collection
;
use
Doctrine\Common\Collections\ArrayCollection
;
/**
* @Entity
* @Table(name="anis_user")
*/
class
User
implements
\
JsonSerializable
{
/**
* @var string
*
* @Id
* @Column(type="string", nullable=false)
*/
protected
$email
;
/**
* @var string
*
* @Column(type="string", nullable=false)
*/
protected
$role
;
/**
* Many Users have Many Groups.
*
* @ManyToMany(targetEntity="Group", mappedBy="users")
*/
protected
$groups
;
public
function
__construct
(
$email
)
{
$this
->
email
=
$email
;
$this
->
groups
=
new
ArrayCollection
();
}
public
function
getEmail
()
{
return
$this
->
email
;
}
public
function
getRole
()
{
return
$this
->
role
;
}
public
function
setRole
(
$role
)
{
$this
->
role
=
$role
;
}
public
function
getGroups
()
{
return
$this
->
groups
;
}
public
function
jsonSerialize
()
{
$groups
=
array
();
foreach
(
$this
->
getGroups
()
as
$group
)
{
$groups
[]
=
$group
->
getId
();
}
return
[
'email'
=>
$this
->
getEmail
(),
'role'
=>
$this
->
getRole
(),
'groups'
=>
$groups
];
}
}
src/Middleware/AdminMiddleware.php
0 → 100644
View file @
ed671c57
<?php
/*
* This file is part of Anis Server.
*
* (c) Laboratoire d'Astrophysique de Marseille / CNRS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare
(
strict_types
=
1
);
namespace
App\Middleware
;
use
Psr\Http\Message\ResponseInterface
as
Response
;
use
Psr\Http\Message\ServerRequestInterface
as
Request
;
use
Psr\Http\Server\RequestHandlerInterface
as
RequestHandler
;
use
Psr\Http\Server\MiddlewareInterface
;
use
Nyholm\Psr7\Response
as
NyholmResponse
;
final
class
AdminMiddleware
implements
MiddlewareInterface
{
public
function
process
(
Request
$request
,
RequestHandler
$handler
):
Response
{
if
(
$request
->
getMethod
()
===
GET
)
{
return
$handler
->
handle
(
$request
);
}
$token
=
$request
->
getAttribute
(
'token'
);
if
(
!
$token
)
{
return
(
new
NyholmResponse
())
->
withStatus
(
401
);
}
if
(
!
in_array
(
'anis_admin'
,
$token
->
getClaim
(
'realm_access'
)
->
roles
))
{
return
(
new
NyholmResponse
())
->
withStatus
(
403
);
}
return
$handler
->
handle
(
$request
);
}
}
src/Middleware/AuthorizationMiddleware.php
View file @
ed671c57
...
...
@@ -85,6 +85,6 @@ final class AuthorizationMiddleware implements MiddlewareInterface
return
(
new
NyholmResponse
())
->
withStatus
(
401
);
}
return
$handler
->
handle
(
$request
->
withAttribute
(
'
email
'
,
$token
->
getClaim
(
'email'
)
));
return
$handler
->
handle
(
$request
->
withAttribute
(
'
token
'
,
$token
));
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment