Index: src/main/java/it/finki/charitable/CharitableApplication.java
===================================================================
--- src/main/java/it/finki/charitable/CharitableApplication.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
+++ src/main/java/it/finki/charitable/CharitableApplication.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
@@ -0,0 +1,15 @@
+package it.finki.charitable;
+
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class CharitableApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(CharitableApplication.class, args);
+    }
+
+}
+
Index: src/main/java/it/finki/charitable/ServletInitializer.java
===================================================================
--- src/main/java/it/finki/charitable/ServletInitializer.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
+++ src/main/java/it/finki/charitable/ServletInitializer.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
@@ -0,0 +1,13 @@
+package it.finki.charitable;
+
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+
+public class ServletInitializer extends SpringBootServletInitializer {
+
+    @Override
+    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+        return application.sources(CharitableApplication.class);
+    }
+
+}
Index: src/main/java/it/finki/charitable/repository/ConfirmationTokenRepository.java
===================================================================
--- src/main/java/it/finki/charitable/repository/ConfirmationTokenRepository.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
+++ src/main/java/it/finki/charitable/repository/ConfirmationTokenRepository.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
@@ -0,0 +1,13 @@
+package it.finki.charitable.repository;
+
+import it.finki.charitable.security.ConfirmationToken;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.Optional;
+
+@Repository
+public interface ConfirmationTokenRepository extends JpaRepository<ConfirmationToken, Long> {
+
+    Optional<ConfirmationToken> findByToken(String token);
+}
Index: src/main/java/it/finki/charitable/repository/DonationInformationRepository.java
===================================================================
--- src/main/java/it/finki/charitable/repository/DonationInformationRepository.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
+++ src/main/java/it/finki/charitable/repository/DonationInformationRepository.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
@@ -0,0 +1,7 @@
+package it.finki.charitable.repository;
+
+import it.finki.charitable.entities.DonationInformation;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface DonationInformationRepository extends JpaRepository<DonationInformation, Long> {
+}
Index: src/main/java/it/finki/charitable/repository/DonationPostRepository.java
===================================================================
--- src/main/java/it/finki/charitable/repository/DonationPostRepository.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
+++ src/main/java/it/finki/charitable/repository/DonationPostRepository.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
@@ -0,0 +1,13 @@
+package it.finki.charitable.repository;
+
+import it.finki.charitable.entities.AppUser;
+import it.finki.charitable.entities.DonationPost;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface DonationPostRepository extends JpaRepository<DonationPost, Long> {
+    List<DonationPost> findAllByUser(AppUser user);
+}
Index: src/main/java/it/finki/charitable/repository/FundsCollectedRepository.java
===================================================================
--- src/main/java/it/finki/charitable/repository/FundsCollectedRepository.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
+++ src/main/java/it/finki/charitable/repository/FundsCollectedRepository.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
@@ -0,0 +1,9 @@
+package it.finki.charitable.repository;
+
+import it.finki.charitable.entities.FundsCollected;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface FundsCollectedRepository extends JpaRepository<FundsCollected, Long> {
+}
Index: src/main/java/it/finki/charitable/repository/UserRepository.java
===================================================================
--- src/main/java/it/finki/charitable/repository/UserRepository.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
+++ src/main/java/it/finki/charitable/repository/UserRepository.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
@@ -0,0 +1,13 @@
+package it.finki.charitable.repository;
+
+import it.finki.charitable.entities.AppUser;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.Optional;
+
+@Repository
+public interface UserRepository extends JpaRepository<AppUser, Long> {
+
+    Optional<AppUser> findByEmail(String email);
+}
Index: src/main/java/it/finki/charitable/security/ConfirmationToken.java
===================================================================
--- src/main/java/it/finki/charitable/security/ConfirmationToken.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
+++ src/main/java/it/finki/charitable/security/ConfirmationToken.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
@@ -0,0 +1,68 @@
+package it.finki.charitable.security;
+
+import it.finki.charitable.entities.AppUser;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "confirmation_token")
+public class ConfirmationToken {
+
+    @SequenceGenerator(
+            name = "conf_token_sequence",
+            sequenceName = "conf_token_sequence",
+            allocationSize = 1
+    )
+    @GeneratedValue(
+            strategy = GenerationType.SEQUENCE,
+            generator = "conf_token_sequence"
+    )
+    @Id
+    @Column(
+            name = "id",
+            nullable = false,
+            updatable = false
+    )
+    private Long id;
+
+    private String token;
+
+    @OneToOne
+    @JoinColumn(
+            nullable = false,
+            name = "app_user_id"
+    )
+    private AppUser user;
+
+    public ConfirmationToken() {
+    }
+
+    public ConfirmationToken(String token, AppUser user) {
+        this.token = token;
+        this.user = user;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getToken() {
+        return token;
+    }
+
+    public void setToken(String token) {
+        this.token = token;
+    }
+
+    public AppUser getUser() {
+        return user;
+    }
+
+    public void setUser(AppUser user) {
+        this.user = user;
+    }
+}
Index: src/main/java/it/finki/charitable/security/PasswordEncoder.java
===================================================================
--- src/main/java/it/finki/charitable/security/PasswordEncoder.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
+++ src/main/java/it/finki/charitable/security/PasswordEncoder.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
@@ -0,0 +1,14 @@
+package it.finki.charitable.security;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+
+@Configuration
+public class PasswordEncoder {
+
+    @Bean
+    public static BCryptPasswordEncoder bCryptPasswordEncoder() {
+        return new BCryptPasswordEncoder(10);
+    }
+}
Index: src/main/java/it/finki/charitable/security/SecurityConfig.java
===================================================================
--- src/main/java/it/finki/charitable/security/SecurityConfig.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
+++ src/main/java/it/finki/charitable/security/SecurityConfig.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
@@ -0,0 +1,61 @@
+package it.finki.charitable.security;
+
+import it.finki.charitable.entities.UserRole;
+import it.finki.charitable.services.UserService;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+
+@Configuration
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
+
+    private final UserService userService;
+    private BCryptPasswordEncoder passwordEncoder() {
+        return PasswordEncoder.bCryptPasswordEncoder();
+    }
+
+    public SecurityConfig(UserService userService) {
+        this.userService = userService;
+    }
+
+    private final static String[] publicMatchers = {
+            "/css/**",
+            "/js/**",
+            "/image/**",
+            "/",
+            "/login",
+            "/register",
+            "/validate",
+            "/album/**",
+            "/post",
+            "/post-photos/**"
+    };
+
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        http
+                .authorizeRequests()
+                .antMatchers(publicMatchers).permitAll()
+                .antMatchers("/moderator-photos/**").hasAuthority(UserRole.MODERATOR.name())
+                .anyRequest().authenticated();
+
+        http
+                .csrf().disable()
+                .cors().disable()
+                .formLogin().loginPage("/login")
+                .defaultSuccessUrl("/", true)
+                .and()
+                .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
+                .logoutSuccessUrl("/").deleteCookies("remember-me")
+                .and()
+                .rememberMe();
+    }
+
+    @Override
+    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+        auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
+    }
+}
Index: src/main/java/it/finki/charitable/services/ConfirmationTokenService.java
===================================================================
--- src/main/java/it/finki/charitable/services/ConfirmationTokenService.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
+++ src/main/java/it/finki/charitable/services/ConfirmationTokenService.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
@@ -0,0 +1,34 @@
+package it.finki.charitable.services;
+
+import it.finki.charitable.entities.AppUser;
+import it.finki.charitable.repository.ConfirmationTokenRepository;
+import it.finki.charitable.security.ConfirmationToken;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class ConfirmationTokenService {
+
+    private final ConfirmationTokenRepository tokenRepository;
+
+    public ConfirmationTokenService(ConfirmationTokenRepository tokenRepository) {
+        this.tokenRepository = tokenRepository;
+    }
+
+    public ConfirmationToken getConfirmationToken(String token) {
+        return tokenRepository.findByToken(token).orElse(null);
+    }
+
+    public List<ConfirmationToken> getAll() {
+        return tokenRepository.findAll();
+    }
+
+    public void saveConfirmationToken(ConfirmationToken token) {
+        tokenRepository.save(token);
+    }
+
+    public void deleteConfirmationToken(ConfirmationToken token) {
+        tokenRepository.delete(token);
+    }
+}
Index: src/main/java/it/finki/charitable/services/DonationInformationService.java
===================================================================
--- src/main/java/it/finki/charitable/services/DonationInformationService.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
+++ src/main/java/it/finki/charitable/services/DonationInformationService.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
@@ -0,0 +1,20 @@
+package it.finki.charitable.services;
+
+import it.finki.charitable.entities.DonationInformation;
+import it.finki.charitable.repository.DonationInformationRepository;
+import org.springframework.stereotype.Service;
+
+@Service
+public class DonationInformationService {
+
+    private final DonationInformationRepository donationInformationRepository;
+
+    public DonationInformationService(DonationInformationRepository donationInformationRepository) {
+        this.donationInformationRepository = donationInformationRepository;
+    }
+
+    public void save(DonationInformation donationInformation) {
+        donationInformationRepository.save(donationInformation);
+    }
+}
+
Index: src/main/java/it/finki/charitable/services/DonationPostService.java
===================================================================
--- src/main/java/it/finki/charitable/services/DonationPostService.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
+++ src/main/java/it/finki/charitable/services/DonationPostService.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
@@ -0,0 +1,51 @@
+package it.finki.charitable.services;
+
+import it.finki.charitable.entities.AppUser;
+import it.finki.charitable.entities.DonationPost;
+import it.finki.charitable.repository.DonationPostRepository;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class DonationPostService {
+
+    private final DonationPostRepository donationPostRepository;
+
+    public DonationPostService(DonationPostRepository donationPostRepository) {
+        this.donationPostRepository = donationPostRepository;
+    }
+
+    public DonationPost save(DonationPost donationPost) {
+        return donationPostRepository.save(donationPost);
+    }
+
+    public DonationPost getById(Long id) {
+        if(donationPostRepository.existsById(id)) {
+            return donationPostRepository.getById(id);
+        }
+
+        return null;
+    }
+
+    public List<DonationPost> findAll() {
+        return donationPostRepository.findAll();
+    }
+
+    public List<DonationPost> findAllByUser(AppUser user) {
+        return donationPostRepository.findAllByUser(user);
+    }
+
+    public void delete(DonationPost donationPost) {
+        donationPostRepository.delete(donationPost);
+    }
+
+    public Page<DonationPost> findPaginated(int pageNo, int pageSize, String sort) {
+        Pageable pageable = PageRequest.of(pageNo - 1, pageSize, Sort.by(sort));
+        return donationPostRepository.findAll(pageable);
+    }
+}
Index: src/main/java/it/finki/charitable/services/EmailService.java
===================================================================
--- src/main/java/it/finki/charitable/services/EmailService.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
+++ src/main/java/it/finki/charitable/services/EmailService.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
@@ -0,0 +1,26 @@
+package it.finki.charitable.services;
+
+import org.springframework.mail.SimpleMailMessage;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.stereotype.Component;
+
+@Component
+public class EmailService {
+
+    private final JavaMailSender javaMailSender;
+
+    public EmailService(JavaMailSender javaMailSender) {
+        this.javaMailSender = javaMailSender;
+    }
+
+    public void sendValidationEmail(String to, String subject, String token) {
+        SimpleMailMessage message = new SimpleMailMessage();
+        message.setTo(to);
+        message.setSubject(subject);
+
+        String text = "Verify your account on the following link\n" +
+                "http://localhost:8080/validate?token=" + token;
+        message.setText(text);
+        javaMailSender.send(message);
+    }
+}
Index: src/main/java/it/finki/charitable/services/FundsCollectedService.java
===================================================================
--- src/main/java/it/finki/charitable/services/FundsCollectedService.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
+++ src/main/java/it/finki/charitable/services/FundsCollectedService.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
@@ -0,0 +1,19 @@
+package it.finki.charitable.services;
+
+import it.finki.charitable.entities.FundsCollected;
+import it.finki.charitable.repository.FundsCollectedRepository;
+import org.springframework.stereotype.Service;
+
+@Service
+public class FundsCollectedService {
+
+    private final FundsCollectedRepository fundsCollectedRepository;
+
+    public FundsCollectedService(FundsCollectedRepository fundsCollectedRepository) {
+        this.fundsCollectedRepository = fundsCollectedRepository;
+    }
+
+    public void save(FundsCollected fundsCollected) {
+        fundsCollectedRepository.save(fundsCollected);
+    }
+}
Index: src/main/java/it/finki/charitable/services/UserService.java
===================================================================
--- src/main/java/it/finki/charitable/services/UserService.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
+++ src/main/java/it/finki/charitable/services/UserService.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
@@ -0,0 +1,30 @@
+package it.finki.charitable.services;
+
+import it.finki.charitable.entities.AppUser;
+import it.finki.charitable.repository.UserRepository;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.stereotype.Service;
+
+@Service
+public class UserService implements UserDetailsService {
+
+    private final UserRepository userRepository;
+
+    public UserService(UserRepository userRepository) {
+        this.userRepository = userRepository;
+    }
+
+    @Override
+    public AppUser loadUserByUsername(String s) throws UsernameNotFoundException {
+        return userRepository.findByEmail(s).orElse(null);
+    }
+
+    public void saveUser(AppUser user) {
+        userRepository.save(user);
+    }
+
+    public void deleteUser(AppUser user) {
+        userRepository.delete(user);
+    }
+}
Index: src/main/java/it/finki/charitable/util/AutomaticEvents.java
===================================================================
--- src/main/java/it/finki/charitable/util/AutomaticEvents.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
+++ src/main/java/it/finki/charitable/util/AutomaticEvents.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
@@ -0,0 +1,34 @@
+package it.finki.charitable.util;
+
+import it.finki.charitable.entities.AppUser;
+import it.finki.charitable.security.ConfirmationToken;
+import it.finki.charitable.services.ConfirmationTokenService;
+import it.finki.charitable.services.UserService;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Component
+public class AutomaticEvents {
+
+    private final UserService userService;
+    private final ConfirmationTokenService confirmationTokenService;
+
+    public AutomaticEvents(UserService userService, ConfirmationTokenService confirmationTokenService) {
+        this.userService = userService;
+        this.confirmationTokenService = confirmationTokenService;
+    }
+
+    @Scheduled(cron = "0 0 0 * * *")
+    public void deleteNonEnabledUsers() {
+        List<ConfirmationToken> toDelete = confirmationTokenService.getAll();
+        for(ConfirmationToken token : toDelete) {
+            AppUser user = token.getUser();
+            confirmationTokenService.deleteConfirmationToken(token);
+            if(!user.getEnabled()) {
+                userService.deleteUser(user);
+            }
+        }
+    }
+}
Index: src/main/java/it/finki/charitable/util/FileUploadUtil.java
===================================================================
--- src/main/java/it/finki/charitable/util/FileUploadUtil.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
+++ src/main/java/it/finki/charitable/util/FileUploadUtil.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
@@ -0,0 +1,29 @@
+package it.finki.charitable.util;
+
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+
+public class FileUploadUtil {
+
+    public static void saveFile(String uploadDir, String fileName,
+                                MultipartFile multipartFile) throws IOException {
+        Path uploadPath = Paths.get(uploadDir);
+
+        if (!Files.exists(uploadPath)) {
+            Files.createDirectories(uploadPath);
+        }
+
+        try (InputStream inputStream = multipartFile.getInputStream()) {
+            Path filePath = uploadPath.resolve(fileName);
+            Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING);
+        } catch (IOException ioe) {
+            throw new IOException("Could not save image file: " + fileName, ioe);
+        }
+    }
+}
Index: src/test/java/it/finki/charitable/CharitableApplicationTests.java
===================================================================
--- src/test/java/it/finki/charitable/CharitableApplicationTests.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
+++ src/test/java/it/finki/charitable/CharitableApplicationTests.java	(revision 3fc9e500d3c47267af48c8223f25bf602e852ee8)
@@ -0,0 +1,13 @@
+package it.finki.charitable;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class CharitableApplicationTests {
+
+    @Test
+    void contextLoads() {
+    }
+
+}
