EventController.java

/**
 * TFG 75.678 - TFG Desarrollo web 2020 e-Learning for Schools
 * Copyright (C) 2020  Eduardo Rodriguez Carro
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.uoc.tfg.sel.web;

import java.util.Base64;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.uoc.tfg.sel.repository.model.Event;
import org.uoc.tfg.sel.repository.model.EventJob;
import org.uoc.tfg.sel.repository.model.EventType;
import org.uoc.tfg.sel.repository.model.User;
import org.uoc.tfg.sel.service.EventService;
import org.uoc.tfg.sel.web.model.Download;
import org.uoc.tfg.sel.web.model.EventJobUpload;

/**
 * The Class EventController.
 * @author Eduardo Rodriguez Carro
 */
@RestController
@CrossOrigin
@RequestMapping("/events")
public class EventController {

	/** The event service. */
	@Autowired
	private EventService eventService;

	/**
	 * Gets the all events paged.
	 *
	 * @param id        the id
	 * @param page      the page
	 * @param itemsPage the items page
	 * @return the all events paged
	 * @throws Exception the exception
	 */
	@PreAuthorize ("hasRole('ROLE_API_EVENTS')")
	@RequestMapping(value = "/all", method = RequestMethod.GET)
	public ResponseEntity<List<Event>> getAllEventsPaged(
			@RequestParam("class") Integer id,
			@RequestParam(name = "page",required = false,defaultValue = "0") Integer page,
			@RequestParam(name = "itemsPage",required = false, defaultValue = "10") Integer itemsPage
	) throws Exception {
		List<Event> events = eventService.getEventBySubjectClass(id, page,itemsPage);
		if (events != null && !events.isEmpty()) {
			return ResponseEntity.ok(events);	
		}else {
			return ResponseEntity.noContent().build();
		}
	}
	
	/**
	 * Delete.
	 *
	 * @param id the id
	 * @return the response entity
	 * @throws Exception the exception
	 */
	@PreAuthorize("hasRole('ROLE_API_EVENTS_DELETE')")
	@RequestMapping(value = "/delete/{id}", method = RequestMethod.DELETE)
	public ResponseEntity<Void> delete(@PathVariable("id") Integer id) throws Exception {
		eventService.deleteEvent(id);
		return ResponseEntity.ok().build();
	}	
	
	
	/**
	 * Gets the all events paged.
	 *
	 * @return the all events paged
	 * @throws Exception the exception
	 */
	@PreAuthorize ("hasRole('ROLE_API_EVENTS_TYPES')")
	@RequestMapping(value = "/types/all", method = RequestMethod.GET)
	public ResponseEntity<List<EventType>> getAllEventTypes() throws Exception {
		List<EventType> events = eventService.getEventTypes();
		if (events != null && !events.isEmpty()) {
			return ResponseEntity.ok(events);	
		}else {
			return ResponseEntity.noContent().build();
		}
	}
	
	/**
	 * Listado de usuarios por tipo.
	 *
	 * @param item the item
	 * @return the response entity
	 * @throws Exception the exception
	 */
	@PreAuthorize("hasRole('ROLE_API_EVENTS_EDIT')")
	@RequestMapping(value = "/save", method = RequestMethod.POST)
	public ResponseEntity<Event> saveUser(@RequestBody Event item) throws Exception {
		Event newEvent = eventService.saveEvent(item);
		return ResponseEntity.ok(newEvent);
	}
	
	/**
	 * Listado de usuarios por tipo.
	 *
	 * @param id the id
	 * @return the users by id
	 * @throws Exception the exception
	 */
	@PreAuthorize("hasRole('ROLE_API_EVENTS')")
	@RequestMapping(value = "/item/{id}", method = RequestMethod.GET)
	public ResponseEntity<Event> getById(@PathVariable("id") Integer id) throws Exception {
		Event event = eventService.getEventById(id);
		return ResponseEntity.ok(event);
	}
	
