Changeset b8dc761


Ignore:
Timestamp:
01/05/22 15:57:29 (2 years ago)
Author:
NikolaCenevski <cenevskinikola@…>
Branches:
master
Children:
6fa3d09
Parents:
881a233
Message:

part 2

Files:
4 added
12 edited

Legend:

Unmodified
Added
Removed
  • pom.xml

    r881a233 rb8dc761  
    6969            <artifactId>spring-boot-starter-mail</artifactId>
    7070        </dependency>
     71        <dependency>
     72            <groupId>org.springframework.boot</groupId>
     73            <artifactId>spring-boot-starter-oauth2-client</artifactId>
     74        </dependency>
    7175    </dependencies>
    7276
  • src/main/java/it/finki/charitable/controller/DonationPostController.java

    r881a233 rb8dc761  
    1414
    1515import java.io.IOException;
     16import java.time.Duration;
    1617import java.time.LocalDate;
    1718import java.util.*;
     
    8788        post.setBankAccount(bankAccount);
    8889        post.setApproved(false);
     90        post.setCreatedAt(LocalDate.now());
     91        long totalDays = Duration.between(post.getCreatedAt().atTime(0, 0, 0), post.getDateDue().atTime(0, 0, 0)).toDays();
     92        if(totalDays < 10)
     93            post.setRiskFactor(0);
    8994
    9095        List<String> phoneNumbers = Arrays.asList(telekom, a1);
     
    169174                    allPosts.sort(Comparator.comparing(DonationPost::getFundsNeeded).reversed());
    170175                }
     176            } else if (sort.equals("riskFactor")) {
     177                if (order.equals("asc")) {
     178                    allPosts.sort(Comparator.comparing(DonationPost::getRiskFactor));
     179                } else {
     180                    allPosts.sort(Comparator.comparing(DonationPost::getRiskFactor).reversed());
     181                }
    171182            }
    172183
    173184            if (groupBy.equals("completed")) {
    174                 List<DonationPost> completed = allPosts.stream().filter(post -> {
    175                     double fundsCollected = post.getFundsCollected().stream().mapToDouble(FundsCollected::getFunds).sum();
    176                     return fundsCollected >= post.getFundsNeeded();
    177                 }).collect(Collectors.toList());
     185                List<DonationPost> completed = allPosts.stream()
     186                        .filter(post -> post.getTotalFundsCollected() >= post.getFundsNeeded())
     187                        .collect(Collectors.toList());
    178188
    179189                int start = (int) pageable.getOffset();
     
    213223        }
    214224
    215         if (post.getApproved() || (post.getUser().getUsername().equals(SecurityContextHolder.getContext().getAuthentication().getName()) && !post.getApproved())) {
     225        AppUser currentUser = (AppUser) model.getAttribute("user");
     226        if (post.getApproved() || (post.getUser().getUsername().equals(currentUser.getUsername()) && !post.getApproved())) {
    216227            AppUser user = post.getUser();
    217228            Moderator moderator = post.getModerator();
     
    223234                model.addAttribute("moderatorLastName", moderator.getLastName());
    224235            }
    225             double total = post.getFundsCollected().stream().mapToDouble(FundsCollected::getFunds).sum();
    226             model.addAttribute("total", total);
    227236        } else {
    228237            model.addAttribute("notFound", true);
     
    250259                return String.format("redirect:/post?postid=%d&error", postid);
    251260            }
    252             post.setFundsNeeded(donatedAmount);
    253261        } catch (NumberFormatException e) {
    254262            return String.format("redirect:/post?postid=%d&error", postid);
     
    259267
    260268        post.getFundsCollected().add(funds);
     269        post.setTotalFundsCollected(post.getTotalFundsCollected() + donatedAmount);
     270
     271        if(post.getRiskFactor() != 101) {
     272            post.setRiskFactor(getRisk(post));
     273        }
     274
    261275        donationPostService.save(post);
    262276
     
    295309    public AppUser addAttributes() {
    296310        if (SecurityContextHolder.getContext().getAuthentication().getPrincipal() != "anonymousUser") {
    297             return (AppUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
     311
     312            String email = SecurityContextHolder.getContext().getAuthentication().getName();
     313            return userService.loadUserByUsername(email);
    298314        }
    299315        return null;
    300316    }
     317
     318    private Integer getRisk(DonationPost post) {
     319        float dailyAverage = post.getTotalFundsCollected() / (Duration.between(post.getCreatedAt().atTime(0, 0, 0), LocalDate.now().atTime(0, 0, 0)).toDays()+1);
     320        float neededAverage = (post.getFundsNeeded() - post.getTotalFundsCollected()) / (Duration.between(LocalDate.now().atTime(0, 0, 0), post.getDateDue().atTime(0, 0, 0)).toDays()+1);
     321
     322        System.out.println(dailyAverage + " " + neededAverage);
     323        int risk = (int) (dailyAverage / neededAverage * 100);
     324
     325        if(risk > 100) {
     326            risk = 100;
     327        }
     328
     329        if(Duration.between(LocalDate.now().atTime(0, 0, 0), post.getDateDue().atTime(0, 0, 0)).toDays() == 0) {
     330            risk = 0;
     331        }
     332
     333        if(post.getFundsNeeded() <= post.getTotalFundsCollected()) {
     334            risk = 101;
     335        }
     336
     337        return risk;
     338    }
    301339}
  • src/main/java/it/finki/charitable/controller/HomeController.java

    r881a233 rb8dc761  
    129129    @ModelAttribute("user")
    130130    public AppUser addAttributes() {
    131         if(SecurityContextHolder.getContext().getAuthentication().getPrincipal() != "anonymousUser") {
    132             return (AppUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
     131        if (SecurityContextHolder.getContext().getAuthentication().getPrincipal() != "anonymousUser") {
     132            String email = SecurityContextHolder.getContext().getAuthentication().getName();
     133            System.out.println(email);
     134            return userService.loadUserByUsername(email);
    133135        }
    134136        return null;
  • src/main/java/it/finki/charitable/controller/UserProfileController.java

    r881a233 rb8dc761  
    115115            fundsCollectedService.save(funds);
    116116            post.getFundsCollected().add(funds);
     117            post.setTotalFundsCollected(post.getTotalFundsCollected() + amount);
    117118            donationPostService.save(post);
    118119        }
     
    122123    @ModelAttribute("user")
    123124    public AppUser addAttributes() {
    124         if(SecurityContextHolder.getContext().getAuthentication().getPrincipal() != "anonymousUser") {
    125             return (AppUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
     125        if (SecurityContextHolder.getContext().getAuthentication().getPrincipal() != "anonymousUser") {
     126
     127            String email = SecurityContextHolder.getContext().getAuthentication().getName();
     128            return userService.loadUserByUsername(email);
    126129        }
    127130        return null;
  • src/main/java/it/finki/charitable/entities/DonationPost.java

    r881a233 rb8dc761  
    6161    private List<FundsCollected> fundsCollected = new ArrayList<>();
    6262
     63    private Float totalFundsCollected = 0f;
     64    private LocalDate createdAt;
     65    private Integer riskFactor = 101;
     66
    6367    @Transient
    6468    public List<String> getImagesPath() {
     
    222226        this.fundsCollected = fundsCollected;
    223227    }
     228
     229    public Float getTotalFundsCollected() {
     230        return totalFundsCollected;
     231    }
     232
     233    public void setTotalFundsCollected(Float totalFundsCollected) {
     234        this.totalFundsCollected = totalFundsCollected;
     235    }
     236
     237    public LocalDate getCreatedAt() {
     238        return createdAt;
     239    }
     240
     241    public void setCreatedAt(LocalDate createdAt) {
     242        this.createdAt = createdAt;
     243    }
     244
     245    public Integer getRiskFactor() {
     246        return riskFactor;
     247    }
     248
     249    public void setRiskFactor(Integer riskFactor) {
     250        this.riskFactor = riskFactor;
     251    }
    224252}
  • src/main/java/it/finki/charitable/security/SecurityConfig.java

    r881a233 rb8dc761  
    33import it.finki.charitable.entities.UserRole;
    44import it.finki.charitable.services.UserService;
     5import org.springframework.beans.factory.annotation.Autowired;
    56import org.springframework.context.annotation.Configuration;
    67import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    78import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    89import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    9 import org.springframework.security.core.Authentication;
    1010import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    1111import org.springframework.security.web.DefaultRedirectStrategy;
     
    1414import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
    1515
    16 import javax.servlet.ServletException;
    17 import javax.servlet.http.HttpServletRequest;
    18 import javax.servlet.http.HttpServletResponse;
    19 import java.io.IOException;
    20 
    2116@Configuration
    2217public class SecurityConfig extends WebSecurityConfigurerAdapter {
     18
     19    @Autowired
     20    private UserO2AuthService userO2AuthService;
     21    @Autowired
     22    private O2AuthSuccessHandler o2AuthSuccessHandler;
    2323
    2424    private final UserService userService;
     
    4141            "/album/**",
    4242            "/post",
    43             "/post-photos/**"
     43            "/post-photos/**",
     44            "/oauth2/authorization/google"
    4445    };
    4546
     
    5859                .successHandler(authenticationSuccessHandler)
    5960                .and()
     61                .oauth2Login()
     62                .loginPage("/login")
     63                .userInfoEndpoint()
     64                .userService(userO2AuthService)
     65                .and()
     66                .successHandler(o2AuthSuccessHandler)
     67                .and()
    6068                .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
    6169                .logoutSuccessUrl("/").deleteCookies("remember-me")
     
    7381    };
    7482
     83
     84
    7585    @Override
    7686    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  • src/main/java/it/finki/charitable/services/EmailService.java

    r881a233 rb8dc761  
    11package it.finki.charitable.services;
    22
     3import it.finki.charitable.entities.EmailMessage;
    34import org.springframework.mail.SimpleMailMessage;
    45import org.springframework.mail.javamail.JavaMailSender;
     6import org.springframework.scheduling.annotation.Async;
    57import org.springframework.stereotype.Component;
    68
     
    911
    1012    private final JavaMailSender javaMailSender;
     13    private final EmailMessageService emailMessageService;
    1114
    12     public EmailService(JavaMailSender javaMailSender) {
     15    public EmailService(JavaMailSender javaMailSender, EmailMessageService emailMessageService) {
    1316        this.javaMailSender = javaMailSender;
     17        this.emailMessageService = emailMessageService;
    1418    }
    1519
     
    2024
    2125        String text = "Verify your account on the following link\n" +
    22                 "http://localhost:8080/validate?token=" + token;
     26                "http://localhost:9091/validate?token=" + token;
    2327        message.setText(text);
    24         javaMailSender.send(message);
     28        sendMail(message);
    2529    }
    2630
     
    3034        message.setSubject(subject);
    3135
    32         String text = "Your post has been approved\n" + "http://localhost:8080/post?postid=" + postId;
     36        String text = "Your post has been approved\n" + "http://localhost:9091/post?postid=" + postId;
    3337        message.setText(text);
    34         javaMailSender.send(message);
     38        sendMail(message);
    3539    }
    3640
     
    4347                "Moderator:\n" + description;
    4448        message.setText(text);
    45         javaMailSender.send(message);
     49        sendMail(message);
    4650    }
    4751
     
    5458                "Moderator:\n" + description;
    5559        message.setText(text);
    56         javaMailSender.send(message);
     60        sendMail(message);
     61    }
     62
     63    @Async
     64    public void sendMail(SimpleMailMessage message) {
     65        try {
     66            javaMailSender.send(message);
     67
     68        } catch (Exception e) {
     69            emailMessageService.save(new EmailMessage(message.getTo()[0], message.getSubject(), message.getText()));
     70        }
    5771    }
    5872}
  • src/main/java/it/finki/charitable/util/AutomaticEvents.java

    r881a233 rb8dc761  
    22
    33import it.finki.charitable.entities.AppUser;
     4import it.finki.charitable.entities.DonationPost;
     5import it.finki.charitable.entities.EmailMessage;
    46import it.finki.charitable.security.ConfirmationToken;
    5 import it.finki.charitable.services.ConfirmationTokenService;
    6 import it.finki.charitable.services.UserService;
     7import it.finki.charitable.services.*;
     8import org.springframework.mail.SimpleMailMessage;
    79import org.springframework.scheduling.annotation.Scheduled;
    810import org.springframework.stereotype.Component;
    911
     12import java.time.Duration;
     13import java.time.LocalDate;
    1014import java.util.List;
     15import java.util.stream.Collectors;
    1116
    1217@Component
     
    1520    private final UserService userService;
    1621    private final ConfirmationTokenService confirmationTokenService;
     22    private final DonationPostService donationPostService;
     23    private final EmailMessageService emailMessageService;
     24    private final EmailService emailService;
    1725
    18     public AutomaticEvents(UserService userService, ConfirmationTokenService confirmationTokenService) {
     26    public AutomaticEvents(UserService userService, ConfirmationTokenService confirmationTokenService, DonationPostService donationPostService, EmailMessageService emailMessageService, EmailService emailService) {
    1927        this.userService = userService;
    2028        this.confirmationTokenService = confirmationTokenService;
     29        this.donationPostService = donationPostService;
     30        this.emailMessageService = emailMessageService;
     31        this.emailService = emailService;
    2132    }
    2233
     
    3243        }
    3344    }
     45
     46    @Scheduled(cron = "0 0 0 * * *")
     47    public void setRisk() {
     48        System.out.println("cron");
     49        List<DonationPost> donationPosts = donationPostService.findAll();
     50        donationPosts = donationPosts.stream().filter(post -> {
     51            long daysToEnd = Duration.between(LocalDate.now().atTime(0, 0, 0), post.getDateDue().atTime(0, 0, 0)).toDays();
     52            long totalDays = Duration.between(post.getCreatedAt().atTime(0, 0, 0), post.getDateDue().atTime(0, 0, 0)).toDays();
     53            System.out.println(daysToEnd + " " + totalDays);
     54
     55            if(totalDays < 10)
     56                return true;
     57
     58            return (daysToEnd * 1f/totalDays) * 100 < 75;
     59        }).collect(Collectors.toList());
     60
     61        donationPosts.forEach(post -> {
     62            float dailyAverage = post.getTotalFundsCollected() / (Duration.between(post.getCreatedAt().atTime(0, 0, 0), LocalDate.now().atTime(0, 0, 0)).toDays() + 1);
     63            float neededAverage = (post.getFundsNeeded() - post.getTotalFundsCollected()) / (Duration.between(LocalDate.now().atTime(0, 0, 0), post.getDateDue().atTime(0, 0, 0)).toDays()+1);
     64
     65            System.out.println(dailyAverage + " " + neededAverage);
     66            int risk = (int) (dailyAverage / neededAverage * 100);
     67
     68            if(risk > 100) {
     69                risk = 100;
     70            }
     71
     72            if(Duration.between(LocalDate.now().atTime(0, 0, 0), post.getDateDue().atTime(0, 0, 0)).toDays() == 0) {
     73                risk = 0;
     74            }
     75
     76            if(post.getFundsNeeded() <= post.getTotalFundsCollected()) {
     77                risk = 101;
     78            }
     79
     80            post.setRiskFactor(risk);
     81            donationPostService.save(post);
     82        });
     83    }
     84
     85    @Scheduled(cron = "0 0 * * * *")
     86    public void sendMessages() {
     87        List<EmailMessage> messages = emailMessageService.findAll();
     88        for(EmailMessage message: messages) {
     89            SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
     90            simpleMailMessage.setTo(message.getSendTo());
     91            simpleMailMessage.setSubject(message.getSubject());
     92            simpleMailMessage.setText(message.getText());
     93            emailService.sendMail(simpleMailMessage);
     94            emailMessageService.delete(message);
     95        }
     96    }
    3497}
  • src/main/resources/application.properties

    r881a233 rb8dc761  
    1919
    2020server.port=9091
     21
     22spring.security.oauth2.client.registration.google.client-id=365912873832-mqicpsq1fbbi8e01ghslpulgblkngk3l.apps.googleusercontent.com
     23spring.security.oauth2.client.registration.google.client-secret=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
     24spring.security.oauth2.client.registration.google.scope=profile,email
     25
     26spring.security.oauth2.client.registration.facebook.client-id=429047632308553
     27spring.security.oauth2.client.registration.facebook.client-secret=c13280b6c116663c5bdd85c5b7a986e1
     28spring.security.oauth2.client.registration.facebook.scope=public_profile,email
  • src/main/resources/templates/album.html

    r881a233 rb8dc761  
    11<!DOCTYPE html>
    2 <html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
     2<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
    33<head>
    44    <meta charset="UTF-8"/>
     
    77    <!-- Bootstrap core CSS -->
    88    <link href="css/bootstrap.min.css" rel="stylesheet"/>
     9    <link rel="stylesheet" href="css/risk.css"/>
    910</head>
    1011<body>
     
    2627                        <option value="dateDue">Date due</option>
    2728                        <option value="fundsNeeded">Funds needed</option>
     29                        <option value="riskFactor">Chance to collect funds</option>
    2830                    </select>
    2931                </div>
     
    4749            <div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 g-3">
    4850                <div class="col" th:each="post : ${postList}">
    49                     <div class="card shadow-sm">
     51                    <div class="card shadow-sm" th:classappend="${post.riskFactor < 25 ? 'red' : (post.riskFactor < 50 ? 'orange' : (post.riskFactor < 75 ? 'yellow' : (post.riskFactor < 100 ? 'light-yellow' : (post.riskFactor == 100 ? 'green' : '') )))}">
    5052                        <img class="card-img" style="object-fit: contain" width="100%" height="225"
    5153                             th:src="${post.imagesPath[0]}">
     
    5355                            <h4 th:text="${post.title}" style="height: 60px"></h4>
    5456                            <p class="card-text text-truncate" style="height: 45px" th:text="${post.description}"></p>
     57                            <span th:if="${post.riskFactor < 101}" class="" style="color: black; margin-left: 62%;">Chance: <small th:text="${post.riskFactor}"></small></span>
     58                            <span th:unless="${post.riskFactor < 101}" style="color: black; margin-left: 62%;">Chance: unavailable</span>
    5559                            <div class="d-flex justify-content-between align-items-center">
    5660                                <div class="btn-group">
    57                                     <a class="btn btn-sm btn-outline-secondary" th:href="@{/post(postid=${post.id})}">Open</a>
     61                                    <a class="btn btn-sm btn-outline-secondary" style="color: black" th:href="@{/post(postid=${post.id})}">Open</a>
    5862                                </div>
    59                                 <span class="text-muted">Date due: <small th:text="${post.dateDue}"></small></span>
     63                                <span class="" style="color: black">Date due: <small th:text="${post.dateDue}"></small></span>
    6064                            </div>
    6165                        </div>
  • src/main/resources/templates/login.html

    r881a233 rb8dc761  
    2727        <button class="w-100 btn btn-lg btn-primary" type="submit">Sign in</button>
    2828    </form>
     29    <a th:href="@{/oauth2/authorization/google}" class="btn btn-primary">Continue with google</a>
     30    <a th:href="@{/oauth2/authorization/facebook}" class="btn btn-primary">Continue with facebook</a>
    2931    <p th:if="${param.error != null}" class="text-danger">Incorrect username or password</p>
    3032    <p th:if="${successValidation}" class="text-success">Account validated</p>
  • src/main/resources/templates/post.html

    r881a233 rb8dc761  
    5050            <p th:text="${post.description}"></p>
    5151            <h5>Funds needed:</h5>
    52             <p><span th:text="${total}"></span>/<span th:text="${post.fundsNeeded}"></span> - <span th:text="${post.currency}"></span></p>
     52            <p><span th:text="${post.totalFundsCollected}"></span>/<span th:text="${post.fundsNeeded}"></span> - <span th:text="${post.currency}"></span></p>
    5353            <h5>Date due:</h5>
    5454            <p th:text="${post.dateDue}"></p>
Note: See TracChangeset for help on using the changeset viewer.