// Path: opentipbot-persistence/src/main/java/opentipbot/persistence/model/OpenTipBotUser.java
// @Entity
// @Table(name = "opentipbot_user")
// /**
//  * @author Gilles Cadignan
//  */
// public class OpenTipBotUser extends BaseEntity<Long>{
// 
//     @Id
//     @GeneratedValue
//     private Long id;
// 
//     private String email;
//     private String displayName;
//     private String userName;
//     private String twitterIdentifier;
//     private String coinAddress;
//     private String profileImageUrl;
//     private String profileUrl;
// 
//     @Basic(fetch = FetchType.LAZY)
//     private byte[] coinAddressQRCode;
// 
//     @Transient
//     private double balance;
// 
//     @Transient
//     private double pendingBalance;
// 
//     public String getUserName() {
//         return userName;
//     }
// 
//     public void setUserName(String userName) {
//         this.userName = userName;
//     }
// 
//     public String getCoinAddress() {
//         return coinAddress;
//     }
// 
//     public void setCoinAddress(String coinAddress) {
//         this.coinAddress = coinAddress;
//     }
// 
//     public Long getId() {
//         return id;
//     }
// 
//     public void setId(Long id) {
//         this.id = id;
//     }
// 
//     public String getEmail() {
//         return email;
//     }
// 
//     public void setEmail(String email) {
//         this.email = email;
//     }
// 
//     public String getDisplayName() {
//         return displayName;
//     }
// 
//     public void setDisplayName(String displayName) {
//         this.displayName = displayName;
//     }
// 
//     public String getTwitterIdentifier() {
//         return twitterIdentifier;
//     }
// 
//     public void setTwitterIdentifier(String twitterIdentifier) {
//         this.twitterIdentifier = twitterIdentifier;
//     }
// 
//     public double getBalance() {
//         return balance;
//     }
// 
//     public void setBalance(double balance) {
//         this.balance = balance;
//     }
// 
//     public String getProfileImageUrl() {
//         return profileImageUrl;
//     }
// 
//     public void setProfileImageUrl(String profileImageUrl) {
//         this.profileImageUrl = profileImageUrl;
//     }
// 
//     public byte[] getCoinAddressQRCode() {
//         return coinAddressQRCode;
//     }
// 
//     public void setCoinAddressQRCode(byte[] coinAddressQRCode) {
//         this.coinAddressQRCode = coinAddressQRCode;
//     }
// 
//     public String getProfileUrl() {
//         return profileUrl;
//     }
// 
//     public void setProfileUrl(String profileUrl) {
//         this.profileUrl = profileUrl;
//     }
// 
//     public double getPendingBalance() {
//         return pendingBalance;
//     }
// 
//     public void setPendingBalance(double pendingBalance) {
//         this.pendingBalance = pendingBalance;
//     }
// }
// 
// Path: opentipbot-persistence/src/main/java/opentipbot/persistence/repository/OpenTipBotUserRepository.java
// public interface OpenTipBotUserRepository extends JpaRepository<OpenTipBotUser, Long> {
//     OpenTipBotUser findByTwitterIdentifier(String twitterIdentifier);
//     OpenTipBotUser findByUserName(String UserName);
// }


import org.springframework.social.connect.UsersConnectionRepository;
import org.springframework.social.twitter.api.Twitter;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.view.RedirectView;
import opentipbot.persistence.model.OpenTipBotUser;
import opentipbot.persistence.repository.OpenTipBotUserRepository;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
 * Copyright 2014 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package opentipbot.web.security;



/**
 * Before a request is handled:
 * 1. sets the current User in the {@link SecurityContext} from a cookie, if present and the user is still connected to Facebook.
 * 2. requires that the user sign-in if he or she hasn't already.
 * @author Gilles Cadignan
 */
public final class UserInterceptor extends HandlerInterceptorAdapter {

	private final UsersConnectionRepository connectionRepository;

    private final OpenTipBotUserRepository opentipbotUserRepository;
	
	private final UserCookieGenerator userCookieGenerator = new UserCookieGenerator();