	/**
	 * Listado de usuarios por tipo.
	 *
	 * @param id the id
	 * @return the users by id
	 * @throws Exception the exception
	 */
	@PreAuthorize("hasRole('ROLE_API_EVENTS_JOBS')")
	@RequestMapping(value = "/item/{id}/jobs", method = RequestMethod.GET)
	public ResponseEntity<List<EventJob>> getJobsByEventId(@PathVariable("id") Integer id) throws Exception {
		List<EventJob> eventJobs = eventService.getEventJobsByEventId(id);
		return ResponseEntity.ok(eventJobs);
	}
	
	/**
	 * Listado de usuarios por tipo.
	 *
	 * @param id the id
	 * @return the users by id
	 * @throws Exception the exception
	 */
	@PreAuthorize("hasRole('ROLE_API_EVENTS_MYJOBS')")
	@RequestMapping(value = "/item/{id}/jobs/my", method = RequestMethod.GET)
	public ResponseEntity<List<EventJob>> getMyJobsByEventId(@PathVariable("id") Integer id,Authentication authentication) throws Exception {
		User user = ControllerUtils.getUser(authentication);
		List<EventJob> eventJobs = eventService.getEventJobsByEventIdAndStudent(id,user);
		return ResponseEntity.ok(eventJobs);
	}
		
	/**
	 * Save event job grade.
	 *
	 * @param eventId the event id
	 * @param jobId   the job id
	 * @param grade   the grade
	 * @return the response entity
	 */
	@PreAuthorize("hasRole('ROLE_API_EVENTS_JOBS_GRADE')")
	@RequestMapping(value = "/item/{id}/jobs/{jid}/grade/{grade}", method = RequestMethod.PUT)
	public ResponseEntity<Void> saveEventJobGrade(@PathVariable("id") Integer eventId,@PathVariable("jid") Integer jobId,@PathVariable("grade") String grade) {
		eventService.saveEventJobGrade(eventId, jobId, grade);
		return ResponseEntity.ok().build();
	}
	
	/**
	 * Download.
	 *
	 * @param eventId the event id
	 * @param jobId   the job id
	 * @return the response entity
	 */
	@PreAuthorize("hasRole('ROLE_API_EVENTS_JOBS_DOWNLOAD')")
	@RequestMapping(value = "/item/{id}/jobs/{jid}/download", method = RequestMethod.GET)
	public ResponseEntity<Download> download(@PathVariable("id") Integer eventId, @PathVariable("jid") Integer jobId) {
		//TODO un estudiante solo puede bajar sus trabajos
		//TODO un profesor solo puede bajar trabajos de eventos propios

		EventJob eventJob = eventService.getEventJobById(jobId);
		if (eventJob != null) {
			byte[] content = eventService.getEventJobContentById(jobId);
			if(content != null) {
				Download download = new Download();
				download.setName(eventJob.getContentName());
				download.setType(eventJob.getContentType());
				download.setSize(eventJob.getContentSize());
				download.setContent(Base64.getEncoder().encodeToString(content));
				return ResponseEntity.ok(download); 
			}
		}
		return ResponseEntity.notFound().build();
	}
	
	/**
	 * Upload.
	 *
	 * @param eventId the event id
	 * @param job     the job
	 * @return the response entity
	 */
	@PreAuthorize("hasRole('ROLE_API_EVENTS_ADDJOB')")
	@RequestMapping(value = "/item/{id}/jobs/upload", method = RequestMethod.POST)	
	public ResponseEntity<Boolean> upload(@PathVariable("id") Integer eventId, @RequestBody EventJobUpload job,Authentication authentication){
		User user = ControllerUtils.getUser(authentication);
		String content = job.getData();
		//data:application/pdf;base64,J
		int dataPosition = content.indexOf(";base64,");
		byte[] binaryContent =  Base64.getDecoder().decode(content.substring(dataPosition + 8));
		String contentMime = content.substring(0,dataPosition).replace("data:", "");
		eventService.saveEventJob(user,eventId,job.getName(), contentMime, binaryContent);
		return ResponseEntity.ok(true);
	}
	
}