Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
stavshamir committed Aug 7, 2018
1 parent 195396e commit e5e882c
Show file tree
Hide file tree
Showing 11 changed files with 301 additions and 0 deletions.
42 changes: 42 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.2.RELEASE")
}
}

group 'listening-history'
version '1.0-SNAPSHOT'

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

bootJar {
baseName = 'gs-spring-boot'
version = '0.1.0'
}

repositories {
mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
compile 'org.springframework.boot:spring-boot-starter-web'
compile 'org.springframework.boot:spring-boot-starter-data-jpa'

compile group: 'org.postgresql', name: 'postgresql'

compile 'se.michaelthelin.spotify:spotify-web-api-java:2.0.2'

testCompile 'org.springframework.boot:spring-boot-starter-test'
testCompile 'com.h2database:h2'
testCompile 'junit:junit'
}
2 changes: 2 additions & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
rootProject.name = 'spotify-listening-history'

14 changes: 14 additions & 0 deletions src/main/java/com/stavshamir/app/AppController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.stavshamir.app;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class AppController {

@RequestMapping("/health")
public String health() {
return "healthy";
}

}
16 changes: 16 additions & 0 deletions src/main/java/com/stavshamir/app/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.stavshamir.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

}

46 changes: 46 additions & 0 deletions src/main/java/com/stavshamir/app/authorization/AuthTokens.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.stavshamir.app.authorization;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class AuthTokens {

@Id
private String userId;

private String accessToken;
private String refreshToken;

public AuthTokens() {}

public AuthTokens(String userId, String accessToken, String refreshToken) {
this.userId = userId;
this.accessToken = accessToken;
this.refreshToken = refreshToken;
}

public String getUserId() {
return userId;
}

public void setUserId(String userId) {
this.userId = userId;
}

public String getAccessToken() {
return accessToken;
}

public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}

public String getRefreshToken() {
return refreshToken;
}

public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.stavshamir.app.authorization;

import com.wrapper.spotify.exceptions.SpotifyWebApiException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.view.RedirectView;

import java.io.IOException;

@RestController
public class AuthTokensController {

private final AuthTokensService authTokensService;

@Autowired
public AuthTokensController(AuthTokensService authTokensService) {
this.authTokensService = authTokensService;
}

@RequestMapping("/authorize")
public RedirectView authorize() {
String url = authTokensService
.getAuthorizationCodeUriRequest("user-read-recently-played")
.execute()
.toString();

RedirectView redirectView = new RedirectView();
redirectView.setUrl(url);
return redirectView;
}

@RequestMapping("/callback")
public String callback(@RequestParam("code") String code) {
try {
authTokensService.retrieveAndPersistTokens(code);
} catch (IOException | SpotifyWebApiException e) {
return "Failed to retrieve authorization credentials from Spotify API: " + e.getMessage();
}

return "Authorization credentials stored successfully";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.stavshamir.app.authorization;

import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface AuthTokensRepository extends JpaRepository<AuthTokens, String> {
Optional<AuthTokens> findByUserId(String userId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.stavshamir.app.authorization;

import com.wrapper.spotify.exceptions.SpotifyWebApiException;
import com.wrapper.spotify.requests.authorization.authorization_code.AuthorizationCodeUriRequest;

import java.io.IOException;

public interface AuthTokensService {

AuthorizationCodeUriRequest getAuthorizationCodeUriRequest(String scope);
void retrieveAndPersistTokens(String code) throws IOException, SpotifyWebApiException;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.stavshamir.app.authorization;

import com.stavshamir.app.spotify.SpotifyClient;
import com.wrapper.spotify.exceptions.SpotifyWebApiException;
import com.wrapper.spotify.model_objects.credentials.AuthorizationCodeCredentials;
import com.wrapper.spotify.requests.authorization.authorization_code.AuthorizationCodeRequest;
import com.wrapper.spotify.requests.authorization.authorization_code.AuthorizationCodeUriRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;

@Service
public class AuthTokensServiceImpl implements AuthTokensService {

private Logger logger = LoggerFactory.getLogger(AuthTokensServiceImpl.class);

private final SpotifyClient spotifyClient;
private final AuthTokensRepository authTokensRepository;

@Autowired
public AuthTokensServiceImpl(SpotifyClient spotifyClient, AuthTokensRepository authTokensRepository) {
this.spotifyClient = spotifyClient;
this.authTokensRepository = authTokensRepository;
}

@Override
public AuthorizationCodeUriRequest getAuthorizationCodeUriRequest(String scope) {
return spotifyClient
.getSpotifyApi()
.authorizationCodeUri()
.scope(scope)
.build();
}

@Override
public void retrieveAndPersistTokens(String code) throws IOException, SpotifyWebApiException {
AuthorizationCodeCredentials credentials = getAuthorizationCodeRequest(code).execute();

String userId = spotifyClient.getSpotifyApiWithAccessToken(credentials.getAccessToken())
.getCurrentUsersProfile()
.build()
.execute()
.getUri();

persistTokens(userId, credentials);
}

private AuthorizationCodeRequest getAuthorizationCodeRequest(String code) {
return spotifyClient
.getSpotifyApi()
.authorizationCode(code)
.build();
}

private void persistTokens(String userId, AuthorizationCodeCredentials credentials) {
String accessToken = credentials.getAccessToken();
String refreshToken = credentials.getRefreshToken();

insertOrUpdateIfExists(userId, accessToken, refreshToken);
}

private void insertOrUpdateIfExists(String userId, String accessToken, String refreshToken) {
AuthTokens auth = authTokensRepository
.findByUserId(userId)
.orElse(new AuthTokens(userId, accessToken, refreshToken));

authTokensRepository.save(auth);
}

}
30 changes: 30 additions & 0 deletions src/main/java/com/stavshamir/app/spotify/SpotifyClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.stavshamir.app.spotify;

import com.wrapper.spotify.SpotifyApi;
import com.wrapper.spotify.SpotifyHttpManager;
import org.springframework.stereotype.Component;

import java.net.URI;

@Component
public class SpotifyClient {
private final String CLIENT_ID = "94002a67e5704e2294bd4a5874cddec6";
private final String CLIENT_SECRET = "f57133b0d830479ca8e17e4c9b5bf76d";
private final URI REDIRECT_URI = SpotifyHttpManager.makeUri("http://localhost:5000/callback");
// private final URI REDIRECT_URI = SpotifyHttpManager.makeUri("https://guarded-bayou-27287.herokuapp.com/callback");

private final SpotifyApi spotifyApi = new SpotifyApi.Builder()
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET)
.setRedirectUri(REDIRECT_URI)
.build();

public SpotifyApi getSpotifyApi() {
return spotifyApi;
}

public SpotifyApi getSpotifyApiWithAccessToken(String accessToken) {
spotifyApi.setAccessToken(accessToken);
return spotifyApi;
}
}
11 changes: 11 additions & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
server.port = 5000

spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.platform=postgres

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQL94Dialect
spring.jpa.hibernate.ddl-auto=update

spring.datasource.url=jdbc:postgresql://localhost:5432/spotify
spring.datasource.username=stav
spring.datasource.password=root

0 comments on commit e5e882c

Please sign in to comment.