Index: src/main/java/it/finki/charitable/controller/DonationPostController.java
===================================================================
--- src/main/java/it/finki/charitable/controller/DonationPostController.java	(revision 881a23306a8fde99ee391c46651f93ecdd68bc00)
+++ src/main/java/it/finki/charitable/controller/DonationPostController.java	(revision b8dc7612c4ce79e01dfe5fa1fe25e62186eefcdb)
@@ -14,4 +14,5 @@
 
 import java.io.IOException;
+import java.time.Duration;
 import java.time.LocalDate;
 import java.util.*;
@@ -87,4 +88,8 @@
         post.setBankAccount(bankAccount);
         post.setApproved(false);
+        post.setCreatedAt(LocalDate.now());
+        long totalDays = Duration.between(post.getCreatedAt().atTime(0, 0, 0), post.getDateDue().atTime(0, 0, 0)).toDays();
+        if(totalDays < 10)
+            post.setRiskFactor(0);
 
         List<String> phoneNumbers = Arrays.asList(telekom, a1);
@@ -169,11 +174,16 @@
                     allPosts.sort(Comparator.comparing(DonationPost::getFundsNeeded).reversed());
                 }
+            } else if (sort.equals("riskFactor")) {
+                if (order.equals("asc")) {
+                    allPosts.sort(Comparator.comparing(DonationPost::getRiskFactor));
+                } else {
+                    allPosts.sort(Comparator.comparing(DonationPost::getRiskFactor).reversed());
+                }
             }
 
             if (groupBy.equals("completed")) {
-                List<DonationPost> completed = allPosts.stream().filter(post -> {
-                    double fundsCollected = post.getFundsCollected().stream().mapToDouble(FundsCollected::getFunds).sum();
-                    return fundsCollected >= post.getFundsNeeded();
-                }).collect(Collectors.toList());
+                List<DonationPost> completed = allPosts.stream()
+                        .filter(post -> post.getTotalFundsCollected() >= post.getFundsNeeded())
+                        .collect(Collectors.toList());
 
                 int start = (int) pageable.getOffset();
@@ -213,5 +223,6 @@
         }
 
-        if (post.getApproved() || (post.getUser().getUsername().equals(SecurityContextHolder.getContext().getAuthentication().getName()) && !post.getApproved())) {
+        AppUser currentUser = (AppUser) model.getAttribute("user");
+        if (post.getApproved() || (post.getUser().getUsername().equals(currentUser.getUsername()) && !post.getApproved())) {
             AppUser user = post.getUser();
             Moderator moderator = post.getModerator();
@@ -223,6 +234,4 @@
                 model.addAttribute("moderatorLastName", moderator.getLastName());
             }
-            double total = post.getFundsCollected().stream().mapToDouble(FundsCollected::getFunds).sum();
-            model.addAttribute("total", total);
         } else {
             model.addAttribute("notFound", true);
@@ -250,5 +259,4 @@
                 return String.format("redirect:/post?postid=%d&error", postid);
             }
