// Path: src/main/java/com/lixiaocong/cms/entity/User.java
// @Entity(name = "User")
// public class User extends AbstractEntity {
//     @Column(nullable = false, unique = true)
//     private String username;
// 
//     @JsonIgnore
//     @Column(nullable = false)
//     private String password;
// 
//     @Column(nullable = false)
//     private boolean admin;
// 
//     @JsonIgnore
//     @OneToMany(mappedBy = "user", cascade = {CascadeType.REMOVE})
//     private Set<Article> articles;
// 
//     @JsonIgnore
//     @OneToMany(mappedBy = "user", cascade = {CascadeType.REMOVE})
//     private Set<Comment> comments;
// 
//     public User() {
//         admin = false;
//         articles = new HashSet<>();
//         comments = new HashSet<>();
//     }
// 
//     public User(String username, String password) {
//         admin = false;
//         articles = new HashSet<>();
//         comments = new HashSet<>();
// 
//         this.username = username;
//         this.password = password;
//     }
// 
//     public Set<Comment> getComments() {
//         return comments;
//     }
// 
//     public void setComments(Set<Comment> comments) {
//         this.comments = comments;
//     }
// 
//     public Set<Article> getArticles() {
//         return articles;
//     }
// 
//     public void setArticles(Set<Article> articles) {
//         this.articles = articles;
//     }
// 
//     public String getUsername() {
//         return username;
//     }
// 
//     public void setUsername(String username) {
//         this.username = username;
//     }
// 
//     public String getPassword() {
//         return password;
//     }
// 
//     public void setPassword(String password) {
//         this.password = password;
//     }
// 
//     public boolean isAdmin() {
//         return admin;
//     }
// 
//     public void setAdmin(boolean admin) {
//         this.admin = admin;
//     }
// }
// 
// Path: src/main/java/com/lixiaocong/cms/exception/ControllerParamException.java
// public class ControllerParamException extends Exception {
// }
// 
// Path: src/main/java/com/lixiaocong/cms/service/IUserService.java
// public interface IUserService {
//     User create(String username, String password);
// 
//     void delete(long id);
// 
//     void update(User user);
// 
//     User get(long id);
// 
//     Page<User> get(int page, int size);
// 
//     User getByUsername(String username);
// }


