Merge branch 'cas-and-apps-api' into 'v2.0'
Manager API: Added menu category and application API (includes openapi spec & tests) See merge request lemonldap-ng/lemonldap-ng!151
This commit is contained in:
commit
65e9e5958f
File diff suppressed because it is too large
Load Diff
|
@ -622,6 +622,357 @@ paths:
|
|||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/api/v1/menu/cat:
|
||||
post:
|
||||
tags:
|
||||
- menucat
|
||||
summary: Create a new Menu Category
|
||||
operationId: addMenuCat
|
||||
requestBody:
|
||||
description: Menu Category to add
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MenuCat'
|
||||
required: true
|
||||
responses:
|
||||
201:
|
||||
$ref: '#/components/responses/Created'
|
||||
400:
|
||||
$ref: '#/components/responses/Error'
|
||||
409:
|
||||
$ref: '#/components/responses/Conflict'
|
||||
|
||||
/api/v1/menu/cat/findByConfKey:
|
||||
get:
|
||||
tags:
|
||||
- menucat
|
||||
summary: Finds Menu Categories by configuration key
|
||||
description: Takes a search pattern to be tested against existing categories
|
||||
operationId: findMenuCatByConfKey
|
||||
parameters:
|
||||
- name: pattern
|
||||
in: query
|
||||
description: Search pattern
|
||||
required: true
|
||||
schema:
|
||||
type: "string"
|
||||
examples:
|
||||
any:
|
||||
summary: Any value
|
||||
value: "*"
|
||||
prefix:
|
||||
summary: Given prefix
|
||||
value: "zone1-*"
|
||||
anywhere:
|
||||
summary: Substring
|
||||
value: "something"
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/responses/ManyMenuCat'
|
||||
400:
|
||||
$ref: '#/components/responses/Error'
|
||||
|
||||
/api/v1/menu/cat/{confKey}:
|
||||
get:
|
||||
tags:
|
||||
- menucat
|
||||
summary: Get Menu Category by configuration key
|
||||
description: Returns a single Category
|
||||
operationId: getMenuCatByConfKey
|
||||
parameters:
|
||||
- name: confKey
|
||||
in: path
|
||||
description: Configuration key of Menu Category
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/confKey'
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/responses/OneMenuCat'
|
||||
400:
|
||||
$ref: '#/components/responses/Error'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
put:
|
||||
tags:
|
||||
- menucat
|
||||
summary: Replaces a Menu Category
|
||||
operationId: replaceMenuCat
|
||||
parameters:
|
||||
- name: confKey
|
||||
in: path
|
||||
description: Configuration key of Menu Category that needs to be replaced
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/confKey'
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MenuCat'
|
||||
responses:
|
||||
204:
|
||||
$ref: '#/components/responses/NoContent'
|
||||
400:
|
||||
$ref: '#/components/responses/Error'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
409:
|
||||
$ref: '#/components/responses/Conflict'
|
||||
patch:
|
||||
tags:
|
||||
- menucat
|
||||
summary: Updates a Menu Category
|
||||
operationId: updateMenuCat
|
||||
parameters:
|
||||
- name: confKey
|
||||
in: path
|
||||
description: Configuration key of Menu Category that needs to be updated
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/confKey'
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MenuCatUpdate'
|
||||
responses:
|
||||
204:
|
||||
$ref: '#/components/responses/NoContent'
|
||||
400:
|
||||
$ref: '#/components/responses/Error'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
409:
|
||||
$ref: '#/components/responses/Conflict'
|
||||
|
||||
delete:
|
||||
tags:
|
||||
- menucat
|
||||
summary: Deletes a Menu Category
|
||||
operationId: deleteMenuCat
|
||||
parameters:
|
||||
- name: confKey
|
||||
in: path
|
||||
description: Configuration key of Menu Category to delete
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/confKey'
|
||||
responses:
|
||||
204:
|
||||
$ref: '#/components/responses/NoContent'
|
||||
400:
|
||||
$ref: '#/components/responses/Error'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/api/v1/menu/app/{cat}:
|
||||
get:
|
||||
tags:
|
||||
- menuapp
|
||||
summary: Get Menu Applications within a Menu Category
|
||||
description: Return existing applications within a menu category
|
||||
operationId: getMenuApps
|
||||
parameters:
|
||||
- name: cat
|
||||
in: path
|
||||
description: Configuration key of Menu Category to work with
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/menuCatConfKey'
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/responses/ManyMenuApp'
|
||||
400:
|
||||
$ref: '#/components/responses/Error'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
post:
|
||||
tags:
|
||||
- menuapp
|
||||
summary: Create a new Menu Application within a Menu Category
|
||||
operationId: addMenuApp
|
||||
parameters:
|
||||
- name: cat
|
||||
in: path
|
||||
description: Configuration key of Menu Category to work with
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/menuCatConfKey'
|
||||
requestBody:
|
||||
description: Menu Application to add
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MenuApp'
|
||||
required: true
|
||||
responses:
|
||||
201:
|
||||
$ref: '#/components/responses/Created'
|
||||
400:
|
||||
$ref: '#/components/responses/Error'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
409:
|
||||
$ref: '#/components/responses/Conflict'
|
||||
|
||||
/api/v1/menu/app/{cat}/findByConfKey:
|
||||
get:
|
||||
tags:
|
||||
- menuapp
|
||||
summary: Finds Menu Applications by configuration key within a Menu Category
|
||||
description: Takes a search pattern to be tested against existing applications within a menu category
|
||||
operationId: findMenuAppByConfKey
|
||||
parameters:
|
||||
- name: cat
|
||||
in: path
|
||||
description: Configuration key of Menu Category to work with
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/menuCatConfKey'
|
||||
- name: pattern
|
||||
in: query
|
||||
description: Search pattern
|
||||
required: true
|
||||
schema:
|
||||
type: "string"
|
||||
examples:
|
||||
any:
|
||||
summary: Any value
|
||||
value: "*"
|
||||
prefix:
|
||||
summary: Given prefix
|
||||
value: "zone1-*"
|
||||
anywhere:
|
||||
summary: Substring
|
||||
value: "something"
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/responses/ManyMenuApp'
|
||||
400:
|
||||
$ref: '#/components/responses/Error'
|
||||
|
||||
/api/v1/menu/app/{cat}/{confKey}:
|
||||
get:
|
||||
tags:
|
||||
- menuapp
|
||||
summary: Get Menu Application within a Menu Category by configuration key
|
||||
description: Returns a single application
|
||||
operationId: getMenuAppByConfKey
|
||||
parameters:
|
||||
- name: cat
|
||||
in: path
|
||||
description: Configuration key of Menu Category to work with
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/menuCatConfKey'
|
||||
- name: confKey
|
||||
in: path
|
||||
description: Configuration key of Menu Application
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/confKey'
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/responses/OneMenuApp'
|
||||
400:
|
||||
$ref: '#/components/responses/Error'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
put:
|
||||
tags:
|
||||
- menuapp
|
||||
summary: Replaces a Menu Application
|
||||
operationId: replaceMenuApp
|
||||
parameters:
|
||||
- name: cat
|
||||
in: path
|
||||
description: Configuration key of Menu Category to work with
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/menuCatConfKey'
|
||||
- name: confKey
|
||||
in: path
|
||||
description: Configuration key of Menu Application that needs to be replaced
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/confKey'
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MenuApp'
|
||||
responses:
|
||||
204:
|
||||
$ref: '#/components/responses/NoContent'
|
||||
400:
|
||||
$ref: '#/components/responses/Error'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
409:
|
||||
$ref: '#/components/responses/Conflict'
|
||||
patch:
|
||||
tags:
|
||||
- menuapp
|
||||
summary: Updates a Menu Application
|
||||
operationId: updateMenuApp
|
||||
parameters:
|
||||
- name: cat
|
||||
in: path
|
||||
description: Configuration key of Menu Category to work with
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/menuCatConfKey'
|
||||
- name: confKey
|
||||
in: path
|
||||
description: Configuration key of Menu Application that needs to be updated
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/confKey'
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MenuAppUpdate'
|
||||
responses:
|
||||
204:
|
||||
$ref: '#/components/responses/NoContent'
|
||||
400:
|
||||
$ref: '#/components/responses/Error'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
409:
|
||||
$ref: '#/components/responses/Conflict'
|
||||
|
||||
delete:
|
||||
tags:
|
||||
- menuapp
|
||||
summary: Deletes a Menu Application
|
||||
operationId: deleteMenuApp
|
||||
parameters:
|
||||
- name: cat
|
||||
in: path
|
||||
description: Configuration key of Menu Category to work with
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/menuCatConfKey'
|
||||
- name: confKey
|
||||
in: path
|
||||
description: Configuration key of Menu Application to delete
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/confKey'
|
||||
responses:
|
||||
204:
|
||||
$ref: '#/components/responses/NoContent'
|
||||
400:
|
||||
$ref: '#/components/responses/Error'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
components:
|
||||
schemas:
|
||||
confKey:
|
||||
|
@ -925,6 +1276,90 @@ components:
|
|||
items:
|
||||
$ref: "#/components/schemas/SecondFactor"
|
||||
|
||||
menuCatConfKey:
|
||||
type: string
|
||||
pattern: '^\w[\w\.\-]*$'
|
||||
MenuCat:
|
||||
required:
|
||||
- confKey
|
||||
- catname
|
||||
type: object
|
||||
properties:
|
||||
confKey:
|
||||
$ref: '#/components/schemas/confKey'
|
||||
catname:
|
||||
type: string
|
||||
order:
|
||||
type: integer
|
||||
MenuCatUpdate:
|
||||
type: object
|
||||
properties:
|
||||
catname:
|
||||
type: string
|
||||
order:
|
||||
type: integer
|
||||
MenuApp:
|
||||
required:
|
||||
- confKey
|
||||
type: object
|
||||
properties:
|
||||
confKey:
|
||||
$ref: '#/components/schemas/confKey'
|
||||
order:
|
||||
type: integer
|
||||
options:
|
||||
$ref: '#/components/schemas/MenuAppOptions'
|
||||
MenuAppOptions:
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
tooltip:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
uri:
|
||||
type: string
|
||||
logo:
|
||||
type: string
|
||||
default: network.png
|
||||
enum:
|
||||
- attach.png
|
||||
- bell.png
|
||||
- bookmark.png
|
||||
- configure.png
|
||||
- database.png
|
||||
- demo.png
|
||||
- folder.png
|
||||
- gear.png
|
||||
- help.png
|
||||
- llng.png
|
||||
- mailappt.png
|
||||
- money.png
|
||||
- network.png
|
||||
- terminal.png
|
||||
- thumbnail.png
|
||||
- tux.png
|
||||
- web.png
|
||||
- (Any reference to an available image in app logo folder)
|
||||
display:
|
||||
type: string
|
||||
default: auto
|
||||
enum:
|
||||
- 'on'
|
||||
- 'off'
|
||||
- auto
|
||||
- (Any special rule to apply for example "$uid eq 'dwho'")
|
||||
MenuAppUpdate:
|
||||
type: object
|
||||
properties:
|
||||
order:
|
||||
type: integer
|
||||
options:
|
||||
$ref: '#/components/schemas/MenuAppOptions'
|
||||
|
||||
responses:
|
||||
NoContent:
|
||||
description: Successful modification
|
||||
|
@ -1002,3 +1437,31 @@ components:
|
|||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/SecondFactors"
|
||||
OneMenuCat:
|
||||
description: Return a Menu Category
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MenuCat'
|
||||
ManyMenuCat:
|
||||
description: Return a list of Menu Categories
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/MenuCat'
|
||||
OneMenuApp:
|
||||
description: Return a Menu Application
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MenuApp'
|
||||
ManyMenuApp:
|
||||
description: Return a list of Menu Applications
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/MenuApp'
|
||||
|
|
|
@ -13,8 +13,10 @@ use Lemonldap::NG::Manager::Api::2F;
|
|||
use Lemonldap::NG::Manager::Api::Providers::OidcRp;
|
||||
use Lemonldap::NG::Manager::Api::Providers::SamlSp;
|
||||
use Lemonldap::NG::Manager::Api::Providers::CasApp;
|
||||
use Lemonldap::NG::Manager::Api::Menu::Cat;
|
||||
use Lemonldap::NG::Manager::Api::Menu::App;
|
||||
|
||||
our $VERSION = '2.0.8';
|
||||
our $VERSION = '2.0.9';
|
||||
|
||||
#############################
|
||||
# I. INITIALIZATION METHODS #
|
||||
|
@ -77,6 +79,24 @@ sub init {
|
|||
'*' => 'getSecondFactors'
|
||||
},
|
||||
},
|
||||
menu => {
|
||||
cat => {
|
||||
findByConfKey => {
|
||||
':uPattern' => 'findMenuCatByConfKey'
|
||||
},
|
||||
':confKey' => {
|
||||
'*' => 'getMenuCatByConfKey'
|
||||
}
|
||||
},
|
||||
app => {
|
||||
':confKey' => {
|
||||
findByConfKey => {
|
||||
':uPattern' => 'findMenuAppByConfKey'
|
||||
},
|
||||
':appConfKey' => 'getMenuApp'
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
['GET']
|
||||
|
@ -96,6 +116,12 @@ sub init {
|
|||
app => 'addCasApp'
|
||||
},
|
||||
},
|
||||
menu => {
|
||||
cat => 'addMenuCat',
|
||||
app => {
|
||||
':confKey' => 'addMenuApp'
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
['POST']
|
||||
|
@ -115,6 +141,14 @@ sub init {
|
|||
app => { ':confKey' => 'replaceCasApp' }
|
||||
},
|
||||
},
|
||||
menu => {
|
||||
cat => { ':confKey' => 'replaceMenuCat' },
|
||||
app => {
|
||||
':confKey' => {
|
||||
':appConfKey' => 'replaceMenuApp'
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
['PUT']
|
||||
|
@ -134,6 +168,14 @@ sub init {
|
|||
app => { ':confKey' => 'updateCasApp' }
|
||||
},
|
||||
},
|
||||
menu => {
|
||||
cat => { ':confKey' => 'updateMenuCat' },
|
||||
app => {
|
||||
':confKey' => {
|
||||
':appConfKey' => 'updateMenuApp'
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
['PATCH']
|
||||
|
@ -164,6 +206,14 @@ sub init {
|
|||
'*' => 'deleteSecondFactors'
|
||||
},
|
||||
},
|
||||
menu => {
|
||||
cat => { ':confKey' => 'deleteMenuCat' },
|
||||
app => {
|
||||
':confKey' => {
|
||||
':appConfKey' => 'deleteMenuApp'
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
['DELETE']
|
||||
|
|
408
lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Api/Menu/App.pm
Normal file
408
lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Api/Menu/App.pm
Normal file
|
@ -0,0 +1,408 @@
|
|||
package Lemonldap::NG::Manager::Api::Menu::App;
|
||||
|
||||
our $VERSION = '2.0.9';
|
||||
|
||||
package Lemonldap::NG::Manager::Api;
|
||||
|
||||
use 5.10.0;
|
||||
use utf8;
|
||||
use Mouse;
|
||||
use Lemonldap::NG::Manager::Conf::Parser;
|
||||
use Data::Dumper;
|
||||
|
||||
extends 'Lemonldap::NG::Manager::Api::Common';
|
||||
|
||||
sub getMenuApp {
|
||||
my ( $self, $req ) = @_;
|
||||
|
||||
my $catConfKey = $req->params('confKey')
|
||||
or return $self->sendError( $req, 'Category confKey is missing', 400 );
|
||||
|
||||
my $appConfKey = $req->params('appConfKey');
|
||||
|
||||
# Get latest configuration
|
||||
my $conf = $self->_confAcc->getConf;
|
||||
|
||||
# Check if catConfKey is defined
|
||||
return $self->sendError( $req,
|
||||
"Menu category '$catConfKey' not found", 404 )
|
||||
unless ( defined $conf->{applicationList}->{$catConfKey} );
|
||||
|
||||
if ( defined $appConfKey ) {
|
||||
|
||||
# Return one application referenced with this appConfKey
|
||||
$self->logger->debug(
|
||||
"[API] Menu application $appConfKey from category $catConfKey configuration requested"
|
||||
);
|
||||
|
||||
my $menuApp =
|
||||
$self->_getMenuAppByConfKey( $conf, $catConfKey, $appConfKey );
|
||||
|
||||
# Return 404 if not found
|
||||
return $self->sendError(
|
||||
$req,
|
||||
"Menu application '$appConfKey' from category '$catConfKey' not found",
|
||||
404
|
||||
) unless ( defined $menuApp );
|
||||
|
||||
return $self->sendJSONresponse( $req, $menuApp );
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
# Return all applications for this category
|
||||
$self->logger->debug(
|
||||
"[API] Menu applications from category $catConfKey configuration requested"
|
||||
);
|
||||
|
||||
my $cat = $conf->{applicationList}->{$catConfKey};
|
||||
|
||||
my @menuApps =
|
||||
map {
|
||||
$self->_isCatApp( $cat->{$_} )
|
||||
? $self->_getMenuAppByConfKey( $conf, $catConfKey, $_ )
|
||||
: ()
|
||||
}
|
||||
keys %{$cat};
|
||||
|
||||
return $self->sendJSONresponse( $req, [@menuApps] );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sub findMenuAppByConfKey {
|
||||
my ( $self, $req ) = @_;
|
||||
|
||||
my $catConfKey = $req->params('confKey')
|
||||
or return $self->sendError( $req, 'Category confKey is missing', 400 );
|
||||
|
||||
my $pattern = (
|
||||
defined $req->params('uPattern')
|
||||
? $req->params('uPattern')
|
||||
: ( defined $req->params('pattern') ? $req->params('pattern') : undef )
|
||||
);
|
||||
|
||||
return $self->sendError( $req, 'Invalid input: pattern is missing', 400 )
|
||||
unless ( defined $pattern );
|
||||
|
||||
unless ( $pattern = $self->_getRegexpFromPattern($pattern) ) {
|
||||
return $self->sendError( $req, 'Invalid input: pattern is invalid',
|
||||
400 );
|
||||
}
|
||||
|
||||
$self->logger->debug(
|
||||
"[API] Find Menu Applications from category $catConfKey by confKey regexp $pattern requested"
|
||||
);
|
||||
|
||||
# Get latest configuration
|
||||
my $conf = $self->_confAcc->getConf;
|
||||
|
||||
# Check if catConfKey is defined
|
||||
return $self->sendError( $req,
|
||||
"Menu category '$catConfKey' not found", 404 )
|
||||
unless ( defined $conf->{applicationList}->{$catConfKey} );
|
||||
|
||||
my $cat = $conf->{applicationList}->{$catConfKey};
|
||||
|
||||
my @menuApps =
|
||||
map {
|
||||
$self->_isCatApp( $cat->{$_} )
|
||||
&& $_ =~ $pattern
|
||||
? $self->_getMenuAppByConfKey( $conf, $catConfKey, $_ )
|
||||
: ()
|
||||
}
|
||||
keys %{$cat};
|
||||
|
||||
return $self->sendJSONresponse( $req, [@menuApps] );
|
||||
}
|
||||
|
||||
sub addMenuApp {
|
||||
my ( $self, $req ) = @_;
|
||||
my $add = $req->jsonBodyToObj;
|
||||
|
||||
my $catConfKey = $req->params('confKey')
|
||||
or return $self->sendError( $req, 'Category confKey is missing', 400 );
|
||||
|
||||
return $self->sendError( $req, "Invalid input: " . $req->error, 400 )
|
||||
unless ($add);
|
||||
|
||||
return $self->sendError( $req, 'Invalid input: confKey is missing', 400 )
|
||||
unless ( defined $add->{confKey} );
|
||||
|
||||
return $self->sendError( $req, 'Invalid input: confKey is not a string',
|
||||
400 )
|
||||
if ( ref $add->{confKey} );
|
||||
|
||||
return $self->sendError( $req, 'Invalid input: confKey contains invalid characters',
|
||||
400 )
|
||||
unless ( $add->{confKey} =~ '^\w[\w\.\-]*$' );
|
||||
|
||||
return $self->sendError( $req, 'Invalid input: name is missing', 400 )
|
||||
unless ( defined $add->{options} && defined $add->{options}{name} );
|
||||
|
||||
return $self->sendError( $req, 'Invalid input: name is not a string', 400 )
|
||||
if ( ref $add->{options}{name} );
|
||||
|
||||
$self->logger->debug(
|
||||
"[API] Add Menu Application from category $catConfKey with confKey $add->{confKey} requested"
|
||||
);
|
||||
|
||||
# Get latest configuration
|
||||
my $conf = $self->_confAcc->getConf( { noCache => 1 } );
|
||||
|
||||
# Check if catConfKey is defined
|
||||
return $self->sendError( $req,
|
||||
"Menu category '$catConfKey' not found", 404 )
|
||||
unless ( defined $conf->{applicationList}->{$catConfKey} );
|
||||
|
||||
return $self->sendError(
|
||||
$req,
|
||||
"Invalid input: A Menu Application with confKey $add->{confKey} already exists in category $catConfKey",
|
||||
409
|
||||
)
|
||||
if (
|
||||
defined $self->_getMenuAppByConfKey( $conf, $catConfKey,
|
||||
$add->{confKey} ) );
|
||||
|
||||
my $res =
|
||||
$self->_pushMenuApp( $conf, $catConfKey, $add->{confKey}, $add, 1 );
|
||||
|
||||
return $self->sendError( $req, $res->{msg}, 400 )
|
||||
unless ( $res->{res} eq 'ok' );
|
||||
|
||||
return $self->sendJSONresponse(
|
||||
$req,
|
||||
{ message => "Successful operation" },
|
||||
code => 201
|
||||
);
|
||||
}
|
||||
|
||||
sub updateMenuApp {
|
||||
my ( $self, $req ) = @_;
|
||||
|
||||
my $catConfKey = $req->params('confKey')
|
||||
or return $self->sendError( $req, 'Category confKey is missing', 400 );
|
||||
|
||||
my $appConfKey = $req->params('appConfKey')
|
||||
or return $self->sendError( $req, 'Application confKey is missing', 400 );
|
||||
|
||||
my $update = $req->jsonBodyToObj;
|
||||
|
||||
return $self->sendError( $req, "Invalid input: " . $req->error, 400 )
|
||||
unless ($update);
|
||||
|
||||
$self->logger->debug(
|
||||
"[API] Menu application $appConfKey from category $catConfKey configuration update requested"
|
||||
);
|
||||
|
||||
# Get latest configuration
|
||||
my $conf = $self->_confAcc->getConf( { noCache => 1 } );
|
||||
|
||||
# Return 404 if not found
|
||||
|
||||
return $self->sendError( $req,
|
||||
"Menu category '$catConfKey' not found", 404 )
|
||||
unless ( defined $self->_getMenuCatByConfKey( $conf, $catConfKey ) );
|
||||
|
||||
return $self->sendError(
|
||||
$req,
|
||||
"Menu application '$appConfKey' from category '$catConfKey' not found",
|
||||
404
|
||||
)
|
||||
unless (
|
||||
defined $self->_getMenuAppByConfKey( $conf, $catConfKey, $appConfKey )
|
||||
);
|
||||
|
||||
my $res =
|
||||
$self->_pushMenuApp( $conf, $catConfKey, $appConfKey, $update, 0 );
|
||||
|
||||
return $self->sendError( $req, $res->{msg}, 400 )
|
||||
unless ( $res->{res} eq 'ok' );
|
||||
|
||||
return $self->sendJSONresponse( $req, undef, code => 204 );
|
||||
}
|
||||
|
||||
sub replaceMenuApp {
|
||||
my ( $self, $req ) = @_;
|
||||
my $catConfKey = $req->params('confKey')
|
||||
or return $self->sendError( $req, 'Category confKey is missing', 400 );
|
||||
|
||||
my $appConfKey = $req->params('appConfKey')
|
||||
or return $self->sendError( $req, 'Application confKey is missing', 400 );
|
||||
|
||||
my $replace = $req->jsonBodyToObj;
|
||||
|
||||
return $self->sendError( $req, "Invalid input: " . $req->error, 400 )
|
||||
unless ($replace);
|
||||
|
||||
return $self->sendError( $req, 'Invalid input: confKey is missing', 400 )
|
||||
unless ( defined $replace->{confKey} );
|
||||
|
||||
return $self->sendError( $req, 'Invalid input: confKey is not a string',
|
||||
400 )
|
||||
if ( ref $replace->{confKey} );
|
||||
|
||||
return $self->sendError( $req, 'Invalid input: confKey contains invalid characters',
|
||||
400 )
|
||||
unless ( $replace->{confKey} =~ '^\w[\w\.\-]*$' );
|
||||
|
||||
return $self->sendError( $req, 'Invalid input: name is missing', 400 )
|
||||
unless ( defined $replace->{options}
|
||||
&& defined $replace->{options}{name} );
|
||||
|
||||
return $self->sendError( $req, 'Invalid input: name is not a string', 400 )
|
||||
if ( ref $replace->{options}{name} );
|
||||
|
||||
$self->logger->debug(
|
||||
"[API] Menu application $appConfKey from category $catConfKey configuration replace requested"
|
||||
);
|
||||
|
||||
# Get latest configuration
|
||||
my $conf = $self->_confAcc->getConf( { noCache => 1 } );
|
||||
|
||||
# Return 404 if not found
|
||||
|
||||
return $self->sendError( $req,
|
||||
"Menu category '$catConfKey' not found", 404 )
|
||||
unless ( defined $self->_getMenuCatByConfKey( $conf, $catConfKey ) );
|
||||
|
||||
return $self->sendError(
|
||||
$req,
|
||||
"Menu application '$appConfKey' from category '$catConfKey' not found",
|
||||
404
|
||||
)
|
||||
unless (
|
||||
defined $self->_getMenuAppByConfKey( $conf, $catConfKey, $appConfKey )
|
||||
);
|
||||
|
||||
my $res =
|
||||
$self->_pushMenuApp( $conf, $catConfKey, $appConfKey, $replace, 1 );
|
||||
return $self->sendError( $req, $res->{msg}, 400 )
|
||||
unless ( $res->{res} eq 'ok' );
|
||||
|
||||
return $self->sendJSONresponse( $req, undef, code => 204 );
|
||||
}
|
||||
|
||||
sub deleteMenuApp {
|
||||
my ( $self, $req ) = @_;
|
||||
|
||||
my $catConfKey = $req->params('confKey')
|
||||
or return $self->sendError( $req, 'Category confKey is missing', 400 );
|
||||
|
||||
my $appConfKey = $req->params('appConfKey')
|
||||
or return $self->sendError( $req, 'Application confKey is missing', 400 );
|
||||
|
||||
$self->logger->debug(
|
||||
"[API] Menu Application $appConfKey from category $catConfKey configuration delete requested"
|
||||
);
|
||||
|
||||
# Get latest configuration
|
||||
my $conf = $self->_confAcc->getConf( { noCache => 1 } );
|
||||
|
||||
return $self->sendError( $req,
|
||||
"Menu category '$catConfKey' not found", 404 )
|
||||
unless ( defined $self->_getMenuCatByConfKey( $conf, $catConfKey ) );
|
||||
|
||||
my $delete = $self->_getMenuAppByConfKey( $conf, $catConfKey, $appConfKey );
|
||||
|
||||
# Return 404 if not found
|
||||
|
||||
return $self->sendError( $req,
|
||||
"Menu category '$appConfKey' not found", 404 )
|
||||
unless ( defined $delete );
|
||||
|
||||
delete $conf->{applicationList}->{$catConfKey}->{$appConfKey};
|
||||
|
||||
# Save configuration
|
||||
$self->_confAcc->saveConf($conf);
|
||||
|
||||
return $self->sendJSONresponse( $req, undef, code => 204 );
|
||||
}
|
||||
|
||||
sub _isCatApp {
|
||||
my ( $self, $candidate ) = @_;
|
||||
|
||||
# Check if candidate is a hash, has "type" defined and if "type" equals "application".
|
||||
return
|
||||
ref $candidate eq ref {}
|
||||
&& defined $candidate->{type}
|
||||
&& $candidate->{type} eq 'application';
|
||||
}
|
||||
|
||||
sub _getMenuAppByConfKey {
|
||||
my ( $self, $conf, $catConfKey, $appConfKey ) = @_;
|
||||
|
||||
# Check if catConfKey is defined
|
||||
return undef unless ( defined $conf->{applicationList}->{$catConfKey} );
|
||||
|
||||
# Check if appConfKey is defined
|
||||
return undef
|
||||
unless ( defined $conf->{applicationList}->{$catConfKey}->{$appConfKey} );
|
||||
|
||||
my $cat = $conf->{applicationList}->{$catConfKey};
|
||||
|
||||
my $menuApp = { confKey => $appConfKey };
|
||||
|
||||
$menuApp->{order} = $cat->{$appConfKey}->{order}
|
||||
if ( defined $cat->{$appConfKey}->{order} );
|
||||
|
||||
# Get options
|
||||
my $options = {};
|
||||
for my $configOption ( keys %{ $cat->{$appConfKey}->{options} } ) {
|
||||
$options->{ $self->_translateOptionConfToApi($configOption) } =
|
||||
$cat->{$appConfKey}->{options}->{$configOption};
|
||||
}
|
||||
|
||||
$menuApp->{options} = $options;
|
||||
|
||||
return $menuApp;
|
||||
}
|
||||
|
||||
sub _pushMenuApp {
|
||||
my ( $self, $conf, $catConfKey, $appConfKey, $push, $replace ) = @_;
|
||||
|
||||
if ($replace) {
|
||||
$conf->{applicationList}->{$catConfKey}->{$appConfKey} = {};
|
||||
$conf->{applicationList}->{$catConfKey}->{$appConfKey}->{type} =
|
||||
"application";
|
||||
$conf->{applicationList}->{$catConfKey}->{$appConfKey}->{options} = {};
|
||||
$conf->{applicationList}->{$catConfKey}->{$appConfKey}->{options}
|
||||
->{display} = "auto";
|
||||
$conf->{applicationList}->{$catConfKey}->{$appConfKey}->{options}
|
||||
->{logo} = "network.png";
|
||||
}
|
||||
|
||||
$conf->{applicationList}->{$catConfKey}->{$appConfKey}->{order} =
|
||||
$push->{order}
|
||||
if ( defined $push->{order} );
|
||||
|
||||
if ( defined $push->{options} ) {
|
||||
foreach ( keys %{ $push->{options} } ) {
|
||||
$conf->{applicationList}->{$catConfKey}->{$appConfKey}->{options}
|
||||
->{$_} = $push->{options}->{$_};
|
||||
}
|
||||
}
|
||||
|
||||
# Test new configuration
|
||||
my $parser = Lemonldap::NG::Manager::Conf::Parser->new( {
|
||||
refConf => $self->_confAcc->getConf,
|
||||
newConf => $conf,
|
||||
req => {},
|
||||
}
|
||||
);
|
||||
unless ( $parser->testNewConf( $self->p ) ) {
|
||||
return {
|
||||
res => 'ko',
|
||||
code => 400,
|
||||
msg => "Configuration error: "
|
||||
. join( ". ", map { $_->{message} } @{ $parser->errors } ),
|
||||
};
|
||||
}
|
||||
|
||||
# Save configuration
|
||||
$self->_confAcc->saveConf($conf);
|
||||
|
||||
return { res => 'ok' };
|
||||
}
|
||||
|
||||
1;
|
270
lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Api/Menu/Cat.pm
Normal file
270
lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Api/Menu/Cat.pm
Normal file
|
@ -0,0 +1,270 @@
|
|||
package Lemonldap::NG::Manager::Api::Menu::Cat;
|
||||
|
||||
our $VERSION = '2.0.9';
|
||||
|
||||
package Lemonldap::NG::Manager::Api;
|
||||
|
||||
use 5.10.0;
|
||||
use utf8;
|
||||
use Mouse;
|
||||
use Lemonldap::NG::Manager::Conf::Parser;
|
||||
|
||||
extends 'Lemonldap::NG::Manager::Api::Common';
|
||||
|
||||
sub getMenuCatByConfKey {
|
||||
my ( $self, $req ) = @_;
|
||||
|
||||
my $confKey = $req->params('confKey')
|
||||
or return $self->sendError( $req, 'confKey is missing', 400 );
|
||||
|
||||
$self->logger->debug(
|
||||
"[API] Menu Category $confKey configuration requested");
|
||||
|
||||
# Get latest configuration
|
||||
my $conf = $self->_confAcc->getConf;
|
||||
|
||||
my $menuCat = $self->_getMenuCatByConfKey( $conf, $confKey );
|
||||
|
||||
# Return 404 if not found
|
||||
return $self->sendError( $req, "Menu category '$confKey' not found", 404 )
|
||||
unless ( defined $menuCat );
|
||||
|
||||
return $self->sendJSONresponse( $req, $menuCat );
|
||||
}
|
||||
|
||||
sub findMenuCatByConfKey {
|
||||
my ( $self, $req ) = @_;
|
||||
|
||||
my $pattern = (
|
||||
defined $req->params('uPattern')
|
||||
? $req->params('uPattern')
|
||||
: ( defined $req->params('pattern') ? $req->params('pattern') : undef )
|
||||
);
|
||||
|
||||
return $self->sendError( $req, 'Invalid input: pattern is missing', 400 )
|
||||
unless ( defined $pattern );
|
||||
|
||||
unless ( $pattern = $self->_getRegexpFromPattern($pattern) ) {
|
||||
return $self->sendError( $req, 'Invalid input: pattern is invalid',
|
||||
400 );
|
||||
}
|
||||
|
||||
$self->logger->debug(
|
||||
"[API] Find Menu Categories by confKey regexp $pattern requested");
|
||||
|
||||
# Get latest configuration
|
||||
my $conf = $self->_confAcc->getConf;
|
||||
|
||||
my @menuCats =
|
||||
map { $_ =~ $pattern ? $self->_getMenuCatByConfKey( $conf, $_ ) : () }
|
||||
keys %{ $conf->{applicationList} };
|
||||
|
||||
return $self->sendJSONresponse( $req, [@menuCats] );
|
||||
}
|
||||
|
||||
sub addMenuCat {
|
||||
my ( $self, $req ) = @_;
|
||||
my $add = $req->jsonBodyToObj;
|
||||
|
||||
return $self->sendError( $req, "Invalid input: " . $req->error, 400 )
|
||||
unless ($add);
|
||||
|
||||
return $self->sendError( $req, 'Invalid input: confKey is missing', 400 )
|
||||
unless ( defined $add->{confKey} );
|
||||
|
||||
return $self->sendError( $req, 'Invalid input: confKey is not a string',
|
||||
400 )
|
||||
if ( ref $add->{confKey} );
|
||||
|
||||
return $self->sendError( $req, 'Invalid input: confKey contains invalid characters',
|
||||
400 )
|
||||
unless ( $add->{confKey} =~ '^\w[\w\.\-]*$' );
|
||||
|
||||
return $self->sendError( $req, 'Invalid input: catname is missing', 400 )
|
||||
unless ( defined $add->{catname} );
|
||||
|
||||
return $self->sendError( $req, 'Invalid input: catname is not a string',
|
||||
400 )
|
||||
if ( ref $add->{catname} );
|
||||
|
||||
$self->logger->debug(
|
||||
"[API] Add Menu Category with confKey $add->{confKey} requested");
|
||||
|
||||
# Get latest configuration
|
||||
my $conf = $self->_confAcc->getConf( { noCache => 1 } );
|
||||
|
||||
return $self->sendError(
|
||||
$req,
|
||||
"Invalid input: A Menu Category with confKey $add->{confKey} already exists",
|
||||
409
|
||||
) if ( defined $self->_getMenuCatByConfKey( $conf, $add->{confKey} ) );
|
||||
|
||||
my $res = $self->_pushMenuCat( $conf, $add->{confKey}, $add, 1 );
|
||||
|
||||
return $self->sendError( $req, $res->{msg}, 400 )
|
||||
unless ( $res->{res} eq 'ok' );
|
||||
|
||||
return $self->sendJSONresponse(
|
||||
$req,
|
||||
{ message => "Successful operation" },
|
||||
code => 201
|
||||
);
|
||||
}
|
||||
|
||||
sub updateMenuCat {
|
||||
my ( $self, $req ) = @_;
|
||||
my $confKey = $req->params('confKey')
|
||||
or return $self->sendError( $req, 'confKey is missing', 400 );
|
||||
|
||||
my $update = $req->jsonBodyToObj;
|
||||
|
||||
return $self->sendError( $req, "Invalid input: " . $req->error, 400 )
|
||||
unless ($update);
|
||||
|
||||
$self->logger->debug(
|
||||
"[API] Menu Category $confKey configuration update requested");
|
||||
|
||||
# Get latest configuration
|
||||
my $conf = $self->_confAcc->getConf( { noCache => 1 } );
|
||||
|
||||
my $current = $self->_getMenuCatByConfKey( $conf, $confKey );
|
||||
|
||||
# Return 404 if not found
|
||||
|
||||
return $self->sendError( $req, "Menu category '$confKey' not found", 404 )
|
||||
unless ( defined $current );
|
||||
|
||||
my $res = $self->_pushMenuCat( $conf, $confKey, $update, 0 );
|
||||
|
||||
return $self->sendError( $req, $res->{msg}, 400 )
|
||||
unless ( $res->{res} eq 'ok' );
|
||||
|
||||
return $self->sendJSONresponse( $req, undef, code => 204 );
|
||||
}
|
||||
|
||||
sub replaceMenuCat {
|
||||
my ( $self, $req ) = @_;
|
||||
my $confKey = $req->params('confKey')
|
||||
or return $self->sendError( $req, 'confKey is missing', 400 );
|
||||
|
||||
my $replace = $req->jsonBodyToObj;
|
||||
|
||||
return $self->sendError( $req, "Invalid input: " . $req->error, 400 )
|
||||
unless ($replace);
|
||||
|
||||
return $self->sendError( $req, 'Invalid input: confKey is missing', 400 )
|
||||
unless ( defined $replace->{confKey} );
|
||||
|
||||
return $self->sendError( $req, 'Invalid input: confKey is not a string',
|
||||
400 )
|
||||
if ( ref $replace->{confKey} );
|
||||
|
||||
return $self->sendError( $req, 'Invalid input: confKey contains invalid characters',
|
||||
400 )
|
||||
unless ( $replace->{confKey} =~ '^\w[\w\.\-]*$' );
|
||||
|
||||
return $self->sendError( $req, 'Invalid input: catname is missing', 400 )
|
||||
unless ( defined $replace->{catname} );
|
||||
|
||||
return $self->sendError( $req, 'Invalid input: catname is not a string',
|
||||
400 )
|
||||
if ( ref $replace->{catname} );
|
||||
|
||||
$self->logger->debug(
|
||||
"[API] Menu Category $confKey configuration replace requested");
|
||||
|
||||
# Get latest configuration
|
||||
my $conf = $self->_confAcc->getConf( { noCache => 1 } );
|
||||
|
||||
# Return 404 if not found
|
||||
|
||||
return $self->sendError( $req, "Menu category '$confKey' not found", 404 )
|
||||
unless ( defined $self->_getMenuCatByConfKey( $conf, $confKey ) );
|
||||
|
||||
my $res = $self->_pushMenuCat( $conf, $confKey, $replace, 1 );
|
||||
return $self->sendError( $req, $res->{msg}, 400 )
|
||||
unless ( $res->{res} eq 'ok' );
|
||||
|
||||
return $self->sendJSONresponse( $req, undef, code => 204 );
|
||||
}
|
||||
|
||||
sub deleteMenuCat {
|
||||
my ( $self, $req ) = @_;
|
||||
my $confKey = $req->params('confKey')
|
||||
or return $self->sendError( $req, 'confKey is missing', 400 );
|
||||
|
||||
$self->logger->debug(
|
||||
"[API] Menu Category $confKey configuration delete requested");
|
||||
|
||||
# Get latest configuration
|
||||
my $conf = $self->_confAcc->getConf( { noCache => 1 } );
|
||||
|
||||
my $delete = $self->_getMenuCatByConfKey( $conf, $confKey );
|
||||
|
||||
# Return 404 if not found
|
||||
|
||||
return $self->sendError( $req, "Menu category '$confKey' not found", 404 )
|
||||
unless ( defined $delete );
|
||||
|
||||
delete $conf->{applicationList}->{$confKey};
|
||||
|
||||
# Save configuration
|
||||
$self->_confAcc->saveConf($conf);
|
||||
|
||||
return $self->sendJSONresponse( $req, undef, code => 204 );
|
||||
}
|
||||
|
||||
sub _getMenuCatByConfKey {
|
||||
my ( $self, $conf, $confKey ) = @_;
|
||||
|
||||
# Check if confKey is defined
|
||||
return undef unless ( defined $conf->{applicationList}->{$confKey} );
|
||||
|
||||
my $menuCat = {
|
||||
confKey => $confKey,
|
||||
catname => $conf->{applicationList}->{$confKey}->{catname}
|
||||
};
|
||||
|
||||
$menuCat->{order} = $conf->{applicationList}->{$confKey}->{order}
|
||||
if ( defined $conf->{applicationList}->{$confKey}->{order} );
|
||||
|
||||
return $menuCat;
|
||||
}
|
||||
|
||||
sub _pushMenuCat {
|
||||
my ( $self, $conf, $confKey, $push, $replace ) = @_;
|
||||
|
||||
if ($replace) {
|
||||
$conf->{applicationList}->{$confKey} = {};
|
||||
$conf->{applicationList}->{$confKey}->{type} = "category";
|
||||
}
|
||||
|
||||
$conf->{applicationList}->{$confKey}->{order} = $push->{order}
|
||||
if ( defined $push->{order} );
|
||||
|
||||
$conf->{applicationList}->{$confKey}->{catname} = $push->{catname}
|
||||
if ( defined $push->{catname} );
|
||||
|
||||
# Test new configuration
|
||||
my $parser = Lemonldap::NG::Manager::Conf::Parser->new( {
|
||||
refConf => $self->_confAcc->getConf,
|
||||
newConf => $conf,
|
||||
req => {},
|
||||
}
|
||||
);
|
||||
unless ( $parser->testNewConf( $self->p ) ) {
|
||||
return {
|
||||
res => 'ko',
|
||||
code => 400,
|
||||
msg => "Configuration error: "
|
||||
. join( ". ", map { $_->{message} } @{ $parser->errors } ),
|
||||
};
|
||||
}
|
||||
|
||||
# Save configuration
|
||||
$self->_confAcc->saveConf($conf);
|
||||
|
||||
return { res => 'ok' };
|
||||
}
|
||||
|
||||
1;
|
515
lemonldap-ng-manager/t/04-menu-api.t
Normal file
515
lemonldap-ng-manager/t/04-menu-api.t
Normal file
|
@ -0,0 +1,515 @@
|
|||
# Test Providers API
|
||||
|
||||
use Test::More;
|
||||
use strict;
|
||||
use JSON;
|
||||
use IO::String;
|
||||
require 't/test-lib.pm';
|
||||
|
||||
our $_json = JSON->new->allow_nonref;
|
||||
|
||||
sub check201 {
|
||||
my ( $test, $res ) = splice @_;
|
||||
|
||||
#diag Dumper($res);
|
||||
is( $res->[0], "201", "$test: Result code is 201" )
|
||||
or diag explain $res->[2];
|
||||
count(1);
|
||||
checkJson( $test, $res );
|
||||
}
|
||||
|
||||
sub check204 {
|
||||
my ( $test, $res ) = splice @_;
|
||||
|
||||
#diag Dumper($res);
|
||||
is( $res->[0], "204", "$test: Result code is 204" )
|
||||
or diag explain $res->[2];
|
||||
count(1);
|
||||
is( $res->[2]->[0], undef, "204 code returns no content" );
|
||||
}
|
||||
|
||||
sub check200 {
|
||||
my ( $test, $res ) = splice @_;
|
||||
|
||||
#diag Dumper($res);
|
||||
is( $res->[0], "200", "$test: Result code is 200" )
|
||||
or diag explain $res->[2];
|
||||
count(1);
|
||||
checkJson( $test, $res );
|
||||
|
||||
}
|
||||
|
||||
sub check409 {
|
||||
my ( $test, $res ) = splice @_;
|
||||
|
||||
#diag Dumper($res);
|
||||
is( $res->[0], "409", "$test: Result code is 409" )
|
||||
or diag explain $res->[2];
|
||||
count(1);
|
||||
checkJson( $test, $res );
|
||||
}
|
||||
|
||||
sub check404 {
|
||||
my ( $test, $res ) = splice @_;
|
||||
|
||||
#diag Dumper($res);
|
||||
is( $res->[0], "404", "$test: Result code is 404" )
|
||||
or diag explain $res->[2];
|
||||
count(1);
|
||||
checkJson( $test, $res );
|
||||
}
|
||||
|
||||
sub check400 {
|
||||
my ( $test, $res ) = splice @_;
|
||||
is( $res->[0], "400", "$test: Result code is 400" )
|
||||
or diag explain $res->[2];
|
||||
count(1);
|
||||
count(1);
|
||||
checkJson( $test, $res );
|
||||
}
|
||||
|
||||
sub checkJson {
|
||||
my ( $test, $res ) = splice @_;
|
||||
my $key;
|
||||
|
||||
#diag Dumper($res->[2]->[0]);
|
||||
ok( $key = from_json( $res->[2]->[0] ), "$test: Response is JSON" );
|
||||
count(1);
|
||||
}
|
||||
|
||||
sub add {
|
||||
my ( $test, $type, $obj ) = splice @_;
|
||||
my $j = $_json->encode($obj);
|
||||
my $res;
|
||||
|
||||
#diag Dumper($j);
|
||||
ok(
|
||||
$res = &client->_post(
|
||||
"/api/v1/menu/$type", '',
|
||||
IO::String->new($j), 'application/json',
|
||||
length($j)
|
||||
),
|
||||
"$test: Request succeed"
|
||||
);
|
||||
count(1);
|
||||
return $res;
|
||||
}
|
||||
|
||||
sub checkAdd {
|
||||
my ( $test, $type, $add ) = splice @_;
|
||||
check201( $test, add( $test, $type, $add ) );
|
||||
}
|
||||
|
||||
sub checkAddNotFound {
|
||||
my ( $test, $type, $add ) = splice @_;
|
||||
check404( $test, add( $test, $type, $add ) );
|
||||
}
|
||||
|
||||
sub checkAddFailsIfExists {
|
||||
my ( $test, $type, $add ) = splice @_;
|
||||
check409( $test, add( $test, $type, $add ) );
|
||||
}
|
||||
|
||||
sub checkAddFailsOnInvalidConfkey {
|
||||
my ( $test, $type, $add ) = splice @_;
|
||||
check400( $test, add( $test, $type, $add ) );
|
||||
}
|
||||
|
||||
sub get {
|
||||
my ( $test, $type, $confKey ) = splice @_;
|
||||
my $res;
|
||||
ok( $res = &client->_get( "/api/v1/menu/$type/$confKey", '' ),
|
||||
"$test: Request succeed" );
|
||||
count(1);
|
||||
return $res;
|
||||
}
|
||||
|
||||
sub checkGet {
|
||||
my ( $test, $type, $confKey, $attrPath, $expectedValue ) = splice @_;
|
||||
my $res = get( $test, $type, $confKey );
|
||||
check200( $test, $res );
|
||||
my @path = split '/', $attrPath;
|
||||
my $key = from_json( $res->[2]->[0] );
|
||||
for (@path) {
|
||||
if ( ref($key) eq 'ARRAY' ) {
|
||||
$key = $key->[$_];
|
||||
}
|
||||
else {
|
||||
$key = $key->{$_};
|
||||
}
|
||||
}
|
||||
ok(
|
||||
$key eq $expectedValue,
|
||||
"$test: check if $attrPath value \"$key\" matches expected value \"$expectedValue\""
|
||||
);
|
||||
count(1);
|
||||
}
|
||||
|
||||
sub checkGetNotFound {
|
||||
my ( $test, $type, $confKey ) = splice @_;
|
||||
check404( $test, get( $test, $type, $confKey ) );
|
||||
}
|
||||
|
||||
sub checkGetList {
|
||||
my ( $test, $type, $confKey, $expectedHits ) = splice @_;
|
||||
my $res = get( $test, $type, $confKey );
|
||||
check200( $test, $res );
|
||||
my $hits = from_json( $res->[2]->[0] );
|
||||
my $counter = @{$hits};
|
||||
ok(
|
||||
$counter eq $expectedHits,
|
||||
"$test: check if nb of hits returned ($counter) matches expectation ($expectedHits)"
|
||||
);
|
||||
count(1);
|
||||
}
|
||||
|
||||
sub update {
|
||||
my ( $test, $type, $confKey, $obj ) = splice @_;
|
||||
my $j = $_json->encode($obj);
|
||||
|
||||
#diag Dumper($j);
|
||||
my $res;
|
||||
ok(
|
||||
$res = &client->_patch(
|
||||
"/api/v1/menu/$type/$confKey", '',
|
||||
IO::String->new($j), 'application/json',
|
||||
length($j)
|
||||
),
|
||||
"$test: Request succeed"
|
||||
);
|
||||
count(1);
|
||||
return $res;
|
||||
}
|
||||
|
||||
sub checkUpdate {
|
||||
my ( $test, $type, $confKey, $update ) = splice @_;
|
||||
check204( $test, update( $test, $type, $confKey, $update ) );
|
||||
}
|
||||
|
||||
sub checkUpdateNotFound {
|
||||
my ( $test, $type, $confKey, $update ) = splice @_;
|
||||
check404( $test, update( $test, $type, $confKey, $update ) );
|
||||
}
|
||||
|
||||
sub checkUpdateFailsIfExists {
|
||||
my ( $test, $type, $confKey, $update ) = splice @_;
|
||||
check409( $test, update( $test, $type, $confKey, $update ) );
|
||||
}
|
||||
|
||||
sub checkUpdateWithUnknownAttributes {
|
||||
my ( $test, $type, $confKey, $update ) = splice @_;
|
||||
check400( $test, update( $test, $type, $confKey, $update ) );
|
||||
}
|
||||
|
||||
sub replace {
|
||||
my ( $test, $type, $confKey, $obj ) = splice @_;
|
||||
my $j = $_json->encode($obj);
|
||||
my $res;
|
||||
ok(
|
||||
$res = &client->_put(
|
||||
"/api/v1/menu/$type/$confKey", '',
|
||||
IO::String->new($j), 'application/json',
|
||||
length($j)
|
||||
),
|
||||
"$test: Request succeed"
|
||||
);
|
||||
count(1);
|
||||
return $res;
|
||||
}
|
||||
|
||||
sub checkReplace {
|
||||
my ( $test, $type, $confKey, $replace ) = splice @_;
|
||||
check204( $test, replace( $test, $type, $confKey, $replace ) );
|
||||
}
|
||||
|
||||
sub checkReplaceAlreadyThere {
|
||||
my ( $test, $type, $confKey, $replace ) = splice @_;
|
||||
check400( $test, replace( $test, $type, $confKey, $replace ) );
|
||||
}
|
||||
|
||||
sub checkReplaceNotFound {
|
||||
my ( $test, $type, $confKey, $update ) = splice @_;
|
||||
check404( $test, replace( $test, $type, $confKey, $update ) );
|
||||
}
|
||||
|
||||
sub checkReplaceWithInvalidAttribute {
|
||||
my ( $test, $type, $confKey, $replace ) = splice @_;
|
||||
check400( $test, replace( $test, $type, $confKey, $replace ) );
|
||||
}
|
||||
|
||||
sub findByConfKey {
|
||||
my ( $test, $type, $confKey ) = splice @_;
|
||||
my $res;
|
||||
ok(
|
||||
$res = &client->_get(
|
||||
"/api/v1/menu/$type/findByConfKey",
|
||||
"pattern=$confKey"
|
||||
),
|
||||
"$test: Request succeed"
|
||||
);
|
||||
count(1);
|
||||
return $res;
|
||||
}
|
||||
|
||||
sub checkFindByConfKeyError {
|
||||
my ( $test, $type, $pattern ) = splice @_;
|
||||
my $res = findByConfKey( $test, $type, $pattern );
|
||||
check400( $test, $res );
|
||||
}
|
||||
|
||||
sub checkFindByConfKey {
|
||||
my ( $test, $type, $confKey, $expectedHits ) = splice @_;
|
||||
my $res = findByConfKey( $test, $type, $confKey );
|
||||
check200( $test, $res );
|
||||
my $hits = from_json( $res->[2]->[0] );
|
||||
my $counter = @{$hits};
|
||||
ok(
|
||||
$counter eq $expectedHits,
|
||||
"$test: check if nb of hits returned ($counter) matches expectation ($expectedHits)"
|
||||
);
|
||||
count(1);
|
||||
}
|
||||
|
||||
sub deleteMenu {
|
||||
my ( $test, $type, $confKey ) = splice @_;
|
||||
my $res;
|
||||
ok(
|
||||
$res = &client->_del(
|
||||
"/api/v1/menu/$type/$confKey", '', '', 'application/json', 0
|
||||
),
|
||||
"$test: Request succeed"
|
||||
);
|
||||
count(1);
|
||||
return $res;
|
||||
}
|
||||
|
||||
sub checkDelete {
|
||||
my ( $test, $type, $confKey ) = splice @_;
|
||||
check204( $test, deleteMenu( $test, $type, $confKey ) );
|
||||
}
|
||||
|
||||
sub checkDeleteNotFound {
|
||||
my ( $test, $type, $confKey ) = splice @_;
|
||||
check404( $test, deleteMenu( $test, $type, $confKey ) );
|
||||
}
|
||||
|
||||
my $test;
|
||||
|
||||
my $cat1 = {
|
||||
confKey => 'mycat1',
|
||||
catname => 'My Cat 1',
|
||||
order => 1
|
||||
};
|
||||
my $cat2 = {
|
||||
confKey => 'mycat2',
|
||||
catname => 'My Cat 2',
|
||||
order => 2
|
||||
};
|
||||
my $cat3 = {
|
||||
confKey => 'mycat/mycat3',
|
||||
catname => 'My Cat 3',
|
||||
order => 2
|
||||
};
|
||||
$test = "Cat - Get mycat1 cat should err on not found";
|
||||
checkGetNotFound( $test, 'cat', 'mycat1' );
|
||||
|
||||
$test = "Cat - Add should succeed";
|
||||
checkAdd( $test, 'cat', $cat1 );
|
||||
checkGet( $test, 'cat', 'mycat1', 'catname', 'My Cat 1' );
|
||||
checkGet( $test, 'cat', 'mycat1', 'order', 1 );
|
||||
|
||||
$test = "Cat - Add should fail on duplicate confKey";
|
||||
checkAddFailsIfExists( $test, 'cat', $cat1 );
|
||||
|
||||
$test = "Cat - Add should fail on invalid confKey";
|
||||
checkAddFailsOnInvalidConfkey( $test, 'cat', $cat3 );
|
||||
|
||||
checkAddFailsOnInvalidConfkey
|
||||
|
||||
$test = "Cat - Update should succeed and keep existing values";
|
||||
$cat1->{order} = 3;
|
||||
delete $cat1->{catname};
|
||||
checkUpdate( $test, 'cat', 'mycat1', $cat1 );
|
||||
checkGet( $test, 'cat', 'mycat1', 'catname', 'My Cat 1' );
|
||||
checkGet( $test, 'cat', 'mycat1', 'order', 3 );
|
||||
|
||||
$test = "Cat - Update should fail if confKey not found";
|
||||
$cat1->{confKey} = 'mycat3';
|
||||
checkUpdateNotFound( $test, 'cat', 'mycat3', $cat1 );
|
||||
|
||||
$test = "Cat - 2nd add should succeed";
|
||||
checkAdd( $test, 'cat', $cat2 );
|
||||
|
||||
$test = "Cat - Replace should succeed";
|
||||
delete $cat2->{order};
|
||||
checkReplace( $test, 'cat', 'mycat2', $cat2 );
|
||||
|
||||
$test = "Cat - Replace should fail if confKey not found";
|
||||
$cat2->{confKey} = 'mycat3';
|
||||
checkReplaceNotFound( $test, 'cat', 'mycat3', $cat2 );
|
||||
|
||||
$test = "Cat - FindByConfKey should find 2 hits";
|
||||
checkFindByConfKey( $test, 'cat', 'mycat', 2 );
|
||||
|
||||
$test = "Cat - FindByConfKey should find 1 hits";
|
||||
checkFindByConfKey( $test, 'cat', 'mycat1', 1 );
|
||||
|
||||
$test = "Cat - FindByConfKey should find 1 hits";
|
||||
checkFindByConfKey( $test, 'cat', 'mycat2', 1 );
|
||||
|
||||
$test = "Cat - FindByConfKey should find 0 hits";
|
||||
checkFindByConfKey( $test, 'cat', 'mycat3', 0 );
|
||||
|
||||
$test = "Cat - FindByConfKey should err on invalid patterns";
|
||||
checkFindByConfKeyError( $test, 'cat', '' );
|
||||
checkFindByConfKeyError( $test, 'cat', '$' );
|
||||
|
||||
my $app1 = {
|
||||
confKey => 'myapp1',
|
||||
options => {
|
||||
name => 'My App 1',
|
||||
description => 'My app 1 description',
|
||||
tooltip => 'My app 1 tooltip',
|
||||
uri => 'http://app1.example.com/'
|
||||
},
|
||||
order => 1
|
||||
};
|
||||
my $app2 = {
|
||||
confKey => 'myapp2',
|
||||
options => {
|
||||
name => 'My App 2',
|
||||
description => 'My app 2 description',
|
||||
display => 'enabled',
|
||||
logo => 'demo.png',
|
||||
tooltip => 'My app 2 tooltip',
|
||||
uri => 'http://app2.example.com/'
|
||||
},
|
||||
order => 2
|
||||
};
|
||||
my $app3 = {
|
||||
confKey => 'myapp3',
|
||||
options => {
|
||||
name => 'My App 3',
|
||||
description => 'My app 3 description',
|
||||
display => "\$uid eq 'dwho'",
|
||||
logo => 'attach.png',
|
||||
tooltip => 'My app 3 tooltip',
|
||||
uri => 'http://app3.example.com/'
|
||||
},
|
||||
order => 1
|
||||
};
|
||||
my $app4 = {
|
||||
confKey => 'myapp1/myapp4',
|
||||
options => {
|
||||
name => 'My App 4',
|
||||
description => 'My app 4 description',
|
||||
tooltip => 'My app 4 tooltip',
|
||||
uri => 'http://app4.example.com/'
|
||||
},
|
||||
order => 1
|
||||
};
|
||||
|
||||
$test = "App - Get mycat3 apps should err on not found";
|
||||
checkGetNotFound( $test, 'app', 'mycat3' );
|
||||
|
||||
$test = "App - Get app myapp1 from existing mycat2 should err on not found";
|
||||
checkGetNotFound( $test, 'app/mycat2', 'myapp1' );
|
||||
|
||||
$test = "App - Get app myapp1 from mycat3 should err on not found";
|
||||
checkGetNotFound( $test, 'app/mycat3', 'myapp1' );
|
||||
|
||||
$test = "App - Add app myapp1 to mycat3 should err on not found";
|
||||
checkAddNotFound( $test, 'app/mycat3', $app1);
|
||||
|
||||
$test = "App - Add app1 to cat1 should succeed";
|
||||
checkAdd( $test, 'app/mycat1', $app1 );
|
||||
checkGet( $test, 'app/mycat1', 'myapp1', 'order', '1' );
|
||||
checkGet( $test, 'app/mycat1', 'myapp1', 'options/name', 'My App 1' );
|
||||
checkGet( $test, 'app/mycat1', 'myapp1', 'options/description',
|
||||
'My app 1 description' );
|
||||
checkGet( $test, 'app/mycat1', 'myapp1', 'options/tooltip',
|
||||
'My app 1 tooltip' );
|
||||
checkGet( $test, 'app/mycat1', 'myapp1', 'options/uri',
|
||||
'http://app1.example.com/' );
|
||||
|
||||
$test = "App - Add app2 to cat1 should succeed";
|
||||
checkAdd( $test, 'app/mycat1', $app2 );
|
||||
checkGet( $test, 'app/mycat1', 'myapp2', 'order', '2' );
|
||||
checkGet( $test, 'app/mycat1', 'myapp2', 'options/name', 'My App 2' );
|
||||
checkGet( $test, 'app/mycat1', 'myapp2', 'options/logo', 'demo.png' );
|
||||
|
||||
$test = "App - Add app3 to cat2 should succeed";
|
||||
checkAdd( $test, 'app/mycat2', $app3 );
|
||||
checkGet( $test, 'app/mycat2', 'myapp3', 'order', '1' );
|
||||
checkGet( $test, 'app/mycat2', 'myapp3', 'options/display', "\$uid eq 'dwho'" );
|
||||
|
||||
$test = "App - Add should fail on duplicate confKey";
|
||||
checkAddFailsIfExists( $test, 'app/mycat1', $app1 );
|
||||
|
||||
$test = "App - Add should fail on invalid confKey";
|
||||
checkAddFailsOnInvalidConfkey( $test, 'app/mycat1', $app4 );
|
||||
|
||||
$test = "App - Check default value were set";
|
||||
checkGet( $test, 'app/mycat1', 'myapp1', 'options/logo', 'network.png' );
|
||||
checkGet( $test, 'app/mycat1', 'myapp1', 'options/display', 'auto' );
|
||||
|
||||
$test = "App - Category 1 should return 2 apps";
|
||||
checkGetList( $test, 'app', 'mycat1', 2 );
|
||||
|
||||
$test = "App - Category 2 should return 1 app";
|
||||
checkGetList( $test, 'app', 'mycat2', 1 );
|
||||
|
||||
$test = "App - FindByConfKey should find 2 hits";
|
||||
checkFindByConfKey( $test, 'app/mycat1', '*', 2 );
|
||||
|
||||
$test = "App - FindByConfKey should find 1 hit";
|
||||
checkFindByConfKey( $test, 'app/mycat1', 'app1', 1 );
|
||||
|
||||
$test = "App - FindByConfKey should err on invalid patterns";
|
||||
checkFindByConfKeyError( $test, 'app/mycat1', '' );
|
||||
checkFindByConfKeyError( $test, 'app/mycat1', '$' );
|
||||
|
||||
$test = "App - Update should succeed and keep existing values";
|
||||
$app1->{options}->{name} = 'My App 1 updated';
|
||||
delete $app1->{options}->{tooltip};
|
||||
delete $app1->{order};
|
||||
checkUpdate( $test, 'app/mycat1', 'myapp1', $app1 );
|
||||
checkGet( $test, 'app/mycat1', 'myapp1', 'options/name', 'My App 1 updated' );
|
||||
checkGet( $test, 'app/mycat1', 'myapp1', 'options/tooltip',
|
||||
'My app 1 tooltip' );
|
||||
checkGet( $test, 'app/mycat1', 'myapp1', 'order', 1 );
|
||||
|
||||
$test = "App - Update should fail if confKey not found";
|
||||
checkUpdateNotFound( $test, 'app/mycat4', 'myapp1', $app1 );
|
||||
$app1->{confKey} = 'myapp4';
|
||||
checkUpdateNotFound( $test, 'app/mycat1', 'myapp4', $app1 );
|
||||
|
||||
$test = "App - Replace should succeed";
|
||||
$app3->{options}->{name} = 'My App 3 updated';
|
||||
checkReplace( $test, 'app/mycat2', 'myapp3', $app3 );
|
||||
checkGet( $test, 'app/mycat2', 'myapp3', 'options/name', 'My App 3 updated' );
|
||||
|
||||
$test = "App - Replace should fail if confKey not found";
|
||||
checkReplaceNotFound( $test, 'app/mycat4', 'myapp3', $app3 );
|
||||
$app3->{confKey} = 'myapp4';
|
||||
checkReplaceNotFound( $test, 'app/mycat2', 'myapp4', $app3 );
|
||||
|
||||
$test = "App - Delete should succeed";
|
||||
checkDelete( $test, 'app/mycat1', 'myapp2' );
|
||||
|
||||
$test = "App - Entity should not be found after deletion";
|
||||
checkDeleteNotFound( $test, 'app/mycat1', 'myapp2' );
|
||||
|
||||
$test = "App - Category 1 should return 1 app";
|
||||
checkGetList( $test, 'app', 'mycat1', 1 );
|
||||
|
||||
$test = "Cat - Clean up";
|
||||
checkDelete( $test, 'cat', 'mycat1' );
|
||||
checkDelete( $test, 'cat', 'mycat2' );
|
||||
$test = "cat - Entity should not be found after clean up";
|
||||
checkDeleteNotFound( $test, 'cat', 'mycat1' );
|
||||
|
||||
# Clean up generated conf files, except for "lmConf-1.json"
|
||||
unlink grep { $_ ne "t/conf/lmConf-1.json" } glob "t/conf/lmConf-*.json";
|
||||
|
||||
done_testing();
|
Loading…
Reference in New Issue
Block a user