Commit 4f5f3a45 authored by Kevin Robert's avatar Kevin Robert
Browse files

UNOTOPLYS-278 : Correction de la gestion des droits et du fil d'ariane, ajout d'une page d'accueil.

parent cec1e61c
......@@ -82,7 +82,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
.antMatchers("/api/account/reset-password/init").permitAll()
.antMatchers("/api/account/reset-password/finish").permitAll()
.antMatchers("/api/form/**").permitAll()
.antMatchers("/api/**").permitAll()
.antMatchers("/api/**").authenticated()
.antMatchers("/management/health").permitAll()
.antMatchers("/management/health/**").permitAll()
.antMatchers("/management/info").authenticated()
......
......@@ -37,9 +37,9 @@ public class FilArianeController {
private final FormService formService;
/**
* Elément du fil d'ariane correspondant à l'accueil.
* Contexte de l'application pour les traductions.
*/
private final FilArianeElement filArianeHome;
private final ApplicationContext applicationContext;
/**
* Constructeur.
......@@ -51,9 +51,8 @@ public class FilArianeController {
final FormService formService,
final ApplicationContext applicationContext
) {
String homeTitle = applicationContext.getMessage("filariane.home.title", new Object[]{}, Locale.getDefault());
this.applicationContext = applicationContext;
this.workspaceService = workspaceService;
this.filArianeHome = new FilArianeElement(homeTitle, Path.HOME);
this.formService = formService;
}
......@@ -66,11 +65,11 @@ public class FilArianeController {
@ResponseBody
public String getUserHome() {
if (PermissionService.currentUserHasAuthority(AuthoritiesConstants.AUTHORITY_VIEW_WORKSPACE)) {
return Path.LIST_WORKSPACES;
return Path.ACCUEIL_WORKSPACES;
} else if (PermissionService.currentUserHasAuthority(AuthoritiesConstants.AUTHORITY_VIEW_FORM)) {
return Path.LIST_FORMS;
return Path.ACCUEIL_FORMS;
}
return "#";
return Path.PAGE_LOGIN;
}
/**
......@@ -81,7 +80,8 @@ public class FilArianeController {
@GetMapping("/home")
@ResponseBody
public List<FilArianeElement> getFilArianeForHome() {
return Collections.singletonList(filArianeHome);
String homeTitle = applicationContext.getMessage("filariane.home.title", new Object[]{}, Locale.getDefault());
return Collections.singletonList(new FilArianeElement(homeTitle, getUserHome()));
}
/**
......@@ -94,7 +94,7 @@ public class FilArianeController {
@ResponseBody
public List<FilArianeElement> getFilArianeForWorkspace(@PathVariable("idWorkspace") final Long idWorkspace) {
LinkedList<FilArianeElement> filAriane = new LinkedList<>();
filAriane.add(filArianeHome);
filAriane.add(getFilArianeForHome().get(0));
Optional<FilArianeElement> filArianeWorkspace = getFilArianeWorkspace(idWorkspace);
filArianeWorkspace.ifPresent(filAriane::add);
return filAriane;
......@@ -110,7 +110,7 @@ public class FilArianeController {
@ResponseBody
public List<FilArianeElement> getFilArianeForForm(@PathVariable("idForm") final Long idForm) {
LinkedList<FilArianeElement> filAriane = new LinkedList<>();
filAriane.add(filArianeHome);
filAriane.add(getFilArianeForHome().get(0));
if (PermissionService.currentUserHasAuthority(AuthoritiesConstants.AUTHORITY_VIEW_FORM)) {
final Optional<FormDTO> formDTO = formService.findOne(idForm);
final FormDTO form = formDTO.orElseThrow(() -> new FilArianeException("Le formulaire n'existe pas."));
......
......@@ -5,10 +5,12 @@ package com.unantes.orientactive.filariane;
*/
public class Path {
public static final String HOME = "/admin/workspace";
public static final String WORKSPACE = "/admin/workspace";
public static final String FORMS = "/form";
public static final String LIST_WORKSPACES = "/admin/workspaces";
public static final String LIST_FORMS = "/admin/forms";
public static final String ACCUEIL_WORKSPACES = "/admin/workspaces";
public static final String ACCUEIL_FORMS = "/admin/forms";
// TODO : Remplacer ça pour une page d'erreur de login du type 'Vous avez bien un compte mais vous n'avez pas de droits associés, veuillez contacter votre administrateur.'
public static final String PAGE_LOGIN = "/login";
}
......@@ -101,4 +101,10 @@ public interface FormRepository extends JpaRepository<Form, Long>, RoleRepositor
@Query(value = "with new_scope as (insert into scope (id_user, id_role) values (:idUser, :idRole) on conflict on constraint unique_scope do nothing returning id) insert into scope_form (id_scope, id_form) values (coalesce((select id from new_scope), (select id from scope where id_user = :idUser and id_role = :idRole)), :idForm) on conflict on constraint unique_scope_form do nothing", nativeQuery = true)
@Modifying
void addRoleWithPermission(@Param("idUser") Long idUser, @Param("idRole") int idRole, @Param("idForm") Long idForm);
@Query(
value = "select f.* from form f join scope_form sf on sf.id_form = f.id join scope s on s.id = sf.id_scope where s.id_user = :idUser",
nativeQuery = true
)
List<Form> getAllFormForContributeur(@Param("idUser") Long idUser);
}
......@@ -3,22 +3,22 @@ package com.unantes.orientactive.service;
import com.unantes.orientactive.domain.Form;
import com.unantes.orientactive.domain.User;
import com.unantes.orientactive.repository.FormRepository;
import com.unantes.orientactive.security.permissions.PermissionEntity;
import com.unantes.orientactive.security.permissions.PermissionService;
import com.unantes.orientactive.security.permissions.Role;
import com.unantes.orientactive.service.dto.AdminUserDTO;
import com.unantes.orientactive.service.dto.FormDTO;
import com.unantes.orientactive.service.mapper.FormMapper;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* Service Implementation for managing {@link Form}.
*/
......@@ -139,6 +139,16 @@ public class FormService extends PermissionService<FormDTO> {
return formRepository.getFormAnswersSessionIds(id);
}
/**
* Récupération des formulaires éditables par un contributeur.
*
* @param idUser L'identifiant de l'utilisateur.
* @return La liste des formulaires.
*/
public List<FormDTO> getAllFormForContributeur(Long idUser) {
return formRepository.getAllFormForContributeur(idUser).stream().map(formMapper::toDto).collect(Collectors.toList());
}
@PreAuthorize("hasAuthority('EDIT_FORM')")
@Override
public void addRole(User user) {
......
......@@ -4,21 +4,30 @@ import com.unantes.orientactive.repository.FormRepository;
import com.unantes.orientactive.service.FormService;
import com.unantes.orientactive.service.dto.FormDTO;
import com.unantes.orientactive.web.rest.errors.BadRequestAlertException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import tech.jhipster.web.util.HeaderUtil;
import tech.jhipster.web.util.ResponseUtil;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
/**
* REST controller for managing {@link com.unantes.orientactive.domain.Form}.
*/
......@@ -171,4 +180,15 @@ public class FormResource {
.headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, id.toString()))
.build();
}
/**
* Récupération des formulaires d'un contributeur.
*
* @param idUser L'identifiant du contributeur.
* @return La liste des formulaire.
*/
@GetMapping("/forms/user/{idUser}")
public List<FormDTO> getAllFormForContributeur(@PathVariable Long idUser) {
return formService.getAllFormForContributeur(idUser);
}
}
......@@ -5,6 +5,7 @@
<div class="alert alert-danger">{{ errorMessage }}</div>
</div>
<div v-if="error403" class="alert alert-danger">{{ $t('error.http.403') }}</div>
<div v-if="error403" class="alert"><a href="/login">Page d'accueil</a></div>
<div v-if="error404" class="alert alert-warning">{{ $t('error.http.404') }}</div>
</div>
</template>
......
......@@ -51,7 +51,7 @@ router.beforeEach((to, from, next) => {
accountService.checkAuth().then(value => {
// si l'utilisateur est déjà connecté, on redirige vers la page d'accueil
if (value) {
next(ROUTES.admin.path);
accountService.retrieveUsersHome().then(homePath => next(homePath));
} else {
// sinon on continue vers la page de login
next();
......
......@@ -7,6 +7,6 @@ export default [
path: '/admin/account/settings',
name: 'Settings',
component: Settings,
meta: { authorities: [Authority.ADMIN] },
meta: { authorities: [Authority.ADMIN_SAAS] },
},
];
import { Authority } from '@/shared/security/authority';
import {Authority} from '@/shared/security/authority';
import {PanelUtils} from "@/components/panel/panel.utils";
const FormCreationComponent = () => import('@/views/form/form-creation.vue');
......@@ -14,45 +14,47 @@ export default [
path: '/admin/workspace/:idWorkspace/form/creation',
name: 'FormCreationComponent',
component: FormCreationComponent,
meta: { authorities: [Authority.ADMIN] },
meta: { authorities: [Authority.ADMIN_SAAS, Authority.EDIT_FORM] },
},
{
// TODO : Non supporté par l'application actuellement.
path: '/admin/form/:idForm/preview',
name: 'FormPreviewComponent',
component: FormPreviewComponent,
meta: { authorities: [Authority.ADMIN] },
meta: { authorities: [Authority.ADMIN_SAAS] },
},
{
path: '/admin/form/:idForm/results',
name: 'FormResultsComponent',
component: FormResultsComponent,
meta: { authorities: [Authority.ADMIN] },
meta: { authorities: [Authority.ADMIN_SAAS, Authority.VIEW_RESULT] },
},
{
path: '/admin/workspace/:idWorkspace/form/:idForm/settings',
name: 'FormSettingsComponent',
component: FormSettingsComponent,
meta: {
authorities: [Authority.ADMIN],
authorities: [Authority.ADMIN_SAAS, Authority.EDIT_WORKSPACE],
panel: PanelUtils.PANEL_FORM,
},
},
{
// TODO : Non supporté par l'application actuellement.
path: '/admin/form/:idForm/share',
name: 'FormShareComponent',
component: FormShareComponent,
meta: { authorities: [Authority.ADMIN] },
meta: { authorities: [Authority.ADMIN_SAAS] },
},
{
path: '/admin/form/list',
name: 'FormListComponent',
component: FormListComponent,
meta: { authorities: [Authority.ADMIN] },
meta: { authorities: [Authority.ADMIN_SAAS, Authority.VIEW_FORM] },
},
{
path: '/admin/form/:idForm/variables',
name: 'FormVariablesComponent',
component: FormVariablesComponent,
meta: { authorities: [Authority.ADMIN] },
meta: { authorities: [Authority.ADMIN_SAAS, Authority.EDIT_FORM] },
},
];
......@@ -6,42 +6,45 @@ const JhiHealthComponent = () => import('@/admin/health/health.vue');
const JhiLogsComponent = () => import('@/admin/logs/logs.vue');
const JhiAuditsComponent = () => import('@/admin/audits/audits.vue');
const JhiMetricsComponent = () => import('@/admin/metrics/metrics.vue');
/**
* Comporte différentes pages d'administration générées par Jhipster.
* Elles ne sont plus supportées, mais elles sont conservées car elles peuvent rester utiles afin d'avoir des statistiques sur l'application.
*/
export default [
{
path: '/admin/docs',
name: 'JhiDocsComponent',
component: JhiDocsComponent,
meta: { authorities: [Authority.ADMIN] },
meta: { authorities: [Authority.ADMIN_SAAS] },
},
{
path: '/admin/audits',
name: 'JhiAuditsComponent',
component: JhiAuditsComponent,
meta: { authorities: [Authority.ADMIN] },
meta: { authorities: [Authority.ADMIN_SAAS] },
},
{
path: '/admin/jhi-health',
name: 'JhiHealthComponent',
component: JhiHealthComponent,
meta: { authorities: [Authority.ADMIN] },
meta: { authorities: [Authority.ADMIN_SAAS] },
},
{
path: '/admin/logs',
name: 'JhiLogsComponent',
component: JhiLogsComponent,
meta: { authorities: [Authority.ADMIN] },
meta: { authorities: [Authority.ADMIN_SAAS] },
},
{
path: '/admin/jhi-metrics',
name: 'JhiMetricsComponent',
component: JhiMetricsComponent,
meta: { authorities: [Authority.ADMIN] },
meta: { authorities: [Authority.ADMIN_SAAS] },
},
{
path: '/admin/jhi-configuration',
name: 'JhiConfigurationComponent',
component: JhiConfigurationComponent,
meta: { authorities: [Authority.ADMIN] },
meta: { authorities: [Authority.ADMIN_SAAS] },
},
];
import { Authority } from '@/shared/security/authority';
import { PanelUtils } from '@/components/panel/panel.utils';
import {Authority} from '@/shared/security/authority';
import {PanelUtils} from '@/components/panel/panel.utils';
const ScreenCreateComponent = () => import('@/views/screen/screen-create.vue');
const ScreenEditComponent = () => import('@/views/screen/screen-edit.vue');
......@@ -11,7 +11,7 @@ export default [
name: 'ScreenCreateComponent',
component: ScreenCreateComponent,
meta: {
authorities: [Authority.ADMIN],
authorities: [Authority.ADMIN_SAAS, Authority.EDIT_FORM],
panel: PanelUtils.PANEL_SCREEN,
},
},
......@@ -20,7 +20,7 @@ export default [
name: 'ScreenEditComponent',
component: ScreenEditComponent,
meta: {
authorities: [Authority.ADMIN],
authorities: [Authority.ADMIN_SAAS, Authority.EDIT_FORM],
panel: PanelUtils.PANEL_SCREEN,
},
},
......@@ -29,7 +29,7 @@ export default [
name: 'ScreenSettingsComponent',
component: ScreenSettingsComponent,
meta: {
authorities: [Authority.ADMIN],
authorities: [Authority.ADMIN_SAAS, Authority.EDIT_FORM],
panel: PanelUtils.PANEL_SCREEN,
},
},
......@@ -38,7 +38,7 @@ export default [
name: 'FirstScreenEditComponent',
component: ScreenEditComponent,
meta: {
authorities: [Authority.ADMIN],
authorities: [Authority.ADMIN_SAAS, Authority.EDIT_FORM],
panel: PanelUtils.PANEL_SCREEN,
},
},
......
......@@ -8,18 +8,18 @@ export default [
path: '/admin/user/:idUser/edit',
name: 'UserEditComponent',
component: UserEditComponent,
meta: { authorities: [Authority.ADMIN] },
meta: { authorities: [Authority.ADMIN_SAAS] },
},
{
path: '/admin/user/creation',
name: 'UserCreateComponent',
component: UserEditComponent,
meta: { authorities: [Authority.ADMIN] },
meta: { authorities: [Authority.ADMIN_SAAS] },
},
{
path: '/admin/user',
name: 'UserListComponent',
component: UserListComponent,
meta: { authorities: [Authority.ADMIN] },
meta: { authorities: [Authority.ADMIN_SAAS] },
},
];
......@@ -8,18 +8,18 @@ export default [
path: '/admin/workspace/:idWorkspace/form/:idForm/variable/:idVariable/edit',
name: 'VariableEditComponent',
component: VariableEditComponent,
meta: { authorities: [Authority.ADMIN] },
meta: { authorities: [Authority.EDIT_FORM] },
},
{
path: '/admin/workspace/:idWorkspace/form/:idForm/variable',
name: 'VariableListComponent',
component: VariableListComponent,
meta: { authorities: [Authority.ADMIN] },
meta: { authorities: [Authority.EDIT_FORM] },
},
{
path: '/admin/workspace/:idWorkspace/form/:idForm/variable/creation',
name: 'VariableCreateComponent',
component: VariableEditComponent,
meta: { authorities: [Authority.ADMIN] },
meta: { authorities: [Authority.EDIT_FORM] },
},
];
import { Authority } from '@/shared/security/authority';
import { PanelUtils } from '@/components/panel/panel.utils';
import {Authority} from '@/shared/security/authority';
import {PanelUtils} from '@/components/panel/panel.utils';
const WorkspaceCreationComponent = () => import('@/views/workspace/workspace-creation.vue');
const WorkspaceSettingsComponent = () => import('@/views/workspace/workspace-settings.vue');
......@@ -11,14 +11,14 @@ export default [
path: '/admin/workspace/creation',
name: 'WorkspaceCreationComponent',
component: WorkspaceCreationComponent,
meta: { authorities: [Authority.ADMIN] },
meta: { authorities: [Authority.ADMIN_SAAS, Authority.EDIT_ORGANIZATION] },
},
{
path: '/admin/workspace/:idWorkspace/settings',
name: 'WorkspaceSettingsComponent',
component: WorkspaceSettingsComponent,
meta: {
authorities: [Authority.ADMIN],
authorities: [Authority.ADMIN_SAAS, Authority.EDIT_WORKSPACE],
panel: PanelUtils.PANEL_WORKSPACE,
},
},
......@@ -26,12 +26,12 @@ export default [
path: '/admin/workspace',
name: 'WorkspaceListComponent',
component: WorkspaceListComponent,
meta: { authorities: [Authority.ADMIN] },
meta: { authorities: [Authority.ADMIN_SAAS, Authority.VIEW_WORKSPACE] },
},
{
path: '/admin/workspace/:idWorkspace/view',
name: 'WorkspaceViewComponent',
component: WorkspaceViewComponent,
meta: { authorities: [Authority.ADMIN] },
meta: { authorities: [Authority.ADMIN_SAAS, Authority.VIEW_WORKSPACE] },
},
];
......@@ -8,6 +8,7 @@ import adminScreen from '@/router/admin-screen';
import adminUser from '@/router/admin-user';
import adminVariable from '@/router/admin-variable';
import adminWorkspace from '@/router/admin-workspace';
const HomeView = () => import('@/views/workspace/home-view.vue');
const Admin = () => import('@/admin/admin.vue');
......@@ -18,8 +19,26 @@ export default [
children: [
{
path: '',
redirect: '/admin/workspace',
meta: { authorities: [Authority.ADMIN] },
redirect: '/admin/forms',
meta: { authorities: [Authority.ADMIN_SAAS, Authority.VIEW_WORKSPACE] },
},
{
path: '/admin/forms',
name: 'HomeView',
component: HomeView,
meta: {
authorities: [Authority.ADMIN_SAAS, Authority.VIEW_FORM, Authority.VIEW_WORKSPACE],
showForms: true
},
},
{
path: '/admin/workspaces',
name: 'HomeView',
component: HomeView,
meta: {
authorities: [Authority.ADMIN_SAAS, Authority.VIEW_FORM, Authority.VIEW_WORKSPACE],
showWorkspaces: true
},
},
...adminAccount,
...adminForm,
......
......@@ -70,6 +70,12 @@ export default class AccountService {
});
}
public retrieveUsersHome(): Promise<any> {
return new Promise( resolve => axios.get(`api/filariane/user/home`)
.then(value => resolve(value.data))
);
}
public logout(): void {
this.store.dispatch('logout', () => this.router.push('/login'));
}
......
......@@ -44,6 +44,19 @@ export default class FormService {
});
}
public retrieveWithPermissionForContributeur(idUser: string): Promise<any> {
return new Promise<any>((resolve, reject) => {
axios
.get(`${baseApiUrl}/user/${idUser}`)
.then(res => {
resolve(res);
})
.catch(err => {
reject(err);
});
});
}
public findAllWithPermission(idEntity: number): Promise<any> {
return new Promise<any>((resolve, reject) => {
axios
......
export enum Authority {
ADMIN = 'ADMIN_SAAS',
ADMIN_SAAS = 'ADMIN_SAAS',
VIEW_WORKSPACE = "VIEW_WORKSPACE",
VIEW_RESULT = "VIEW_RESULT",
VIEW_ORGANIZATION = "VIEW_ORGANIZATION",
EDIT_WORKSPACE = "EDIT_WORKSPACE",
VIEW_FORM = "VIEW_FORM",
EDIT_FORM = "EDIT_FORM",
EDIT_ORGANIZATION = "EDIT_ORGANIZATION",
// TODO : utilisé pour les tests mais dans l'idée ne sert a rien.
USER = 'ROLE_USER',
}
import { Store } from 'vuex';
import {Store} from 'vuex';
import axios from 'axios';
import VueI18n from 'vue-i18n';
import TranslationService from '@/locale/translation.service';
......@@ -10,6 +10,7 @@ export default class HeaderService {
public static readonly TAB_KEY_VIEW = 'view';
public static readonly TAB_KEY_VARIABLE = 'variable';
public static readonly TAB_KEY_WORKSPACES = 'workspaces';
public static readonly TAB_KEY_FORMS = 'forms';
public static readonly TAB_KEY_USERS = 'users';
constructor(private store: Store<any>, private translationService: TranslationService, private i18n: VueI18n) {
......@@ -90,4 +91,25 @@ export default class HeaderService {
this.store.commit('filArianeElements', res.data);
});
}
public updateTabsForHome(currentKey: string): void {
let tabs = [
{