-            post.setFundsNeeded(donatedAmount);
         } catch (NumberFormatException e) {
             return String.format("redirect:/post?postid=%d&error", postid);
@@ -259,4 +267,10 @@
 
         post.getFundsCollected().add(funds);
+        post.setTotalFundsCollected(post.getTotalFundsCollected() + donatedAmount);
+
+        if(post.getRiskFactor() != 101) {
+            post.setRiskFactor(getRisk(post));
+        }
+
         donationPostService.save(post);
 
@@ -295,7 +309,31 @@
     public AppUser addAttributes() {
         if (SecurityContextHolder.getContext().getAuthentication().getPrincipal() != "anonymousUser") {
-            return (AppUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+
+            String email = SecurityContextHolder.getContext().getAuthentication().getName();
+            return userService.loadUserByUsername(email);
         }
         return null;
     }
+
+    private Integer getRisk(DonationPost post) {
+        float dailyAverage = post.getTotalFundsCollected() / (Duration.between(post.getCreatedAt().atTime(0, 0, 0), LocalDate.now().atTime(0, 0, 0)).toDays()+1);
+        float neededAverage = (post.getFundsNeeded() - post.getTotalFundsCollected()) / (Duration.between(LocalDate.now().atTime(0, 0, 0), post.getDateDue().atTime(0, 0, 0)).toDays()+1);
+
+        System.out.println(dailyAverage + " " + neededAverage);
+        int risk = (int) (dailyAverage / neededAverage * 100);
+
+        if(risk > 100) {
+            risk = 100;
+        }
+
+        if(Duration.between(LocalDate.now().atTime(0, 0, 0), post.getDateDue().atTime(0, 0, 0)).toDays() == 0) {
+            risk = 0;
+        }
+
+        if(post.getFundsNeeded() <= post.getTotalFundsCollected()) {
+            risk = 101;
+        }
+
+        return risk;
+    }
 }
Index: src/main/java/it/finki/charitable/controller/HomeController.java
===================================================================
--- src/main/java/it/finki/charitable/controller/HomeController.java	(revision 881a23306a8fde99ee391c46651f93ecdd68bc00)
+++ src/main/java/it/finki/charitable/controller/HomeController.java	(revision b8dc7612c4ce79e01dfe5fa1fe25e62186eefcdb)
@@ -129,6 +129,8 @@
     @ModelAttribute("user")
     public AppUser addAttributes() {
-        if(SecurityContextHolder.getContext().getAuthentication().getPrincipal() != "anonymousUser") {
-            return (AppUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+        if (SecurityContextHolder.getContext().getAuthentication().getPrincipal() != "anonymousUser") {
+            String email = SecurityContextHolder.getContext().getAuthentication().getName();
+            System.out.println(email);
+            return userService.loadUserByUsername(email);
         }
         return null;
Index: src/main/java/it/finki/charitable/controller/UserProfileController.java
===================================================================
--- src/main/java/it/finki/charitable/controller/UserProfileController.java	(revision 881a23306a8fde99ee391c46651f93ecdd68bc00)
+++ src/main/java/it/finki/charitable/controller/UserProfileController.java	(revision b8dc7612c4ce79e01dfe5fa1fe25e62186eefcdb)
@@ -115,4 +115,5 @@
             fundsCollectedService.save(funds);
             post.getFundsCollected().add(funds);
+            post.setTotalFundsCollected(post.getTotalFundsCollected() + amount);
             donationPostService.save(post);
         }
@@ -122,6 +123,8 @@
     @ModelAttribute("user")
     public AppUser addAttributes() {
-        if(SecurityContextHolder.getContext().getAuthentication().getPrincipal() != "anonymousUser") {
-            return (AppUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+        if (SecurityContextHolder.getContext().getAuthentication().getPrincipal() != "anonymousUser") {
+
+            String email = SecurityContextHolder.getContext().getAuthentication().getName();
+            return userService.loadUserByUsername(email);
         }
         return null;
Index: src/main/java/it/finki/charitable/entities/DonationPost.java
===================================================================
--- src/main/java/it/finki/charitable/entities/DonationPost.java	(revision 881a23306a8fde99ee391c46651f93ecdd68bc00)
+++ src/main/java/it/finki/charitable/entities/DonationPost.java	(revision b8dc7612c4ce79e01dfe5fa1fe25e62186eefcdb)
@@ -61,4 +61,8 @@
     private List<FundsCollected> fundsCollected = new ArrayList<>();
 
+    private Float totalFundsCollected = 0f;
+    private LocalDate createdAt;
+    private Integer riskFactor = 101;
+
     @Transient
     public List<String> getImagesPath() {
@@ -222,3 +226,27 @@
         this.fundsCollected = fundsCollected;
     }
+
+    public Float getTotalFundsCollected() {
+        return totalFundsCollected;
+    }
+
+    public void setTotalFundsCollected(Float totalFundsCollected) {
+        this.totalFundsCollected = totalFundsCollected;
+    }
+
+    public LocalDate getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(LocalDate createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public Integer getRiskFactor() {
+        return riskFactor;
+    }
+
+    public void setRiskFactor(Integer riskFactor) {
+        this.riskFactor = riskFactor;
+    }
 }
Index: src/main/java/it/finki/charitable/security/O2AuthSuccessHandler.java
===================================================================
--- src/main/java/it/finki/charitable/security/O2AuthSuccessHandler.java	(revision b8dc7612c4ce79e01dfe5fa1fe25e62186eefcdb)
+++ src/main/java/it/finki/charitable/security/O2AuthSuccessHandler.java	(revision b8dc7612c4ce79e01dfe5fa1fe25e62186eefcdb)
@@ -0,0 +1,49 @@
+package it.finki.charitable.security;
+
+import it.finki.charitable.entities.AppUser;
+import it.finki.charitable.entities.MainUser;
+import it.finki.charitable.entities.UserRole;
+import it.finki.charitable.services.UserService;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
+import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
+import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.UUID;
+
+@Component
+public class O2AuthSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
+
+    private final UserService userService;
+
+    public O2AuthSuccessHandler(UserService userService) {
+        this.userService = userService;
+    }
+
+    @Override
+    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException {
+
+        UserO2Auth userO2Auth = (UserO2Auth) authentication.getPrincipal();
+        String email = userO2Auth.getName();
+        AppUser user = userService.loadUserByUsername(email);
+        if(user == null) {
+            AppUser newUser = new MainUser();
+            String[] name = userO2Auth.getAttribute("name").toString().split(" ");
+            newUser.setFirstName(name[0]);
+            newUser.setLastName(name[1]);
+            newUser.setEmail(email);
+            newUser.setPassword(PasswordEncoder.bCryptPasswordEncoder().encode(UUID.randomUUID().toString()));
+            newUser.setUserRole(UserRole.USER);
+            newUser.setEnabled(true);
+            userService.saveUser(newUser);
+        }
+
+        super.onAuthenticationSuccess(request, response, authentication);
+    }
+}
Index: src/main/java/it/finki/charitable/security/SecurityConfig.java
===================================================================
--- src/main/java/it/finki/charitable/security/SecurityConfig.java	(revision 881a23306a8fde99ee391c46651f93ecdd68bc00)
+++ src/main/java/it/finki/charitable/security/SecurityConfig.java	(revision b8dc7612c4ce79e01dfe5fa1fe25e62186eefcdb)
@@ -3,9 +3,9 @@
 import it.finki.charitable.entities.UserRole;
 import it.finki.charitable.services.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
 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.core.Authentication;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.security.web.DefaultRedirectStrategy;
@@ -14,11 +14,11 @@
 import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
 
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-
 @Configuration
 public class SecurityConfig extends WebSecurityConfigurerAdapter {
+
+    @Autowired
+    private UserO2AuthService userO2AuthService;
+    @Autowired
+    private O2AuthSuccessHandler o2AuthSuccessHandler;
 
     private final UserService userService;
@@ -41,5 +41,6 @@
             "/album/**",
             "/post",
-            "/post-photos/**"
+            "/post-photos/**",
+            "/oauth2/authorization/google"
     };
 
@@ -58,4 +59,11 @@
                 .successHandler(authenticationSuccessHandler)
                 .and()
+                .oauth2Login()
+                .loginPage("/login")
+                .userInfoEndpoint()
+                .userService(userO2AuthService)
+                .and()
+                .successHandler(o2AuthSuccessHandler)
+                .and()
                 .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                 .logoutSuccessUrl("/").deleteCookies("remember-me")
@@ -73,4 +81,6 @@
     };
 
+
+
     @Override
     protected void configure(AuthenticationManagerBuilder auth) throws Exception {
Index: src/main/java/it/finki/charitable/security/UserO2Auth.java
===================================================================
--- src/main/java/it/finki/charitable/security/UserO2Auth.java	(revision b8dc7612c4ce79e01dfe5fa1fe25e62186eefcdb)
+++ src/main/java/it/finki/charitable/security/UserO2Auth.java	(revision b8dc7612c4ce79e01dfe5fa1fe25e62186eefcdb)
@@ -0,0 +1,34 @@
+package it.finki.charitable.security;
+
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.oauth2.core.user.OAuth2User;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+public class UserO2Auth implements OAuth2User {
+
+    private OAuth2User oAuth2User;
+
+    public UserO2Auth(OAuth2User oAuth2User) {
+        this.oAuth2User = oAuth2User;
+    }
+
+    @Override
+    public Map<String, Object> getAttributes() {
+        return oAuth2User.getAttributes();
+    }
+
+    @Override
+    public Collection<? extends GrantedAuthority> getAuthorities() {
+        SimpleGrantedAuthority authority = new SimpleGrantedAuthority("USER");
+        return Collections.singletonList(authority);
+    }
+
+    @Override
+    public String getName() {
+        return oAuth2User.getAttribute("email");
+    }
+}
Index: src/main/java/it/finki/charitable/security/UserO2AuthService.java
===================================================================
--- src/main/java/it/finki/charitable/security/UserO2AuthService.java	(revision b8dc7612c4ce79e01dfe5fa1fe25e62186eefcdb)
+++ src/main/java/it/finki/charitable/security/UserO2AuthService.java	(revision b8dc7612c4ce79e01dfe5fa1fe25e62186eefcdb)
@@ -0,0 +1,16 @@
+package it.finki.charitable.security;
+
+import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
+import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
+import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
+import org.springframework.security.oauth2.core.user.OAuth2User;
+import org.springframework.stereotype.Service;
+
+@Service
+public class UserO2AuthService extends DefaultOAuth2UserService {
+
+    @Override
+    public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
+        return new UserO2Auth(super.loadUser(userRequest));
+    }
+}
Index: src/main/java/it/finki/charitable/services/EmailService.java
===================================================================
--- src/main/java/it/finki/charitable/services/EmailService.java	(revision 881a23306a8fde99ee391c46651f93ecdd68bc00)
+++ src/main/java/it/finki/charitable/services/EmailService.java	(revision b8dc7612c4ce79e01dfe5fa1fe25e62186eefcdb)
@@ -1,6 +1,8 @@
 package it.finki.charitable.services;
 
+import it.finki.charitable.entities.EmailMessage;
 import org.springframework.mail.SimpleMailMessage;
 import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Component;
 
@@ -9,7 +11,9 @@
 
     private final JavaMailSender javaMailSender;
+    private final EmailMessageService emailMessageService;
 
-    public EmailService(JavaMailSender javaMailSender) {
+    public EmailService(JavaMailSender javaMailSender, EmailMessageService emailMessageService) {
         this.javaMailSender = javaMailSender;
+        this.emailMessageService = emailMessageService;
     }
 
@@ -20,7 +24,7 @@
 
         String text = "Verify your account on the following link\n" +
-                "http://localhost:8080/validate?token=" + token;
+                "http://localhost:9091/validate?token=" + token;
         message.setText(text);
-        javaMailSender.send(message);
+        sendMail(message);
     }
 
@@ -30,7 +34,7 @@
         message.setSubject(subject);
 
-        String text = "Your post has been approved\n" + "http://localhost:8080/post?postid=" + postId;
+        String text = "Your post has been approved\n" + "http://localhost:9091/post?postid=" + postId;
         message.setText(text);
-        javaMailSender.send(message);
+        sendMail(message);
     }
 
@@ -43,5 +47,5 @@
                 "Moderator:\n" + description;
         message.setText(text);
-        javaMailSender.send(message);
+        sendMail(message);
     }
 
@@ -54,5 +58,15 @@
                 "Moderator:\n" + description;
         message.setText(text);
-        javaMailSender.send(message);
+        sendMail(message);
+    }
+
+    @Async
+    public void sendMail(SimpleMailMessage message) {
+        try {
+            javaMailSender.send(message);
+
+        } catch (Exception e) {
+            emailMessageService.save(new EmailMessage(message.getTo()[0], message.getSubject(), message.getText()));
+        }
     }
 }
