Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
91b6b70
VSPC-189 added citeshpere connection
ajay3568yadav Jul 16, 2025
b33d13c
VSPC-189 manager class fix
ajay3568yadav Jul 18, 2025
8c6002b
VSPC-189 added mapping
ajay3568yadav Jul 18, 2025
79b105b
VSPC-189 moved citesphere option to references
ajay3568yadav Jul 23, 2025
4c3b30e
VSPC-189 edit slide
ajay3568yadav Aug 1, 2025
2d855d3
VSPC-189 editing the reference blocks
ajay3568yadav Aug 4, 2025
5e63907
VSPC-189 filed selection fix
ajay3568yadav Aug 8, 2025
179306f
VSPC-189 citesphere manager
ajay3568yadav Aug 11, 2025
07c444e
VSPC-189 citation manager fixes
ajay3568yadav Aug 12, 2025
5e26a16
[VSPC-189] created citesphere controller to handle calls to citesphere
Girik1105 Sep 8, 2025
e8fca0a
[VSPC-189] Added auoth flow to connect with citesphere
Girik1105 Sep 10, 2025
6194bba
[VSPC-189] Added debug print, fixed endpoints, added implmentation in…
Girik1105 Sep 11, 2025
6478a4a
[VSPC-189] Fixed oauth flow and citesphere controller
Girik1105 Sep 12, 2025
fe55e98
[VSPC-189] shows connection status to frontend
Girik1105 Sep 12, 2025
fb8a44b
[VSPC-189] Groups now show after connecting to citesphere - need to f…
Girik1105 Sep 12, 2025
2e2989d
[VSPC-189] Groups to collections to item workflow for references impo…
Girik1105 Sep 15, 2025
e79aeb5
[VSPC-189] Successfully implemented reference import from citesphere …
Girik1105 Sep 15, 2025
c0ce36c
[VSPC-189] Removed debug comments, debug logs, cleaneed code
Girik1105 Sep 18, 2025
1a645b5
[VSPC-189] Citesphere config update
Girik1105 Sep 18, 2025
ff11d73
[VSPC-189] revert config properties to orignal
Girik1105 Sep 18, 2025
cdcc35d
[VSPC-189] code cleanup
Girik1105 Sep 18, 2025
c5575fe
[VSPC-189] added comments that were removed unintentionally
Girik1105 Sep 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions vspace/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
<email.from></email.from>
<app.url></app.url>

<citesphere.api.url></citesphere.api.url>
<citesphere.client.id></citesphere.client.id>
<citesphere.client.secret></citesphere.client.secret>

<tomcat.deploy.path></tomcat.deploy.path>
<tomcat.app.name>vspace</tomcat.app.name>
<tomcat.server.id>TomcatServer</tomcat.server.id>
Expand Down Expand Up @@ -219,6 +223,13 @@
<version>0.15.0</version>
</dependency>

<!-- OkHttp for Citesphere API calls -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.3</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf-spring5 -->
<dependency>
<groupId>org.thymeleaf</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ protected void configure(HttpSecurity http) throws Exception {
.authorizeRequests()
// Anyone can access the urls
.antMatchers("/", "/exhibit/**", "/api/**", "/resources/**", "/login",
"/logout", "/register", "/reset/**", "/setup/admin", "/404","/preview/**").permitAll()
"/logout", "/register", "/reset/**", "/setup/admin", "/404","/preview/**",
"/staff/citesphere/oauth/**").permitAll()
// The rest of the our application is protected.
.antMatchers("/users/**", "/admin/**", "/staff/user/**").hasRole("ADMIN")
.antMatchers("/staff/**").hasAnyRole("STAFF", "ADMIN")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package edu.asu.diging.vspace.core.exception;