	public UserInterceptor(UsersConnectionRepository connectionRepository, OpenTipBotUserRepository opentipbotUserRepository) {
		this.connectionRepository = connectionRepository;
        this.opentipbotUserRepository = opentipbotUserRepository;
	}
	
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		rememberUser(request, response);
		handleSignOut(request, response);			
		if (SecurityContext.userSignedIn() || requestForNotProtected(request)) {
			return true;
		} else {
			return requireSignIn(request, response);
		}
	}
	
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
		SecurityContext.remove();
	}

	// internal helpers

	private void rememberUser(HttpServletRequest request, HttpServletResponse response) {
		String userId = userCookieGenerator.readCookieValue(request);
		if (userId == null) {
			return;
		}
		if (!userNotFound(userId)) {
			userCookieGenerator.removeCookie(response);
			return;
		}
// Path: opentipbot-persistence/src/main/java/opentipbot/persistence/model/OpenTipBotUser.java
// @Entity
// @Table(name = "opentipbot_user")
// /**
//  * @author Gilles Cadignan
//  */
// public class OpenTipBotUser extends BaseEntity<Long>{
// 
//     @Id
//     @GeneratedValue
//     private Long id;
// 
//     private String email;
//     private String displayName;
//     private String userName;
//     private String twitterIdentifier;
//     private String coinAddress;
//     private String profileImageUrl;
//     private String profileUrl;
// 
//     @Basic(fetch = FetchType.LAZY)
//     private byte[] coinAddressQRCode;
// 
//     @Transient
//     private double balance;
// 
//     @Transient
//     private double pendingBalance;
// 
//     public String getUserName() {
//         return userName;
//     }
// 
//     public void setUserName(String userName) {
//         this.userName = userName;
//     }
// 
//     public String getCoinAddress() {
//         return coinAddress;
//     }
// 
//     public void setCoinAddress(String coinAddress) {
//         this.coinAddress = coinAddress;
//     }
// 
//     public Long getId() {
//         return id;
//     }
// 
//     public void setId(Long id) {
//         this.id = id;
//     }
// 
//     public String getEmail() {
//         return email;
//     }
// 
//     public void setEmail(String email) {
//         this.email = email;
//     }
// 
//     public String getDisplayName() {
//         return displayName;
//     }
// 
//     public void setDisplayName(String displayName) {
//         this.displayName = displayName;
//     }
// 
//     public String getTwitterIdentifier() {
//         return twitterIdentifier;
//     }
// 
//     public void setTwitterIdentifier(String twitterIdentifier) {
//         this.twitterIdentifier = twitterIdentifier;
//     }
// 
//     public double getBalance() {
//         return balance;
//     }
// 
//     public void setBalance(double balance) {
//         this.balance = balance;
//     }
// 
//     public String getProfileImageUrl() {
//         return profileImageUrl;
//     }
// 
//     public void setProfileImageUrl(String profileImageUrl) {
//         this.profileImageUrl = profileImageUrl;
//     }
// 
//     public byte[] getCoinAddressQRCode() {
//         return coinAddressQRCode;
//     }
// 
//     public void setCoinAddressQRCode(byte[] coinAddressQRCode) {
//         this.coinAddressQRCode = coinAddressQRCode;
//     }
// 
//     public String getProfileUrl() {
//         return profileUrl;
//     }
// 
//     public void setProfileUrl(String profileUrl) {
//         this.profileUrl = profileUrl;
//     }
// 
//     public double getPendingBalance() {
//         return pendingBalance;
//     }
// 
//     public void setPendingBalance(double pendingBalance) {
//         this.pendingBalance = pendingBalance;
//     }
// }
// 
// Path: opentipbot-persistence/src/main/java/opentipbot/persistence/repository/OpenTipBotUserRepository.java
// public interface OpenTipBotUserRepository extends JpaRepository<OpenTipBotUser, Long> {
//     OpenTipBotUser findByTwitterIdentifier(String twitterIdentifier);
//     OpenTipBotUser findByUserName(String UserName);
// }


// Path: opentipbot-webapp/src/main/java/opentipbot/web/security/UserInterceptor.java
import org.springframework.social.connect.UsersConnectionRepository;
import org.springframework.social.twitter.api.Twitter;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.view.RedirectView;
import opentipbot.persistence.model.OpenTipBotUser;
import opentipbot.persistence.repository.OpenTipBotUserRepository;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/*
 * Copyright 2014 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package opentipbot.web.security;



/**
 * Before a request is handled:
 * 1. sets the current User in the {@link SecurityContext} from a cookie, if present and the user is still connected to Facebook.
 * 2. requires that the user sign-in if he or she hasn't already.
 * @author Gilles Cadignan
 */
public final class UserInterceptor extends HandlerInterceptorAdapter {

	private final UsersConnectionRepository connectionRepository;

    private final OpenTipBotUserRepository opentipbotUserRepository;
	
	private final UserCookieGenerator userCookieGenerator = new UserCookieGenerator();

	public UserInterceptor(UsersConnectionRepository connectionRepository, OpenTipBotUserRepository opentipbotUserRepository) {
		this.connectionRepository = connectionRepository;
        this.opentipbotUserRepository = opentipbotUserRepository;
	}
	
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		rememberUser(request, response);
		handleSignOut(request, response);			
		if (SecurityContext.userSignedIn() || requestForNotProtected(request)) {
			return true;
		} else {
			return requireSignIn(request, response);
		}
	}
	
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
		SecurityContext.remove();
	}

	// internal helpers

	private void rememberUser(HttpServletRequest request, HttpServletResponse response) {
		String userId = userCookieGenerator.readCookieValue(request);
		if (userId == null) {
			return;
		}
		if (!userNotFound(userId)) {
			userCookieGenerator.removeCookie(response);
			return;
		}
        OpenTipBotUser opentipbotUser= opentipbotUserRepository.findOne(Long.parseLong(userId));