Index: src/main/java/it/finki/charitable/util/AutomaticEvents.java
===================================================================
--- src/main/java/it/finki/charitable/util/AutomaticEvents.java	(revision 881a23306a8fde99ee391c46651f93ecdd68bc00)
+++ src/main/java/it/finki/charitable/util/AutomaticEvents.java	(revision b8dc7612c4ce79e01dfe5fa1fe25e62186eefcdb)
@@ -2,11 +2,16 @@
 
 import it.finki.charitable.entities.AppUser;
+import it.finki.charitable.entities.DonationPost;
+import it.finki.charitable.entities.EmailMessage;
 import it.finki.charitable.security.ConfirmationToken;
-import it.finki.charitable.services.ConfirmationTokenService;
-import it.finki.charitable.services.UserService;
+import it.finki.charitable.services.*;
+import org.springframework.mail.SimpleMailMessage;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 
+import java.time.Duration;
+import java.time.LocalDate;
 import java.util.List;
+import java.util.stream.Collectors;
 
 @Component
@@ -15,8 +20,14 @@
     private final UserService userService;
     private final ConfirmationTokenService confirmationTokenService;
+    private final DonationPostService donationPostService;
+    private final EmailMessageService emailMessageService;
+    private final EmailService emailService;
 
-    public AutomaticEvents(UserService userService, ConfirmationTokenService confirmationTokenService) {
+    public AutomaticEvents(UserService userService, ConfirmationTokenService confirmationTokenService, DonationPostService donationPostService, EmailMessageService emailMessageService, EmailService emailService) {
         this.userService = userService;
         this.confirmationTokenService = confirmationTokenService;
+        this.donationPostService = donationPostService;
+        this.emailMessageService = emailMessageService;
+        this.emailService = emailService;
     }
 
@@ -32,3 +43,55 @@
         }
     }