/**
* Exception thrown when there are issues with Citesphere authentication tokens
*/
public class CitesphereTokenException extends Exception {

private static final long serialVersionUID = 1L;
private final int statusCode;
private final boolean isTokenExpired;

public CitesphereTokenException(String message) {
super(message);
this.statusCode = 0;
this.isTokenExpired = false;
}

public CitesphereTokenException(String message, int statusCode) {
super(message);
this.statusCode = statusCode;
this.isTokenExpired = (statusCode == 401 || statusCode == 403);
}

public CitesphereTokenException(String message, Throwable cause) {
super(message, cause);
this.statusCode = 0;
this.isTokenExpired = false;
}

public CitesphereTokenException(String message, int statusCode, boolean isTokenExpired) {
super(message);
this.statusCode = statusCode;
this.isTokenExpired = isTokenExpired;
}

public int getStatusCode() {
return statusCode;
}

public boolean isTokenExpired() {
return isTokenExpired;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package edu.asu.diging.vspace.core.services;

import java.util.Map;

/**
* Authentication token object for Citesphere API
*/
public class CitesphereAuthToken {

private String authType;
private Map<String, String> headers;
private String accessToken;
private String refreshToken;
private String username;
private String password;
private long tokenExpiryTime;

/**
* Constructor for OAuth authentication
* @param accessToken OAuth access token
*/
public CitesphereAuthToken(String accessToken) {
this.authType = "oauth";
this.accessToken = accessToken;
}

/**
* Constructor for OAuth authentication with refresh token
* @param accessToken OAuth access token
* @param refreshToken OAuth refresh token
* @param expiryTime Token expiry time in milliseconds
*/
public CitesphereAuthToken(String accessToken, String refreshToken, long expiryTime) {
this.authType = "oauth";
this.accessToken = accessToken;
this.refreshToken = refreshToken;
this.tokenExpiryTime = expiryTime;
}

/**
* Constructor for Basic authentication
* @param username Username
* @param password Password
*/
public CitesphereAuthToken(String username, String password) {
this.authType = "basic";
this.username = username;
this.password = password;
}

// Getters and setters
public String getAuthType() {
return authType;
}

public void setAuthType(String authType) {
this.authType = authType;
}

public Map<String, String> getHeaders() {
return headers;
}

public void setHeaders(Map<String, String> headers) {
this.headers = headers;
}

public String getAccessToken() {
return accessToken;
}

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

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 String getRefreshToken() {
return refreshToken;
}

public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}

public long getTokenExpiryTime() {
return tokenExpiryTime;
}

public void setTokenExpiryTime(long tokenExpiryTime) {
this.tokenExpiryTime = tokenExpiryTime;
}

/**
* Check if the access token is expired
* @return true if token is expired, false otherwise
*/
public boolean isTokenExpired() {
return tokenExpiryTime > 0 && System.currentTimeMillis() > tokenExpiryTime;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package edu.asu.diging.vspace.core.services;

import java.util.Map;
import edu.asu.diging.vspace.core.exception.CitesphereTokenException;

/**
* Service interface for Citesphere API operations
*/
public interface ICitesphereManager {

/**
* Get user information
* @return User data as Map
*/
Map<String, Object> getUser();

/**
* Check test endpoint
* @return Test response as Map
*/
Map<String, Object> checkTest();

/**
* Check access for a document
* @param documentId Document ID to check access for
* @return Access check response as Map
*/
Map<String, Object> checkAccess(String documentId);

/**
* Get data by endpoint
* @param endpoint API endpoint path
* @return Data response as Map
*/
Map<String, Object> getDataByEndpoint(String endpoint);

/**
* Get all groups
* @return Groups data as Map
*/
Map<String, Object> getGroups();

/**
* Get group information
* @param groupId Group ID
* @return Group information as Map
*/
Map<String, Object> getGroupInfo(String groupId);

/**
* Get group items
* @param zoteroGroupId Zotero group ID
* @return Group items as Map
*/
Map<String, Object> getGroupItems(String zoteroGroupId);

/**
* Get collections
* @param zoteroGroupId Zotero group ID
* @return Collections as Map
*/
Map<String, Object> getCollections(String zoteroGroupId);

/**
* Get collection items
* @param zoteroGroupId Zotero group ID
* @param collectionId Collection ID
* @param pageNumber Page number (optional, defaults to 0)
* @return Collection items as Map
*/
Map<String, Object> getCollectionItems(String zoteroGroupId, String collectionId, int pageNumber);

/**
* Get collection items (overloaded method without page number)
* @param zoteroGroupId Zotero group ID
* @param collectionId Collection ID
* @return Collection items as Map
*/
Map<String, Object> getCollectionItems(String zoteroGroupId, String collectionId);

/**
* Get item information
* @param zoteroGroupId Zotero group ID
* @param itemId Item ID
* @return Item information as Map
*/
Map<String, Object> getItemInfo(String zoteroGroupId, String itemId);

/**
* Get collections by collection ID
* @param zoteroGroupId Zotero group ID
* @param collectionId Collection ID
* @return Collections as Map
*/
Map<String, Object> getCollectionsByCollectionId(String zoteroGroupId, String collectionId);

/**
* Add item to group
* @param groupId Group ID
* @param data Item data
* @param filePath Path to file to upload
* @return Response from API
*/
Object addItem(String groupId, Map<String, Object> data, String filePath);

/**
* Refresh the access token using refresh token
* @return New CitesphereAuthToken with refreshed access token
* @throws CitesphereTokenException if refresh fails
*/
CitesphereAuthToken refreshToken() throws CitesphereTokenException;

/**
* Validate if current token is still valid
* @return true if token is valid, false otherwise
*/
boolean isTokenValid();
}
Loading