Index: src/main/java/it/finki/charitable/config/MvcConfig.java
===================================================================
--- src/main/java/it/finki/charitable/config/MvcConfig.java	(revision 55775667201163b458d59d683882d62bc92839e0)
+++ src/main/java/it/finki/charitable/config/MvcConfig.java	(revision 55775667201163b458d59d683882d62bc92839e0)
@@ -0,0 +1,27 @@
+package it.finki.charitable.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+@Configuration
+public class MvcConfig implements WebMvcConfigurer {
+
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry registry) {
+        exposeDirectory("post-photos", registry);
+        exposeDirectory("moderator-photos", registry);
+    }
+
+    private void exposeDirectory(String dirName, ResourceHandlerRegistry registry) {
+        Path uploadDir = Paths.get(dirName);
+        String uploadPath = uploadDir.toFile().getAbsolutePath();
+        if(dirName.startsWith("../")) {
+            dirName = dirName.replace("../", "");
+        }
+        registry.addResourceHandler("/" + dirName + "/**").addResourceLocations("file:/"+ uploadPath + "/");
+    }
+}
Index: src/main/java/it/finki/charitable/controller/DonationPostController.java
===================================================================
--- src/main/java/it/finki/charitable/controller/DonationPostController.java	(revision 55775667201163b458d59d683882d62bc92839e0)
+++ src/main/java/it/finki/charitable/controller/DonationPostController.java	(revision 55775667201163b458d59d683882d62bc92839e0)
@@ -0,0 +1,199 @@
+package it.finki.charitable.controller;
+
+import it.finki.charitable.entities.AppUser;
+import it.finki.charitable.entities.DonationInformation;
+import it.finki.charitable.entities.DonationPost;
+import it.finki.charitable.entities.FundsCollected;
+import it.finki.charitable.services.DonationInformationService;
+import it.finki.charitable.services.DonationPostService;
+import it.finki.charitable.services.FundsCollectedService;
+import it.finki.charitable.services.UserService;
+import it.finki.charitable.util.FileUploadUtil;
+import org.springframework.data.domain.Page;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.IOException;
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+@Controller
+public class DonationPostController {
+
+    private final DonationPostService donationPostService;
+    private final UserService userService;
+    private final FundsCollectedService fundsCollectedService;
+    private final DonationInformationService donationInformationService;
+
+    public DonationPostController(DonationPostService donationPostService, UserService userService, FundsCollectedService fundsCollectedService, DonationInformationService donationInformationService) {
+        this.donationPostService = donationPostService;
+        this.userService = userService;
+        this.fundsCollectedService = fundsCollectedService;
+        this.donationInformationService = donationInformationService;
+    }
+
+    @RequestMapping("/upload")
+    public String upload() {
+        return "upload";
+    }
+
+    @RequestMapping(value = "/newPost", method = RequestMethod.POST)
+    public String newPost(Model model,
+                          @RequestParam String title,
+                          @RequestParam String fundsNeeded,
+                          @RequestParam String currency,
+                          @RequestParam String description,
+                          @RequestParam String telekom,
+                          @RequestParam String a1,
+                          @RequestParam(defaultValue = "2021-01-01") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate dateDue,
+                          @RequestParam String bankAccount,
+                          @RequestParam MultipartFile titleImage,
+                          @RequestParam MultipartFile[] images,
+                          @RequestParam MultipartFile[] moderatorImages) {
+
+        DonationPost post = new DonationPost();
+        post.setTitle(title);
+
+        try {
+            float funds = Float.parseFloat(fundsNeeded);
+            post.setFundsNeeded(funds);
+        } catch (NumberFormatException e) {
+            e.printStackTrace();
+        }
+
+        post.setCurrency(currency);
+        post.setDescription(description);
+        post.setDateDue(dateDue);
+        post.setBankAccount(bankAccount);
+
+        List<String> phoneNumbers = Arrays.asList(telekom, a1);
+
+        List<String> photos = new ArrayList<>();
+        photos.add(StringUtils.cleanPath(Objects.requireNonNull(titleImage.getOriginalFilename())));
+        Arrays.stream(images).filter(i -> !i.isEmpty()).forEach(i -> photos.add(StringUtils.cleanPath(Objects.requireNonNull(i.getOriginalFilename()))));
+
+        List<MultipartFile> files = new ArrayList<>();
+        files.add(titleImage);
+        files.addAll(Arrays.stream(images).filter(i -> !i.isEmpty()).collect(Collectors.toList()));
+
+        List<String> moderatorPhotos = new ArrayList<>();
+        Arrays.stream(moderatorImages).forEach(i -> moderatorPhotos.add(StringUtils.cleanPath(Objects.requireNonNull(i.getOriginalFilename()))));
+
+        post.setPhoneNumbers(phoneNumbers);
+        post.setImages(photos);
+        post.setModeratorImages(moderatorPhotos);
+
+        AppUser user = (AppUser) model.getAttribute("user");
+        post.setUser(user);
+
+        DonationPost savedPost = donationPostService.save(post);
+
+        for (MultipartFile file : files) {
+            String fileName = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename()));
+            String uploadDir = "post-photos/" + savedPost.getId();
+            try {
+                FileUploadUtil.saveFile(uploadDir, fileName, file);
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+
+        }
+
+        for (MultipartFile file : moderatorImages) {
+
+            String fileName = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename()));
+            String uploadDir = "moderator-photos/" + savedPost.getId();
+            try {
+                FileUploadUtil.saveFile(uploadDir, fileName, file);
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+
+        return "upload";
+    }
+
+    @RequestMapping("/album")
+    public String album(Model model) {
+        List<DonationPost> postList = donationPostService.findAll();
+        if (postList.size() == 0) {
+            model.addAttribute("noPosts", true);
+            return "album";
+        }
+        model.addAttribute("postList", postList);
+        return "album";
+    }
+
+    @RequestMapping("/post")
+    public String showPost(Model model, @RequestParam Long postid) {
+        DonationPost post = donationPostService.getById(postid);
+        if (post == null) {
+            model.addAttribute("notFound", true);
+            return "post";
+        }
+        AppUser user = post.getUser();
+        model.addAttribute("post", post);
+        model.addAttribute("createdByFirstName", user.getFirstName());
+        model.addAttribute("createdByLastName", user.getLastName());
+        double total = post.getFundsCollected().stream().mapToDouble(FundsCollected::getFunds).sum();
+        model.addAttribute("total", total);
+        return "post";
+    }
+
+    @RequestMapping("/deletePost")
+    public String deletePost(@RequestParam Long postid) {
+        DonationPost post = donationPostService.getById(postid);
+        if (post.getUser().getUsername().equals(SecurityContextHolder.getContext().getAuthentication().getName())) {
+            List<String> fileForDeletion = post.getPhotosForDeletion();
+            for (String f : fileForDeletion) {
+                File file = new File(f);
+                file.delete();
+            }
+            donationPostService.delete(post);
+        }
+
+        return "redirect:/myPosts";
+    }
+
+    @RequestMapping("/donate")
+    public String donate(Model model, @RequestParam Long postid,
+                         @RequestParam String cardName,
+                         @RequestParam String cardNumber,
+                         @RequestParam String expiryDate,
+                         @RequestParam String cvv,
+                         @RequestParam float amount) {
+
+        DonationPost post = donationPostService.getById(postid);
+        FundsCollected funds = new FundsCollected("online", amount);
+        fundsCollectedService.save(funds);
+
+        post.getFundsCollected().add(funds);
+        donationPostService.save(post);
+
+        DonationInformation donationInformation = new DonationInformation(amount, post.getId(), post.getTitle());
+        donationInformationService.save(donationInformation);
+        AppUser user = userService.loadUserByUsername(SecurityContextHolder.getContext().getAuthentication().getName());
+        user.getDonationInformation().add(donationInformation);
+        userService.saveUser(user);
+
+        return String.format("redirect:/post?postid=%d", postid);
+    }
+
+    @ModelAttribute("user")
+    public AppUser addAttributes() {
+        if (SecurityContextHolder.getContext().getAuthentication().getPrincipal() != "anonymousUser") {
+            return (AppUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+        }
+        return null;
+    }
+}
Index: src/main/java/it/finki/charitable/controller/HomeController.java
===================================================================
--- src/main/java/it/finki/charitable/controller/HomeController.java	(revision 55775667201163b458d59d683882d62bc92839e0)
+++ src/main/java/it/finki/charitable/controller/HomeController.java	(revision 55775667201163b458d59d683882d62bc92839e0)
@@ -0,0 +1,134 @@
+package it.finki.charitable.controller;
+
+import it.finki.charitable.entities.AppUser;
+import it.finki.charitable.entities.UserRole;
+import it.finki.charitable.security.ConfirmationToken;
+import it.finki.charitable.security.PasswordEncoder;
+import it.finki.charitable.services.ConfirmationTokenService;
+import it.finki.charitable.services.EmailService;
+import it.finki.charitable.services.UserService;
+import org.apache.commons.validator.routines.EmailValidator;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.security.Principal;
+import java.util.UUID;
+
+@Controller
+public class HomeController {
+
+    private final UserService userService;
+    private final ConfirmationTokenService confirmationTokenService;
+    private final EmailService emailService;
+
+    public HomeController(UserService userService, ConfirmationTokenService confirmationTokenService, EmailService emailService) {
+        this.userService = userService;
+        this.confirmationTokenService = confirmationTokenService;
+        this.emailService = emailService;
+    }
+
+    @RequestMapping("/")
+    public String index() {
+        return "index";
+    }
+
+    @RequestMapping("/login")
+    public String login(Principal principal) {
+        if(principal != null) {
+            return "redirect:/";
+        }
+
+        return "login";
+    }
+
+    @RequestMapping("/register")
+    public String register(Principal principal) {
+        if(principal != null) {
+            return "redirect:/";
+        }
+        return "register";
+    }
+
+    @RequestMapping(value = "/register", method = RequestMethod.POST)
+    public String newUser(Model model, @RequestParam String firstName,
+                          @RequestParam String lastName,
+                          @RequestParam String email,
+                          @RequestParam String password,
+                          @RequestParam String confirmPassword
+    ) {
+
+        boolean exists = userService.loadUserByUsername(email) != null;
+        if(exists) {
+            model.addAttribute("userExists", true);
+            return "register";
+        }
+
+        boolean error = false;
+        if(!EmailValidator.getInstance().isValid(email)) {
+            model.addAttribute("emailError", true);
+            error = true;
+        }
+
+        if(!password.equals(confirmPassword)) {
+            model.addAttribute("passwordError", true);
+            error = true;
+        }
+
+        if(firstName.isEmpty() || lastName.isEmpty()) {
+            model.addAttribute("nameError", true);
+            error = true;
+        }
+
+        if(error){
+            return "register";
+        }
+
+        AppUser user = new AppUser();
+        user.setFirstName(firstName);
+        user.setLastName(lastName);
+        user.setEmail(email);
+        user.setPassword(PasswordEncoder.bCryptPasswordEncoder().encode(password));
+        user.setUserRole(UserRole.USER);
+        user.setEnabled(false);
+
+        String token = UUID.randomUUID().toString();
+        ConfirmationToken confirmationToken = new ConfirmationToken(token, user);
+
+        userService.saveUser(user);
+        confirmationTokenService.saveConfirmationToken(confirmationToken);
+
+        emailService.sendValidationEmail(email, "CharitableMk account validation", token);
+
+        model.addAttribute("success",true);
+
+        return "register";
+    }
+
+    @RequestMapping("/validate")
+    public String validate(Model model, @RequestParam String token) {
+        ConfirmationToken confirmationToken = confirmationTokenService.getConfirmationToken(token);
+        if(confirmationToken != null) {
+            AppUser user = confirmationToken.getUser();
+            user.setEnabled(true);
+            userService.saveUser(user);
+            model.addAttribute("successValidation", true);
+            return "login";
+        }
+
+        model.addAttribute("error", true);
+        return "login";
+    }
+
+    @ModelAttribute("user")
+    public AppUser addAttributes() {
+        if(SecurityContextHolder.getContext().getAuthentication().getPrincipal() != "anonymousUser") {
+            return (AppUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+        }
+        return null;
+    }
+}
Index: src/main/java/it/finki/charitable/controller/UserProfileController.java
===================================================================
--- src/main/java/it/finki/charitable/controller/UserProfileController.java	(revision 55775667201163b458d59d683882d62bc92839e0)
+++ src/main/java/it/finki/charitable/controller/UserProfileController.java	(revision 55775667201163b458d59d683882d62bc92839e0)
@@ -0,0 +1,113 @@
+package it.finki.charitable.controller;
+
+import it.finki.charitable.entities.AppUser;
+import it.finki.charitable.entities.DonationInformation;
+import it.finki.charitable.entities.DonationPost;
+import it.finki.charitable.security.PasswordEncoder;
+import it.finki.charitable.services.DonationPostService;
+import it.finki.charitable.services.UserService;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.List;
+
+@Controller
+public class UserProfileController {
+
+    private final UserService userService;
+    private final DonationPostService donationPostService;
+
+    public UserProfileController(UserService userService, DonationPostService donationPostService) {
+        this.userService = userService;
+        this.donationPostService = donationPostService;
+    }
+
+    @RequestMapping("/userInformation")
+    public String userInformation(Model model) {
+        model.addAttribute("userInformation", true);
+        return "myProfile";
+    }
+
+    @RequestMapping("/myDonations")
+    public String myDonations(Model model) {
+        model.addAttribute("myDonations", true);
+        AppUser user = userService.loadUserByUsername(SecurityContextHolder.getContext().getAuthentication().getName());
+        List<DonationInformation> donations = user.getDonationInformation();
+        model.addAttribute("donations", donations);
+        double total = donations.stream().mapToDouble(DonationInformation::getDonatedAmount).sum();
+        model.addAttribute("total", total);
+        return "myProfile";
+    }
+
+    @RequestMapping("/myPosts")
+    public String myPosts(Model model) {
+        AppUser user = (AppUser) model.getAttribute("user");
+        List<DonationPost> posts = donationPostService.findAllByUser(user);
+        model.addAttribute("postList", posts);
+        model.addAttribute("myPosts", true);
+        return "myProfile";
+    }
+
+    @RequestMapping(value = "/changePassword", method = RequestMethod.POST)
+    public String changePassword(Model model,
+                                 @RequestParam String oldPassword,
+                                 @RequestParam String newPassword,
+                                 @RequestParam String confirmPassword) {
+
+        AppUser user = (AppUser) model.getAttribute("user");
+        if(PasswordEncoder.bCryptPasswordEncoder().matches(oldPassword, user.getPassword())) {
+            if(newPassword.equals(confirmPassword)) {
+                user.setPassword(PasswordEncoder.bCryptPasswordEncoder().encode(newPassword));
+                userService.saveUser(user);
+                model.addAttribute("changedPassword", true);
+                model.addAttribute("userInformation", true);
+                return "myProfile";
+            }
+        }
+
+        model.addAttribute("notChangedPassword", true);
+        model.addAttribute("userInformation", true);
+        return "myProfile";
+    }
+
+    @RequestMapping(value = "/changeCardInfo", method = RequestMethod.POST)
+    public String changeCardInfo(Model model,
+                                 @RequestParam String cardName,
+                                 @RequestParam String cardNumber,
+                                 @RequestParam String expiryDate,
+                                 @RequestParam String cvv) {
+
+        if(cardName.isEmpty() || cardNumber.isEmpty() || expiryDate.isEmpty() || cvv.isEmpty()) {
+            model.addAttribute("creditCardError", true);
+            model.addAttribute("userInformation", true);
+            return "myProfile";
+        }
+
+        AppUser user = (AppUser) model.getAttribute("user");
+        user.setCreditCardInfo(cardName + "," + cardNumber + "," + expiryDate + "," + cvv);
+        userService.saveUser(user);
+
+        return "redirect:/userInformation";
+    }
+
+    @RequestMapping("/removeCardInfo")
+    public String removeCardInfo(Model model) {
+        AppUser user = (AppUser) model.getAttribute("user");
+        user.setCreditCardInfo(null);
+        userService.saveUser(user);
+        return "redirect:/userInformation";
+    }
+
+    @ModelAttribute("user")
+    public AppUser addAttributes() {
+        if(SecurityContextHolder.getContext().getAuthentication().getPrincipal() != "anonymousUser") {
+            return (AppUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+        }
+        return null;
+    }
+}
Index: src/main/java/it/finki/charitable/entities/AppUser.java
===================================================================
--- src/main/java/it/finki/charitable/entities/AppUser.java	(revision 55775667201163b458d59d683882d62bc92839e0)
+++ src/main/java/it/finki/charitable/entities/AppUser.java	(revision 55775667201163b458d59d683882d62bc92839e0)
@@ -0,0 +1,152 @@
+package it.finki.charitable.entities;
+
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import javax.persistence.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+@Entity
+@Table(name = "app_user")
+public class AppUser implements UserDetails {
+
+    @SequenceGenerator(
+            name = "user_sequence",
+            sequenceName = "user_sequence",
+            allocationSize = 1
+    )
+    @GeneratedValue(
+            strategy = GenerationType.SEQUENCE,
+            generator = "user_sequence"
+    )
+    @Id
+    @Column(
+        name = "id",
+        nullable = false,
+        updatable = false
+    )
+    private Long id;
+
+    private String firstName;
+    private String lastName;
+    private String email;
+    private String password;
+    private String creditCardInfo;
+    @Enumerated(EnumType.STRING)
+    private UserRole userRole;
+    private Boolean enabled;
+
+    @OneToMany
+    private List<DonationInformation> donationInformation = new ArrayList<>();
+
+    public AppUser() {
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getCreditCardInfo() {
+        return creditCardInfo;
+    }
+
+    public void setCreditCardInfo(String creditCardInfo) {
+        this.creditCardInfo = creditCardInfo;
+    }
+
+    public UserRole getUserRole() {
+        return userRole;
+    }
+
+    public void setUserRole(UserRole userRole) {
+        this.userRole = userRole;
+    }
+
+    public Boolean getEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(Boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    public List<DonationInformation> getDonationInformation() {
+        return donationInformation;
+    }
+
+    public void setDonationInformation(List<DonationInformation> donationInformation) {
+        this.donationInformation = donationInformation;
+    }
+
+    @Override
+    public Collection<? extends GrantedAuthority> getAuthorities() {
+        SimpleGrantedAuthority authority = new SimpleGrantedAuthority(userRole.name());
+        return Collections.singletonList(authority);
+    }
+
+    @Override
+    public String getPassword() {
+        return password;
+    }
+
+    @Override
+    public String getUsername() {
+        return email;
+    }
+
+    @Override
+    public boolean isAccountNonExpired() {
+        return true;
+    }
+
+    @Override
+    public boolean isAccountNonLocked() {
+        return true;
+    }
+
+    @Override
+    public boolean isCredentialsNonExpired() {
+        return true;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return enabled;
+    }
+}
Index: src/main/java/it/finki/charitable/entities/DonationInformation.java
===================================================================
--- src/main/java/it/finki/charitable/entities/DonationInformation.java	(revision 55775667201163b458d59d683882d62bc92839e0)
+++ src/main/java/it/finki/charitable/entities/DonationInformation.java	(revision 55775667201163b458d59d683882d62bc92839e0)
@@ -0,0 +1,70 @@
+package it.finki.charitable.entities;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "donation_information")
+public class DonationInformation {
+
+    @SequenceGenerator(
+            name = "donation_information_sequence",
+            sequenceName = "donation_information_sequence",
+            allocationSize = 1
+    )
+    @GeneratedValue(
+            strategy = GenerationType.SEQUENCE,
+            generator = "donation_information_sequence"
+    )
+    @Id
+    @Column(
+            name = "id",
+            nullable = false,
+            updatable = false
+    )
+    private Long id;
+
+    private float donatedAmount;
+    private Long postId;
+    private String title;
+
+    public DonationInformation() {
+    }
+
+    public DonationInformation(float donatedAmount, Long postId, String title) {
+        this.donatedAmount = donatedAmount;
+        this.postId = postId;
+        this.title = title;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public float getDonatedAmount() {
+        return donatedAmount;
+    }
+
+    public void setDonatedAmount(float donatedAmount) {
+        this.donatedAmount = donatedAmount;
+    }
+
+    public Long getPostId() {
+        return postId;
+    }
+
+    public void setPostId(Long postId) {
+        this.postId = postId;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+}
Index: src/main/java/it/finki/charitable/entities/DonationPost.java
===================================================================
--- src/main/java/it/finki/charitable/entities/DonationPost.java	(revision 55775667201163b458d59d683882d62bc92839e0)
+++ src/main/java/it/finki/charitable/entities/DonationPost.java	(revision 55775667201163b458d59d683882d62bc92839e0)
@@ -0,0 +1,199 @@
+package it.finki.charitable.entities;
+
+import javax.persistence.*;
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
+
+@Entity
+@Table(name = "donation_post")
+public class DonationPost {
+
+    @SequenceGenerator(
+            name = "donation_post_sequence",
+            sequenceName = "donation_post_sequence",
+            allocationSize = 1
+    )
+    @GeneratedValue(
+            strategy = GenerationType.SEQUENCE,
+            generator = "donation_post_sequence"
+    )
+    @Id
+    @Column(
+            name = "id",
+            nullable = false,
+            updatable = false
+    )
+    private Long id;
+
+    private String title;
+    @Column(
+            name = "description",
+            columnDefinition = "TEXT"
+    )
+    private String description;
+    private float fundsNeeded;
+    private String currency;
+    private LocalDate dateDue;
+    private String bankAccount;
+
+    @ElementCollection
+    List<String> phoneNumbers;
+
+    @ElementCollection
+    List<String> images;
+
+    @ElementCollection
+    List<String> moderatorImages;
+
+    @ManyToOne
+    @JoinColumn(
+            nullable = false,
+            name = "app_user_id"
+    )
+    private AppUser user;
+
+    @OneToMany
+    private List<FundsCollected> fundsCollected = new ArrayList<>();
+
+    @Transient
+    public List<String> getImagesPath() {
+        if (images == null || id == null) return null;
+
+        List<String> photoPaths = new ArrayList<>();
+        for(String path: images) {
+            photoPaths.add("../../../../post-photos/" + id + "/" + path);
+        }
+
+        return photoPaths;
+    }
+
+    @Transient
+    public List<String> getModeratorPath() {
+        if (images == null || id == null) return null;
+
+        List<String> photoPaths = new ArrayList<>();
+        for(String path: images) {
+            photoPaths.add("../../../../moderator-photos/" + id + "/" + path);
+        }
+
+        return photoPaths;
+    }
+
+    @Transient
+    public List<String> getPhotosForDeletion() {
+        if (images == null || id == null) return null;
+
+        List<String> photoPaths = new ArrayList<>();
+        for(String path: images) {
+            photoPaths.add("post-photos\\" + id + "\\" + path);
+        }
+        photoPaths.add("post-photos\\" + id);
+
+        for(String path: moderatorImages) {
+            photoPaths.add("moderator-photos\\" + id + "\\" + path);
+        }
+        photoPaths.add("moderator-photos\\" + id);
+
+        return photoPaths;
+    }
+
+    public DonationPost() {
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public float getFundsNeeded() {
+        return fundsNeeded;
+    }
+
+    public void setFundsNeeded(float fundsNeeded) {
+        this.fundsNeeded = fundsNeeded;
+    }
+
+    public String getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(String currency) {
+        this.currency = currency;
+    }
+
+    public LocalDate getDateDue() {
+        return dateDue;
+    }
+
+    public void setDateDue(LocalDate dateDue) {
+        this.dateDue = dateDue;
+    }
+
+    public String getBankAccount() {
+        return bankAccount;
+    }
+
+    public void setBankAccount(String bankAccount) {
+        this.bankAccount = bankAccount;
+    }
+
+    public List<String> getPhoneNumbers() {
+        return phoneNumbers;
+    }
+
+    public void setPhoneNumbers(List<String> phoneNumbers) {
+        this.phoneNumbers = phoneNumbers;
+    }
+
+    public List<String> getImages() {
+        return images;
+    }
+
+    public void setImages(List<String> images) {
+        this.images = images;
+    }
+
+    public List<String> getModeratorImages() {
+        return moderatorImages;
+    }
+
+    public void setModeratorImages(List<String> moderatorImages) {
+        this.moderatorImages = moderatorImages;
+    }
+
+    public AppUser getUser() {
+        return user;
+    }
+
+    public void setUser(AppUser user) {
+        this.user = user;
+    }
+
+    public List<FundsCollected> getFundsCollected() {
+        return fundsCollected;
+    }
+
+    public void setFundsCollected(List<FundsCollected> fundsCollected) {
+        this.fundsCollected = fundsCollected;
+    }
+}
Index: src/main/java/it/finki/charitable/entities/FundsCollected.java
===================================================================
--- src/main/java/it/finki/charitable/entities/FundsCollected.java	(revision 55775667201163b458d59d683882d62bc92839e0)
+++ src/main/java/it/finki/charitable/entities/FundsCollected.java	(revision 55775667201163b458d59d683882d62bc92839e0)
@@ -0,0 +1,61 @@
+package it.finki.charitable.entities;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "funds_collected")
+public class FundsCollected {
+
+    @SequenceGenerator(
+            name = "funds_collected_sequence",
+            sequenceName = "funds_collected_sequence",
+            allocationSize = 1
+    )
+    @GeneratedValue(
+            strategy = GenerationType.SEQUENCE,
+            generator = "funds_collected_sequence"
+    )
+    @Id
+    @Column(
+            name = "id",
+            nullable = false,
+            updatable = false
+    )
+    private Long id;
+
+    private String description;
+
+    private float funds;
+
+    public FundsCollected() {
+    }
+
+    public FundsCollected(String description, float funds) {
+        this.description = description;
+        this.funds = funds;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public float getFunds() {
+        return funds;
+    }
+
+    public void setFunds(float funds) {
+        this.funds = funds;
+    }
+}
Index: src/main/java/it/finki/charitable/entities/UserRole.java
===================================================================
--- src/main/java/it/finki/charitable/entities/UserRole.java	(revision 55775667201163b458d59d683882d62bc92839e0)
+++ src/main/java/it/finki/charitable/entities/UserRole.java	(revision 55775667201163b458d59d683882d62bc92839e0)
@@ -0,0 +1,6 @@
+package it.finki.charitable.entities;
+
+public enum UserRole {
+    USER,
+    MODERATOR
+}