+
+    @Scheduled(cron = "0 0 0 * * *")
+    public void setRisk() {
+        System.out.println("cron");
+        List<DonationPost> donationPosts = donationPostService.findAll();
+        donationPosts = donationPosts.stream().filter(post -> {
+            long daysToEnd = Duration.between(LocalDate.now().atTime(0, 0, 0), post.getDateDue().atTime(0, 0, 0)).toDays();
+            long totalDays = Duration.between(post.getCreatedAt().atTime(0, 0, 0), post.getDateDue().atTime(0, 0, 0)).toDays();
+            System.out.println(daysToEnd + " " + totalDays);
+
+            if(totalDays < 10)
+                return true;
+
+            return (daysToEnd * 1f/totalDays) * 100 < 75;
+        }).collect(Collectors.toList());
+
+        donationPosts.forEach(post -> {
+            float dailyAverage = post.getTotalFundsCollected() / (Duration.between(post.getCreatedAt().atTime(0, 0, 0), LocalDate.now().atTime(0, 0, 0)).toDays() + 1);
+            float neededAverage = (post.getFundsNeeded() - post.getTotalFundsCollected()) / (Duration.between(LocalDate.now().atTime(0, 0, 0), post.getDateDue().atTime(0, 0, 0)).toDays()+1);
+
+            System.out.println(dailyAverage + " " + neededAverage);
+            int risk = (int) (dailyAverage / neededAverage * 100);
+
+            if(risk > 100) {
+                risk = 100;
+            }
+
+            if(Duration.between(LocalDate.now().atTime(0, 0, 0), post.getDateDue().atTime(0, 0, 0)).toDays() == 0) {
+                risk = 0;
+            }
+
+            if(post.getFundsNeeded() <= post.getTotalFundsCollected()) {
+                risk = 101;
+            }
+
+            post.setRiskFactor(risk);
+            donationPostService.save(post);
+        });
+    }
+
+    @Scheduled(cron = "0 0 * * * *")
+    public void sendMessages() {
+        List<EmailMessage> messages = emailMessageService.findAll();
+        for(EmailMessage message: messages) {
+            SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
+            simpleMailMessage.setTo(message.getSendTo());
+            simpleMailMessage.setSubject(message.getSubject());
+            simpleMailMessage.setText(message.getText());
+            emailService.sendMail(simpleMailMessage);
+            emailMessageService.delete(message);
+        }
+    }
 }
