securis/src/main/java/net/curisit/securis/services/PackResource.java
.. .. @@ -1,6 +1,7 @@ 1 1 package net.curisit.securis.services; 2 2 3 3 import java.security.Principal; 4 +import java.util.ArrayList;4 5 import java.util.Date; 5 6 import java.util.HashSet; 6 7 import java.util.List; .. .. @@ -21,8 +22,10 @@ 21 22 import javax.ws.rs.Produces; 22 23 import javax.ws.rs.core.Context; 23 24 import javax.ws.rs.core.MediaType; 25 +import javax.ws.rs.core.MultivaluedMap;24 26 import javax.ws.rs.core.Response; 25 27 import javax.ws.rs.core.Response.Status; 28 +import javax.ws.rs.core.UriInfo;26 29 27 30 import org.apache.logging.log4j.LogManager; 28 31 import org.apache.logging.log4j.Logger; .. .. @@ -80,33 +83,63 @@ 80 83 @Path("/") 81 84 @Securable 82 85 @Produces({ MediaType.APPLICATION_JSON }) 83 - public Response index(@Context BasicSecurityContext bsc) {86 + public Response index(@Context UriInfo uriInfo, @Context BasicSecurityContext bsc) {84 87 LOG.info("Getting packs list "); 88 + MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters();85 89 86 90 // EntityManager em = emProvider.get(); 87 91 em.clear(); 88 92 93 + TypedQuery<Pack> q = createQuery(queryParams, bsc);94 + if (q == null) {95 + return Response.ok().build();96 + }97 +98 + List<Pack> list = q.getResultList();99 +100 + return Response.ok(list).build();101 + }102 +103 + private String generateWhereFromParams(boolean addWhere, MultivaluedMap<String, String> queryParams) {104 + List<String> conditions = new ArrayList<>();105 + if (queryParams.containsKey("organizationId")) {106 + conditions.add(String.format("pa.organization.id = %s", queryParams.getFirst("organizationId")));107 + }108 + if (queryParams.containsKey("applicationId")) {109 + conditions.add(String.format("pa.licenseType.application.id = %s", queryParams.getFirst("applicationId")));110 + }111 + if (queryParams.containsKey("licenseTypeId")) {112 + conditions.add(String.format("pa.licenseType.id = %s", queryParams.getFirst("licenseTypeId")));113 + }114 + String connector = addWhere ? " where " : " and ";115 + return (conditions.isEmpty() ? "" : connector) + String.join(" and ", conditions);116 + }117 +118 + private TypedQuery<Pack> createQuery(MultivaluedMap<String, String> queryParams, BasicSecurityContext bsc) {89 119 TypedQuery<Pack> q; 120 + String hql = "SELECT pa FROM Pack pa";90 121 if (bsc.isUserInRole(BasicSecurityContext.ROL_ADMIN)) { 91 - LOG.info("Getting all packs for user: " + bsc.getUserPrincipal());92 - q = em.createNamedQuery("list-packs", Pack.class);122 + hql += generateWhereFromParams(true, queryParams);123 + q = em.createQuery(hql, Pack.class);93 124 } else { 94 125 if (bsc.getApplicationsIds() == null || bsc.getApplicationsIds().isEmpty()) { 95 - return Response.ok().build();126 + return null;96 127 } 97 128 if (bsc.getOrganizationsIds() == null || bsc.getOrganizationsIds().isEmpty()) { 98 - q = em.createNamedQuery("list-packs-by-apps", Pack.class);129 + hql += " where pa.licenseType.application.id in :list_ids_app ";99 130 } else { 100 - q = em.createNamedQuery("list-packs-by-orgs-apps", Pack.class);131 + hql += " where pa.organization.id in :list_ids_org and pa.licenseType.application.id in :list_ids_app ";132 + }133 + hql += generateWhereFromParams(false, queryParams);134 + q = em.createQuery(hql, Pack.class);135 + if (hql.contains("list_ids_org")) {101 136 q.setParameter("list_ids_org", bsc.getOrganizationsIds()); 102 137 } 103 138 q.setParameter("list_ids_app", bsc.getApplicationsIds()); 104 139 LOG.info("Getting packs from orgs: {} and apps: {}", bsc.getOrganizationsIds(), bsc.getApplicationsIds()); 105 140 } 106 141 107 - List<Pack> list = q.getResultList();108 -109 - return Response.ok(list).build();142 + return q;110 143 } 111 144 112 145 private Response generateErrorUnathorizedAccess(Pack pack, Principal user) { securis/src/main/webapp/sql_update.sql
.. .. @@ -7,4 +7,5 @@ 7 7 application_id INT NOT NULL, 8 8 PRIMARY KEY (username, application_id)); 9 9 10 +update user set roles = 128 where username = '_client';10 11 securis/src/main/webapp/src/app/forms/license.form.component.ts
.. .. @@ -111,6 +111,9 @@ 111 111 this.router.navigate([`packs/${this.pack.id}/licenses`]); 112 112 } 113 113 114 + editPack(): void {115 + this.router.navigate([`packs/edit/${this.pack.id}`]);116 + }114 117 115 118 ngAfterViewInit(): void { 116 119 this.init(); securis/src/main/webapp/src/app/forms/license.form.html
.. .. @@ -8,7 +8,8 @@ 8 8 <button md-icon-button (click)="save()"><md-icon>save</md-icon></button> 9 9 <md-toolbar-row class="inner-padding" *ngIf="!!pack" > 10 10 <div> 11 - <span i18n>Pack</span>: {{pack.code}}11 + <span i18n>Pack</span>: {{pack.code}}12 + <button md-icon-button (click)="editPack()"><md-icon>edit</md-icon></button>12 13 </div> 13 14 <div class="inner-padding" flex="70" style="margin-left: 10px;" layout-align="start center" layout="row"> 14 15 <md-chip selected [mdTooltip]="$L.get('field.application_name')" color="primary">{{pack.application_name}} </md-chip> securis/src/main/webapp/src/app/listing/application.list.component.html
.. .. @@ -26,6 +26,9 @@ 26 26 <ng-template tdDataTableTemplate="menu" let-row="row" let-index="index"> 27 27 <div layout="row" layout-align="end center"> 28 28 <button md-icon-button (click)="edit(row.id)" color="primary"><md-icon>edit</md-icon></button> 29 + <button md-icon-button (click)="showRelatedPacks(row)" color="accent" [mdTooltip]="$L.get('Show related packs')">30 + <md-icon>arrow_forward</md-icon>31 + </button>29 32 </div> 30 33 </ng-template> 31 34 </td-data-table> securis/src/main/webapp/src/app/listing/application.list.component.ts
.. .. @@ -69,8 +69,8 @@ 69 69 } 70 70 71 71 72 - packAction(action: any) {73 - console.log(action.command);72 + showRelatedPacks(app : any) : void {73 + this.router.navigate(['packs/'], {queryParams: {applicationId: app.id, name: app.name}});74 74 } 75 75 76 76 isActionAvailable(pack : any) : boolean { securis/src/main/webapp/src/app/listing/license.list.component.html
.. .. @@ -5,6 +5,7 @@ 5 5 <md-icon>arrow_back</md-icon> 6 6 </button> 7 7 <span class="md-title" i18n>Licenses for pack</span>: {{pack?.code}} 8 + <button md-icon-button (click)="editPack()"><md-icon>edit</md-icon></button>8 9 </span> 9 10 <span class="push-left-sm" *ngIf="filteredItems < data.length"> 10 11 <span class="md-body-1">{{filteredItems}} of {{data.length}} packs filtered</span> securis/src/main/webapp/src/app/listing/license.list.component.ts
.. .. @@ -111,8 +111,13 @@ 111 111 112 112 goBack() : void { 113 113 this.router.navigate([`packs`]); 114 + }115 +116 + editPack(): void {117 + this.router.navigate([`packs/edit/${this.pack.id}`]);114 118 } 115 119 120 +116 121 isLicenseExpired(lic: any): boolean { 117 122 return lic.expiration_date < (new Date().getTime()); 118 123 } securis/src/main/webapp/src/app/listing/licensetype.list.component.html
.. .. @@ -26,6 +26,9 @@ 26 26 <ng-template tdDataTableTemplate="menu" let-row="row" let-index="index"> 27 27 <div layout="row" layout-align="end center"> 28 28 <button md-icon-button (click)="edit(row.id)" color="primary"><md-icon>edit</md-icon></button> 29 + <button md-icon-button (click)="showRelatedPacks(row)" color="accent" [mdTooltip]="$L.get('Show related packs')">30 + <md-icon>arrow_forward</md-icon>31 + </button>29 32 </div> 30 33 </ng-template> 31 34 </td-data-table> securis/src/main/webapp/src/app/listing/licensetype.list.component.ts
.. .. @@ -66,8 +66,8 @@ 66 66 } 67 67 68 68 69 - packAction(action: any) {70 - console.log(action.command);69 + showRelatedPacks(lt : any) : void {70 + this.router.navigate(['packs/'], {queryParams: {licenseTypeId: lt.id, name: lt.name}});71 71 } 72 72 73 73 isActionAvailable(pack : any) : boolean { securis/src/main/webapp/src/app/listing/organization.list.component.html
.. .. @@ -26,6 +26,9 @@ 26 26 <ng-template tdDataTableTemplate="menu" let-row="row" let-index="index"> 27 27 <div layout="row" layout-align="end center"> 28 28 <button md-icon-button (click)="edit(row.id)" color="primary"><md-icon>edit</md-icon></button> 29 + <button md-icon-button (click)="showRelatedPacks(row)" color="accent" [mdTooltip]="$L.get('Show related packs')">30 + <md-icon>arrow_forward</md-icon>31 + </button>29 32 </div> 30 33 </ng-template> 31 34 </td-data-table> securis/src/main/webapp/src/app/listing/organization.list.component.ts
.. .. @@ -64,12 +64,11 @@ 64 64 ); 65 65 } 66 66 67 -68 - packAction(action: any) {69 - console.log(action.command);67 + showRelatedPacks(org : any) : void {68 + this.router.navigate(['packs/'], {queryParams: {organizationId: org.id, name: org.name}});70 69 } 71 70 72 - isActionAvailable(pack : any) : boolean {71 + isActionAvailable(org : any) : boolean {73 72 return true; 74 73 } 75 74 securis/src/main/webapp/src/app/listing/pack.list.component.html
.. .. @@ -1,5 +1,8 @@ 1 1 <td-layout-card-over cardWidth="90"> 2 2 <md-toolbar role="toolbar" class="mat-secondary"> 3 + <button *ngIf="!!prevUrl" md-icon-button (click)="goBack()" color="accent">4 + <md-icon>arrow_back</md-icon>5 + </button>3 6 <span class="push-left-sm"> 4 7 <span class="md-title" i18n>Packs</span> 5 8 </span> .. .. @@ -11,6 +14,15 @@ 11 14 <button md-mini-fab color="accent" (click)="create()" [mdTooltip]="$L.get('Create a new pack')"> 12 15 <md-icon>add</md-icon> 13 16 </button> 17 + <md-toolbar-row *ngIf="!!filter_description">18 + <md-chip-list>19 + <md-chip selected color="accent">{{filter_description}} </md-chip>20 + </md-chip-list>21 + <button md-icon-button (click)="reload()" >22 + <md-icon>cancel</md-icon>23 + </button>24 + <span flex></span>25 + </md-toolbar-row>14 26 </md-toolbar> 15 27 <div flex="84" layout-align="center end" layout="column"> 16 28 <td-data-table securis/src/main/webapp/src/app/listing/pack.list.component.ts
.. .. @@ -1,4 +1,5 @@ 1 1 import { Router, ActivatedRoute } from '@angular/router'; 2 +import { Location } from '@angular/common';2 3 import { ToastsManager } from 'ng2-toastr/ng2-toastr'; 3 4 import { MdDialog, MdDialogConfig } from '@angular/material'; 4 5 import { .. .. @@ -11,12 +12,12 @@ 11 12 import { IPageChangeEvent } from '@covalent/core'; 12 13 import { Component, ViewChild, AfterViewInit } from '@angular/core'; 13 14 import { TdMediaService } from '@covalent/core'; 14 -import { PacksService, PACK_ACTIONS } from '../resources/packs';15 +import { PacksService, PACK_ACTIONS, PacksFilter } from '../resources/packs';15 16 import { PackFormComponent } from '../forms/pack.form.component'; 16 17 import { LocaleService } from '../common/i18n'; 17 18 import { ListingBase } from './base'; 18 19 19 -20 +/**20 21 var pack_example = { 21 22 id: 7, 22 23 code: 'DX250000', .. .. @@ -45,7 +46,7 @@ 45 46 preactivation_valid_period: 70, 46 47 renew_valid_period: 0, 47 48 } 48 -49 +*/49 50 @Component({ 50 51 selector: 'pack-list', 51 52 templateUrl: 'src/app/listing/pack.list.component.html' .. .. @@ -63,6 +64,8 @@ 63 64 ]; 64 65 65 66 pack_menu_options = PACK_ACTIONS; 67 + filter_description : string;68 + prevUrl : string = null;66 69 67 70 constructor(_dataTableService: TdDataTableService, 68 71 private media: TdMediaService, .. .. @@ -76,14 +79,42 @@ 76 79 super(_dataTableService); 77 80 } 78 81 79 - reload() : void {80 - this.packs.get().subscribe(82 + reload(filter?: PacksFilter) : void {83 + this.prepareFilteredBehavior(filter);84 + this.packs.get(filter).subscribe(81 85 (list : any[]) => { 82 86 this.data = list; 83 87 this.refresh(); 84 88 }, 85 89 (err: any) => console.error(err) 86 90 ); 91 + }92 +93 + goBack() : void {94 + if (this.prevUrl) {95 + this.router.navigate([this.prevUrl]);96 + }97 + }98 +99 + prepareFilteredBehavior(filter: PacksFilter) {100 + if (!filter) {101 + this.filter_description = '';102 + this.prevUrl = null;103 + } else {104 + if (!!filter.applicationId) {105 + this.filter_description = `Application: ${filter.name}`;106 + this.prevUrl = 'applications';107 + } else if (!!filter.organizationId) {108 + this.filter_description = `Organization: ${filter.name}`;109 + this.prevUrl = 'organizations';110 + } else if (!!filter.licenseTypeId) {111 + this.filter_description = `License type: ${filter.name}`;112 + this.prevUrl = 'licensetypes';113 + } else {114 + this.filter_description = '';115 + this.prevUrl = null;116 + }117 + }87 118 } 88 119 89 120 packAction(action: string, pack: any) { .. .. @@ -113,10 +144,13 @@ 113 144 this.sortOrder = sortEvent.order; 114 145 this.refresh(); 115 146 } 116 -147 +117 148 ngAfterViewInit(): void { 118 - this.reload();119 149 this.media.broadcast(); 150 + this.route.queryParams.subscribe(params => {151 + let filter = params as PacksFilter;152 + this.reload(filter);153 + });120 154 } 121 155 } 122 -156 +securis/src/main/webapp/src/app/resources/base.ts
.. .. @@ -3,8 +3,8 @@ 3 3 import { Observable } from 'rxjs/Observable'; 4 4 import { Http, RequestOptionsArgs, URLSearchParams } from '@angular/http'; 5 5 6 -class MySearchParams extends URLSearchParams {7 - constructor(obj : any) {6 +export class MySearchParams extends URLSearchParams {7 + constructor(obj : any = {}) {8 8 var searchQuery = Object.keys(obj).map(key => `${key}=${encodeURIComponent(obj[key])}`).join('&'); 9 9 super(searchQuery); 10 10 } securis/src/main/webapp/src/app/resources/packs.ts
.. .. @@ -1,7 +1,7 @@ 1 1 import { Observable } from 'rxjs/Rx'; 2 2 import { Injectable } from '@angular/core'; 3 3 import { Http, RequestOptions } from '@angular/http'; 4 -import { SeCurisResourceServices } from './base';4 +import { SeCurisResourceServices, MySearchParams } from './base';5 5 import { LocaleService } from '../common/i18n'; 6 6 7 7 var pack_example = { .. .. @@ -31,6 +31,13 @@ 31 31 organization_name: 'CurisTec', 32 32 preactivation_valid_period: 70, 33 33 renew_valid_period: 0, 34 +}35 +36 +export type PacksFilter = {37 + licenseTypeId?: number;38 + organizationId?: number;39 + applicationId?: number;40 + name?: string;34 41 } 35 42 36 43 export const PACK_STATUS = { .. .. @@ -79,6 +86,13 @@ 79 86 super($L, http, 'pack'); 80 87 } 81 88 89 + public get(filter?: PacksFilter) {90 + let searchParams = new MySearchParams(filter);91 + let url = `${this.resource}/?${searchParams}`;92 + console.log(`url: ${url}`);93 + return this.http.get(url).map(response => response.json()).catch(err => super.processErrorResponse(err));94 + }95 +82 96 public activate(id: number) { 83 97 return super.action(id, "activate"); 84 98 }