Skip to content

Commit

Permalink
updating walkthrough 3 to move queries into the repository to the ser…
Browse files Browse the repository at this point in the history
…vice layer. the controller only deals with HTTP and session data.

Change-Id: Ic73265ddbe2ff8c827ea624d97e1f942b548eb9a
  • Loading branch information
mahima-desetty committed Mar 9, 2024
1 parent ec7a7b5 commit 0005ee2
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,11 @@ public class AuthController {
/** Declare AuthService to be used in the Controller class constructor. */
private final AuthService authService;

/** Declare UserRepository to be used in the Controller class constructor. */
private final UserRepository userRepository;

/** AuthController constructor. Uses constructor injection to instantiate the AuthService and
* UserRepository classes.
/** AuthController constructor. Uses constructor injection to instantiate the AuthService class.
* @param authService the service class that handles the implementation logic of requests.
* @param userRepository the class that interacts with User objects stored in persistent storage.
*/
public AuthController(AuthService authService, UserRepository userRepository) {
public AuthController(AuthService authService) {
this.authService = authService;
this.userRepository = userRepository;
}

/** Returns the index page that will be displayed when the add-on opens in a new tab.
Expand Down Expand Up @@ -109,7 +103,7 @@ else if (login_hint != null) {
* If the credentials in persistent storage are null, we should navigate the user to the
* authorization flow to obtain persisted credentials.
*/
User storedUser = getUser(login_hint);
User storedUser = authService.getUser(login_hint);
if (storedUser != null) {
Credential credential = authService.loadFromCredentialDataStore(login_hint);
if (credential != null) {
Expand Down Expand Up @@ -173,9 +167,8 @@ public String callback(HttpServletRequest request, HttpServletResponse response,

/** This is the end of the auth flow. We should save user info to the database. */
Userinfo userinfo = authService.getUserInfo(credentials);
saveUser(credentials, userinfo, session);

return "close-pop-up";
authService.saveUser(credentials, userinfo, session.getAttribute("login_hint"));
return "close-pop-up-addon-discovery";
} catch (Exception e) {
return onError(e.getMessage(), model);
}
Expand All @@ -200,7 +193,7 @@ public String test(HttpSession session, Model model) {
}

/** Save credentials in case access token was refreshed. */
saveUser(credentials, null, session);
authService.saveUser(credentials, null, session.getAttribute("login_hint"));
return "test";
} catch (Exception e) {
return onError(e.getMessage(), model);
Expand Down Expand Up @@ -235,8 +228,9 @@ public String clear(HttpSession session, Model model) {
public String revoke(HttpSession session, Model model) {
try {
if (session != null && session.getAttribute("credentials") != null) {
String login_hint = session.getAttribute("login_hint").toString();
Credential credentials = (Credential) session.getAttribute("credentials");
ResponseEntity responseEntity = authService.revokeCredentials(credentials);
ResponseEntity responseEntity = authService.revokeCredentials(credentials, login_hint);
Integer httpStatusCode = responseEntity.getStatusCodeValue();

if (httpStatusCode != 200) {
Expand All @@ -261,47 +255,4 @@ public String onError(String errorMessage, Model model) {
model.addAttribute("error", errorMessage);
return "error";
}

/** Retrieves stored credentials based on the user id.
* @param id the id of the current user
* @return User the database entry corresponding to the current user, or null if the user does
* not exist in the database.
*/
public User getUser(String id) {
if (id != null) {
Optional<User> user = userRepository.findById(id);
if (user.isPresent()) {
return user.get();
}
}
return null;
}

/** Adds or updates a user in the database.
* @param credential the credentials object to save or update in the database.
* @param userinfo the userinfo object to save or update in the database.
* @param session the current session.
*/
public void saveUser(Credential credential, Userinfo userinfo, HttpSession session) {
User storedUser = null;
if (session != null && session.getAttribute("login_hint") != null) {
storedUser = getUser(session.getAttribute("login_hint").toString());
}

if (storedUser != null) {
if (userinfo != null) {
storedUser.setId(userinfo.getId());
storedUser.setEmail(userinfo.getEmail());
}

userRepository.save(storedUser);
} else if (credential != null && userinfo != null) {
User newUser = new User(
userinfo.getId(),
userinfo.getEmail()
);
userRepository.save(newUser);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Optional;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
Expand All @@ -65,6 +66,18 @@ public class AuthService {
"https://www.googleapis.com/auth/classroom.addons.student"
};

/** Declare UserRepository to be used in the class constructor. */
private final UserRepository userRepository;

/** AuthService constructor. Uses constructor injection to instantiate the
* UserRepository class.
* @param userRepository the class that interacts with User objects stored in
* persistent storage.
*/
public AuthService(UserRepository userRepository) {
this.userRepository = userRepository;
}

/** Creates and returns a Collection object with all requested scopes.
* @return Collection of scopes requested by the application.
*/
Expand Down Expand Up @@ -235,7 +248,8 @@ public Userinfo getUserInfo(Credential credentials) throws Exception {
* @return response entity returned from the HTTP call to obtain response information.
* @throws RestClientException if the POST request to the revoke endpoint is unsuccessful.
*/
public ResponseEntity<String> revokeCredentials(Credential credentials) throws RestClientException {
public ResponseEntity<String> revokeCredentials(Credential credentials, String login_hint)
throws Exception {
try {
String accessToken = credentials.getAccessToken();
String url = "https://oauth2.googleapis.com/revoke?token=" + accessToken;
Expand All @@ -246,11 +260,53 @@ public ResponseEntity<String> revokeCredentials(Credential credentials) throws R
ResponseEntity<String> responseEntity = new RestTemplate().exchange(url, HttpMethod.POST,
httpEntity, String.class);

GoogleAuthorizationCodeFlow flow = getFlow();
flow.getCredentialDataStore().delete(login_hint);
return responseEntity;
} catch (RestClientException e) {
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}

/** Retrieves the User from the UserRepository.
* @param id the id of the current user
* @return User the database entry corresponding to the current user, or null if the user does
* not exist in the database.
*/
public User getUser(String id) {
if (id != null) {
Optional<User> user = userRepository.findById(id);
if (user.isPresent()) {
return user.get();
}
}
return null;
}

/** Adds or updates a user in the database.
* @param credential the credentials object to save or update in the database.
* @param userinfo the userinfo object to save or update in the database.
* @param login_hint the login_hint from the session.
*/
public void saveUser(Credential credential, Userinfo userinfo, Object login_hint) {
User storedUser = null;
if (login_hint != null) {
storedUser = getUser(login_hint.toString());
}

if (storedUser != null) {
if (userinfo != null) {
storedUser.setId(userinfo.getId());
storedUser.setEmail(userinfo.getEmail());
}
userRepository.save(storedUser);
} else if (credential != null && userinfo != null) {
User newUser = new User(
userinfo.getId(),
userinfo.getEmail()
);
userRepository.save(newUser);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ <h2>Authorization Required</h2>
<hr>
<!--
Developer note: if you have *never* seen the user before, they'll need to
authorize your app. It's most reliable to do so in a popup due to add-ons
being presented in an iframe.
authorize your app. This should be done in a popup due to add-ons being
presented in an iframe.
-->
<a target="popup" onclick="createPopup(this.href);return false" href="/authorize">
<img src="../images/btn_google_signin_dark_normal_web.png" alt="Authorize the user">
Expand Down

0 comments on commit 0005ee2

Please sign in to comment.