import com.lixiaocong.cms.entity.User;
import com.lixiaocong.cms.exception.ControllerParamException;
import com.lixiaocong.cms.model.UserSignUpForm;
import com.lixiaocong.cms.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.social.connect.Connection;
import org.springframework.social.connect.ConnectionFactoryLocator;
import org.springframework.social.connect.UsersConnectionRepository;
import org.springframework.social.connect.web.ProviderSignInUtils;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.ModelAndView;
import javax.validation.Valid;
    public SignController(ConnectionFactoryLocator connectionFactoryLocator, UsersConnectionRepository connectionRepository, IUserService userService, UserDetailsService userDetailsService) {
        this.providerSignInUtils = new ProviderSignInUtils(connectionFactoryLocator, connectionRepository);
        this.userService = userService;
        this.encoder = new BCryptPasswordEncoder();
        this.userDetailsService = userDetailsService;
    }

    @RequestMapping(value = "signin", method = RequestMethod.GET)
    public String signin() {
        return "sign/signin";
    }

    @RequestMapping(value = "/signup", method = RequestMethod.GET)
    public ModelAndView signup(WebRequest request) {
        ModelAndView ret = new ModelAndView("sign/signup");
        Connection<?> connection = providerSignInUtils.getConnectionFromSession(request);

        if (connection != null) {
            String name = connection.fetchUserProfile().getName();
            ret.addObject("username", name);
            ret.addObject("message", "please set your password");
        }
        return ret;
    }

    @RequestMapping(value = "/singup", method = RequestMethod.POST)
    public ModelAndView post(@Valid UserSignUpForm user, BindingResult result, WebRequest request) throws ControllerParamException {
        if (result.hasErrors()) throw new ControllerParamException();

        try {
// Path: src/main/java/com/lixiaocong/cms/entity/User.java
// @Entity(name = "User")
// public class User extends AbstractEntity {
//     @Column(nullable = false, unique = true)
//     private String username;
// 
//     @JsonIgnore
//     @Column(nullable = false)
//     private String password;
// 
//     @Column(nullable = false)
//     private boolean admin;
// 
//     @JsonIgnore
//     @OneToMany(mappedBy = "user", cascade = {CascadeType.REMOVE})
//     private Set<Article> articles;
// 
//     @JsonIgnore
//     @OneToMany(mappedBy = "user", cascade = {CascadeType.REMOVE})
//     private Set<Comment> comments;
// 
//     public User() {
//         admin = false;
//         articles = new HashSet<>();
//         comments = new HashSet<>();
//     }
// 
//     public User(String username, String password) {
//         admin = false;
//         articles = new HashSet<>();
//         comments = new HashSet<>();
// 
//         this.username = username;
//         this.password = password;
//     }
// 
//     public Set<Comment> getComments() {
//         return comments;
//     }
// 
//     public void setComments(Set<Comment> comments) {
//         this.comments = comments;
//     }
// 
//     public Set<Article> getArticles() {
//         return articles;
//     }
// 
//     public void setArticles(Set<Article> articles) {
//         this.articles = articles;
//     }
// 
//     public String getUsername() {
//         return username;
//     }
// 
//     public void setUsername(String username) {
//         this.username = username;
//     }
// 
//     public String getPassword() {
//         return password;
//     }
// 
//     public void setPassword(String password) {
//         this.password = password;
//     }
// 
//     public boolean isAdmin() {
//         return admin;
//     }
// 
//     public void setAdmin(boolean admin) {
//         this.admin = admin;
//     }
// }
// 
// Path: src/main/java/com/lixiaocong/cms/exception/ControllerParamException.java
// public class ControllerParamException extends Exception {
// }
// 
// Path: src/main/java/com/lixiaocong/cms/service/IUserService.java
// public interface IUserService {
//     User create(String username, String password);
// 
//     void delete(long id);
// 
//     void update(User user);
// 
//     User get(long id);
// 
//     Page<User> get(int page, int size);
// 
//     User getByUsername(String username);
// }


// Path: src/main/java/com/lixiaocong/cms/controller/SignController.java
import com.lixiaocong.cms.entity.User;
import com.lixiaocong.cms.exception.ControllerParamException;
import com.lixiaocong.cms.model.UserSignUpForm;
import com.lixiaocong.cms.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.social.connect.Connection;
import org.springframework.social.connect.ConnectionFactoryLocator;
import org.springframework.social.connect.UsersConnectionRepository;
import org.springframework.social.connect.web.ProviderSignInUtils;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.ModelAndView;
import javax.validation.Valid;

    public SignController(ConnectionFactoryLocator connectionFactoryLocator, UsersConnectionRepository connectionRepository, IUserService userService, UserDetailsService userDetailsService) {
        this.providerSignInUtils = new ProviderSignInUtils(connectionFactoryLocator, connectionRepository);
        this.userService = userService;
        this.encoder = new BCryptPasswordEncoder();
        this.userDetailsService = userDetailsService;
    }

    @RequestMapping(value = "signin", method = RequestMethod.GET)
    public String signin() {
        return "sign/signin";
    }

    @RequestMapping(value = "/signup", method = RequestMethod.GET)
    public ModelAndView signup(WebRequest request) {
        ModelAndView ret = new ModelAndView("sign/signup");
        Connection<?> connection = providerSignInUtils.getConnectionFromSession(request);

        if (connection != null) {
            String name = connection.fetchUserProfile().getName();
            ret.addObject("username", name);
            ret.addObject("message", "please set your password");
        }
        return ret;
    }

    @RequestMapping(value = "/singup", method = RequestMethod.POST)
    public ModelAndView post(@Valid UserSignUpForm user, BindingResult result, WebRequest request) throws ControllerParamException {
        if (result.hasErrors()) throw new ControllerParamException();

        try {
            User localUser = userService.create(user.getUsername(), encoder.encode(user.getPassword()));