OrganizationLinkerService.java
package edu.ucsb.cs156.frontiers.services;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import edu.ucsb.cs156.frontiers.entities.Course;
import edu.ucsb.cs156.frontiers.errors.InvalidInstallationTypeException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
@Service
public class OrganizationLinkerService {
private RestTemplate restTemplate;
@Autowired JwtService jwtService;
@Autowired ObjectMapper objectMapper;
public OrganizationLinkerService(RestTemplateBuilder restTemplateBuilder) {
restTemplate = restTemplateBuilder.build();
}
/**
* Returns the URL for a redirect to install Frontiers
*
* @return URL to install Frontiers to an organization
*/
public String getRedirectUrl()
throws NoSuchAlgorithmException, InvalidKeySpecException, JsonProcessingException {
String token = jwtService.getJwt();
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.add("Authorization", "Bearer " + token);
requestHeaders.add("Accept", "application/vnd.github+json");
requestHeaders.add("X-GitHub-Api-Version", "2022-11-28");
String ENDPOINT = "https://api.github.com/app";
HttpEntity<String> newEntity = new HttpEntity<>(requestHeaders);
ResponseEntity<String> response =
restTemplate.exchange(ENDPOINT, HttpMethod.GET, newEntity, String.class);
JsonNode responseJson = objectMapper.readTree(response.getBody());
String newUrl = responseJson.get("html_url").toString().replaceAll("\"", "");
return newUrl;
}
/**
* Provides the name of the organization attached to a particular installation ID
*
* @param installation_id ID of the app installation
* @return name of the organization attached to the installation
*/
public String getOrgName(String installation_id)
throws NoSuchAlgorithmException, InvalidKeySpecException, JsonProcessingException {
String token = jwtService.getJwt();
String ENDPOINT = "https://api.github.com/app/installations/" + installation_id;
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Bearer " + token);
headers.add("Accept", "application/vnd.github+json");
headers.add("X-GitHub-Api-Version", "2022-11-28");
HttpEntity<String> entity = new HttpEntity<>(headers);
ResponseEntity<String> response =
restTemplate.exchange(ENDPOINT, HttpMethod.GET, entity, String.class);
JsonNode responseJson = objectMapper.readTree(response.getBody());
String type = responseJson.get("account").get("type").asText();
if (!type.equals("Organization")) {
throw new InvalidInstallationTypeException(type);
}
String orgName = responseJson.get("account").get("login").asText();
return orgName;
}
/**
* Removes the Frontiers installation from the linked GitHub org
*
* @param course The entity for the course about to be deleted
*/
public void unenrollOrganization(Course course)
throws NoSuchAlgorithmException, InvalidKeySpecException {
if (course.getOrgName() == null || course.getInstallationId() == null) {
return;
}
String token = jwtService.getJwt();
String ENDPOINT = "https://api.github.com/app/installations/" + course.getInstallationId();
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Bearer " + token);
headers.add("Accept", "application/vnd.github+json");
headers.add("X-GitHub-Api-Version", "2022-11-28");
HttpEntity<String> entity = new HttpEntity<>(headers);
try {
ResponseEntity<String> response =
restTemplate.exchange(ENDPOINT, HttpMethod.DELETE, entity, String.class);
} catch (HttpClientErrorException ignored) {
}
}
}