From f6f9da07901a90dad77c15690464facfc1fa8e67 Mon Sep 17 00:00:00 2001 From: learner97 Date: Wed, 10 Apr 2024 17:40:08 -0600 Subject: [PATCH 1/2] tested a few things in backend, removed need for tokens in some areas, got view pages to start displaying --- .../sbh3/controllers/AdminController.java | 10 ++++++-- .../sbh3/controllers/DownloadController.java | 15 ++++++++---- .../sbh3/controllers/SearchController.java | 7 +++--- .../sbh3/security/config/SecurityConfig.java | 2 +- .../sbh3/services/SearchService.java | 12 +++++----- frontend/components/Admin/Registries.js | 23 +++++++++++++------ frontend/public/commitHash.txt | 2 +- 7 files changed, 45 insertions(+), 26 deletions(-) diff --git a/backend/src/main/java/com/synbiohub/sbh3/controllers/AdminController.java b/backend/src/main/java/com/synbiohub/sbh3/controllers/AdminController.java index 5faf147f..ed9875cf 100644 --- a/backend/src/main/java/com/synbiohub/sbh3/controllers/AdminController.java +++ b/backend/src/main/java/com/synbiohub/sbh3/controllers/AdminController.java @@ -130,8 +130,14 @@ public String deletePlugin(@RequestParam Map allParams, HttpServl @GetMapping(value = "/admin/registries") @ResponseBody public JsonNode getRegistries() throws IOException { - return ConfigUtil.get("webOfRegistries"); - + try { + JsonNode result = ConfigUtil.get("webOfRegistries"); + return result; + } catch (IOException e) { + e.printStackTrace(); + // Optionally, handle the exception or log more details here. + throw e; // rethrow the exception if you want to maintain the current method signature + } } @PostMapping(value = "/admin/saveRegistry") diff --git a/backend/src/main/java/com/synbiohub/sbh3/controllers/DownloadController.java b/backend/src/main/java/com/synbiohub/sbh3/controllers/DownloadController.java index 3e4f3b09..55c88fdf 100644 --- a/backend/src/main/java/com/synbiohub/sbh3/controllers/DownloadController.java +++ b/backend/src/main/java/com/synbiohub/sbh3/controllers/DownloadController.java @@ -1,6 +1,5 @@ package com.synbiohub.sbh3.controllers; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.synbiohub.sbh3.services.DownloadService; import com.synbiohub.sbh3.utils.ConfigUtil; @@ -13,7 +12,6 @@ import org.springframework.util.AntPathMatcher; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import java.io.ByteArrayInputStream; @@ -30,9 +28,16 @@ public class DownloadController extends AntPathMatcher { private final ObjectMapper mapper; @GetMapping(value = "/public/{db}/{id}/{ver}/sbol") // Separate mapping for private components /user/{username}/{db}/{id}/{ver} + public ResponseEntity getSBOLRecursiveRDFDownload(@PathVariable String db, @PathVariable String id, @PathVariable String ver) throws IOException { + return getInputStreamResourceResponseEntity(db, id, ver); + } + + @GetMapping(value = "/public/{db}/{id}/{ver}") // Separate mapping for private components /user/{username}/{db}/{id}/{ver} public ResponseEntity getSBOLRecursiveRDF(@PathVariable String db, @PathVariable String id, @PathVariable String ver) throws IOException { -// var uri = request.getRequestURL().toString(); -// String splitUri = uri.split("/sbol")[0]; //TODO replace http://localhost:6789 with https://synbiohub.org + return getInputStreamResourceResponseEntity(db, id, ver); + } + + private ResponseEntity getInputStreamResourceResponseEntity(String db, String id, String ver) throws IOException { String splitUri = ConfigUtil.get("defaultGraph").toString().replace("\"","") + "/" + db + "/" + id + "/" + ver; String uri = splitUri + "/sbol"; @@ -50,7 +55,7 @@ public ResponseEntity getSBOLRecursiveRDF(@PathVariable String db, @PathVaria //.contentLength(results.length) .contentType( MediaType.parseMediaType("application/xml")) - .header("Content-Disposition", "attachment; filename=\"" + uriArr[uriArr.length-3] + ".xml\"") + .header("Content-Disposition", "attachment; filename=\"" + uriArr[uriArr.length - 3] + ".xml\"") .body(new InputStreamResource(new ByteArrayInputStream(byteOutput.toByteArray()))); } diff --git a/backend/src/main/java/com/synbiohub/sbh3/controllers/SearchController.java b/backend/src/main/java/com/synbiohub/sbh3/controllers/SearchController.java index 08c682ba..db579c77 100644 --- a/backend/src/main/java/com/synbiohub/sbh3/controllers/SearchController.java +++ b/backend/src/main/java/com/synbiohub/sbh3/controllers/SearchController.java @@ -8,9 +8,7 @@ import org.json.JSONObject; import org.springframework.web.bind.annotation.*; -import javax.json.Json; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.util.Map; @RestController @@ -199,8 +197,9 @@ public String getTypeCount(@PathVariable("type") String type, HttpServletRequest */ @RequestMapping(value = "/sparql", headers = "Accept=application/json") @ResponseBody - public String getSPARQL(@RequestParam String query) throws IOException { - return searchService.SPARQLQuery(query); + public String getSPARQL(@RequestParam Map params) throws IOException { + System.out.println(params); + return searchService.SPARQLQuery(params.get("query")); } // @GetMapping(value = "/search/**") diff --git a/backend/src/main/java/com/synbiohub/sbh3/security/config/SecurityConfig.java b/backend/src/main/java/com/synbiohub/sbh3/security/config/SecurityConfig.java index ec32b1d9..83355359 100644 --- a/backend/src/main/java/com/synbiohub/sbh3/security/config/SecurityConfig.java +++ b/backend/src/main/java/com/synbiohub/sbh3/security/config/SecurityConfig.java @@ -53,7 +53,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .cors() .and() .authorizeHttpRequests() - .requestMatchers("/setup", "/login", "/register", "/search", "/search/**", "/searchCount", "/searchCount/**", "/twins", "/uses", "/similar", "/sbol", "/sbolnr", "/metadata", "/gb", "/fasta", "/gff", "/download", "/public/**", "/sparql", "/ComponentDefinition/**", "/**/count", "/count", "/admin/theme").permitAll() + .requestMatchers("/setup", "/login", "/register", "/search", "/search/**", "/searchCount", "/searchCount/**", "/twins", "/uses", "/similar", "/sbol", "/sbolnr", "/metadata", "/gb", "/fasta", "/gff", "/download", "/public/**", "/sparql", "/ComponentDefinition/**", "/**/count", "/count", "/admin/theme", "/admin/registries", "admin/plugins").permitAll() .anyRequest().authenticated() .and() .csrf().disable() diff --git a/backend/src/main/java/com/synbiohub/sbh3/services/SearchService.java b/backend/src/main/java/com/synbiohub/sbh3/services/SearchService.java index c9b29241..f329c6d6 100644 --- a/backend/src/main/java/com/synbiohub/sbh3/services/SearchService.java +++ b/backend/src/main/java/com/synbiohub/sbh3/services/SearchService.java @@ -350,7 +350,7 @@ public String SPARQLQuery(String query) throws IOException { HashMap params = new HashMap<>(); params.put("default-graph-uri", ConfigUtil.get("defaultGraph").asText()); params.put("query", query); - + System.out.println(query.getClass().getName()); url = ConfigUtil.get("sparqlEndpoint").asText() + "?default-graph-uri={default-graph-uri}&query={query}&format=json&"; // url = ConfigUtil.get("sparqlEndpoint").asText() + "?default-graph-uri={default-graph-uri}&query={query}"; // has to be the first one. without format json, getting root collections fails @@ -369,7 +369,7 @@ public byte[] SPARQLRDFXMLQuery(String query) throws IOException { httpHeaders.add("Accept", "application/rdf+xml"); HttpEntity entity = new HttpEntity(httpHeaders); - url = ConfigUtil.get("sparqlEndpoint").asText() + "?default-graph-uri={default-graph-uri}&query={query}"; + url = ConfigUtil.get("sparqlEndpoint").asText(); var rest = restTemplate.exchange(url, HttpMethod.GET, entity, byte[].class, params); return rest.getBody(); @@ -385,12 +385,12 @@ public byte[] queryOldSBHSparqlEndpoint(String WOREndpoint, String query) throws String url; HashMap params = new HashMap<>(); // params.put("default-graph-uri", ConfigUtil.get("defaultGraph").asText()); - params.put("query", query); - params.put("format", "application/rdf+xml"); +// params.put("query", query); +// params.put("format", "application/rdf+xml"); HttpHeaders httpHeaders = new HttpHeaders(); // httpHeaders.add("Accept", "application/json"); - httpHeaders.add("Accept", "application/rdf+xml"); - HttpEntity entity = new HttpEntity<>("body", httpHeaders); + httpHeaders.add("Accept", "text/plain"); + HttpEntity entity = new HttpEntity<>(httpHeaders); // url = WOREndpoint + "/sparql?query="+query; // var result = restTemplate.getForObject(url, String.class); diff --git a/frontend/components/Admin/Registries.js b/frontend/components/Admin/Registries.js index 5e40027d..d62486ce 100644 --- a/frontend/components/Admin/Registries.js +++ b/frontend/components/Admin/Registries.js @@ -324,7 +324,7 @@ const sortMethods = { const useRegistries = (token, dispatch) => { const { data, error } = useSWR( - [`${publicRuntimeConfig.backend}/admin/registries`, token, dispatch], + [`${publicRuntimeConfig.backend}/admin/registries`, dispatch], fetcher ); return { @@ -334,13 +334,12 @@ const useRegistries = (token, dispatch) => { }; }; -const fetcher = (url, token, dispatch) => +const fetcher = (url, dispatch) => axios .get(url, { headers: { 'Content-Type': 'application/json', - Accept: 'application/json', - 'X-authorization': token + Accept: 'application/json' } }) .then(response => response.data) @@ -352,10 +351,20 @@ const fetcher = (url, token, dispatch) => export async function processUrl(inputUrl, token, dispatch) { - const data = await fetcher(`${publicRuntimeConfig.backend}/admin/registries`, token, dispatch); + const data = await fetcher(`${publicRuntimeConfig.backend}/admin/registries`, dispatch); + + if (data) { - const registries = data.registries; + let registries; + // Check if data.registries is an array + if (data.registries && Array.isArray(data.registries)) { + registries = data.registries; + } else if (data && typeof data === 'object') { + registries = [data]; // This is an example, adjust based on your needs + } else { + registries = []; + } for (const registry of registries) { if (inputUrl.startsWith(registry.uri)) { @@ -371,7 +380,7 @@ export async function processUrl(inputUrl, token, dispatch) { export async function processUrlReverse(inputUrl, token, dispatch) { - const data = await fetcher(`${publicRuntimeConfig.backend}/admin/registries`, token, dispatch); + const data = await fetcher(`${publicRuntimeConfig.backend}/admin/registries`, dispatch); if (data) { const registries = data.registries; diff --git a/frontend/public/commitHash.txt b/frontend/public/commitHash.txt index 1ed322d6..8c8584ae 100644 --- a/frontend/public/commitHash.txt +++ b/frontend/public/commitHash.txt @@ -1 +1 @@ -f9c72e082959d08d21bc635f6c81ff0d99cffc31 \ No newline at end of file +35018640cb85726c5305f5a619ea4b275bbe811f \ No newline at end of file From 893191d8c5d5e9d736036d74a90fd88da4d947f8 Mon Sep 17 00:00:00 2001 From: learner97 Date: Thu, 18 Apr 2024 19:07:34 -0600 Subject: [PATCH 2/2] removed instances of hardcoded synbiohub.org, adjusted queries for that --- frontend/.env.development | 4 +-- frontend/components/Admin/Registries.js | 6 ++--- .../components/Viewing/Collection/Members.js | 4 ++- .../Fetching/executeQueryFromTableJSON.js | 10 ++++--- .../PageJSON/Rendering/TableBuilder.js | 4 +++ .../Viewing/Sections/Details/Details.js | 2 +- frontend/pages/[...view].js | 12 +++++++-- frontend/public/commitHash.txt | 2 +- frontend/sparql/tools/getQueryResponse.js | 20 +++++++++++++- frontend/specialAccess/setup.js | 27 +++++++++++++------ 10 files changed, 68 insertions(+), 23 deletions(-) diff --git a/frontend/.env.development b/frontend/.env.development index 08697a0f..0734af5a 100644 --- a/frontend/.env.development +++ b/frontend/.env.development @@ -1,2 +1,2 @@ -backend="http://localhost:6789" -backendSS="http://localhost:6789" \ No newline at end of file +backend="http://localhost:7777" +backendSS="http://localhost:7777" \ No newline at end of file diff --git a/frontend/components/Admin/Registries.js b/frontend/components/Admin/Registries.js index d62486ce..a788d738 100644 --- a/frontend/components/Admin/Registries.js +++ b/frontend/components/Admin/Registries.js @@ -355,7 +355,7 @@ export async function processUrl(inputUrl, token, dispatch) { - if (data) { + if (data && data.registries) { let registries; // Check if data.registries is an array if (data.registries && Array.isArray(data.registries)) { @@ -368,7 +368,7 @@ export async function processUrl(inputUrl, token, dispatch) { for (const registry of registries) { if (inputUrl.startsWith(registry.uri)) { - const urlRemovedForLink = inputUrl.replace(registry.uri, ""); + const urlRemovedForLink = inputUrl.replace(registry.uri, ""); // TODO: Should only strip for only "you" const urlReplacedForBackend = inputUrl.replace(registry.uri, registry.url); return { urlRemovedForLink, urlReplacedForBackend }; } @@ -382,7 +382,7 @@ export async function processUrlReverse(inputUrl, token, dispatch) { const data = await fetcher(`${publicRuntimeConfig.backend}/admin/registries`, dispatch); - if (data) { + if (data && data.registries) { const registries = data.registries; for (const registry of registries) { diff --git a/frontend/components/Viewing/Collection/Members.js b/frontend/components/Viewing/Collection/Members.js index 0309cc88..70de669c 100644 --- a/frontend/components/Viewing/Collection/Members.js +++ b/frontend/components/Viewing/Collection/Members.js @@ -25,6 +25,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faTrash, faUnlink } from '@fortawesome/free-solid-svg-icons'; import { getAfterThirdSlash } from '../ViewHeader'; import Status, { useStatus } from '../../Admin/Status'; +import { useTheme } from '../../Admin/Theme'; /* eslint sonarjs/cognitive-complexity: "off" */ @@ -51,6 +52,7 @@ export default function Members(properties) { const [typeFilter, setTypeFilter] = useState('Show Only Root Objects'); const dispatch = useDispatch(); const [processedUri, setProcessedUri] = useState(publicRuntimeConfig.backend); + const { theme } = useTheme(); let preparedSearch = search !== '' @@ -74,7 +76,7 @@ export default function Members(properties) { const parameters = { from: '', - graphPrefix: 'https://synbiohub.org/', // TODO: Maybe get this from somewhere? + graphPrefix: `${theme.uriPrefix}`, // TODO: Maybe get this from somewhere? collection: properties.uri, sort: sort, search: preparedSearch, diff --git a/frontend/components/Viewing/PageJSON/Fetching/executeQueryFromTableJSON.js b/frontend/components/Viewing/PageJSON/Fetching/executeQueryFromTableJSON.js index e4d995f6..f6534307 100644 --- a/frontend/components/Viewing/PageJSON/Fetching/executeQueryFromTableJSON.js +++ b/frontend/components/Viewing/PageJSON/Fetching/executeQueryFromTableJSON.js @@ -10,15 +10,17 @@ export default function executeQueryFromTableJSON( ) { if (typeof uri === "undefined") { uri = "URI is undefined"; -} + } + + console.log(uri); - return getQueryResponse( dispatch, prefixes + '\n' + buildQuery(uri, table), - {}, + { uri }, '', false, - urlOverride + urlOverride, + uri ); } diff --git a/frontend/components/Viewing/PageJSON/Rendering/TableBuilder.js b/frontend/components/Viewing/PageJSON/Rendering/TableBuilder.js index fcfad0b8..1a45c8a7 100644 --- a/frontend/components/Viewing/PageJSON/Rendering/TableBuilder.js +++ b/frontend/components/Viewing/PageJSON/Rendering/TableBuilder.js @@ -48,8 +48,12 @@ function TableRenderer({ uri, prefixes, table, metadata, owner }) { const token = useSelector(state => state.user.token); const [content, setContent] = useState(null); const dispatch = useDispatch(); + console.log(uri); + console.log(prefixes); + console.log(table); useEffect(() => { executeQueryFromTableJSON(dispatch, uri, prefixes, table).then(response => { + console.log(response); setContent(parseQueryResult(table, response, prefixes)); }); }, [uri, prefixes, table]); diff --git a/frontend/components/Viewing/Sections/Details/Details.js b/frontend/components/Viewing/Sections/Details/Details.js index 600fd928..03ea5656 100644 --- a/frontend/components/Viewing/Sections/Details/Details.js +++ b/frontend/components/Viewing/Sections/Details/Details.js @@ -29,7 +29,7 @@ export default function Details(properties) { if (details == undefined) { getQueryResponse(dispatch, getDetails, { uri: properties.uri }).then( details => { - if (details.length > 0) setDetails(details[0]); + if (details && details.length > 0) setDetails(details[0]); } ); diff --git a/frontend/pages/[...view].js b/frontend/pages/[...view].js index 8233b458..2d2a4635 100644 --- a/frontend/pages/[...view].js +++ b/frontend/pages/[...view].js @@ -13,6 +13,7 @@ import getQueryResponse from '../sparql/tools/getQueryResponse'; import { addError } from '../redux/actions'; import styles from '../styles/view.module.css'; import LinkedSearch from '../components/Search/StandardSearch/LinkedSearch'; +import { useTheme } from '../components/Admin/Theme'; export default function View({ data, error }) { const dispatch = useDispatch(); @@ -24,7 +25,7 @@ export default function View({ data, error }) { const token = useSelector(state => state.user.token); const url = view ? view.join('/') : ''; const [metadata, setMetadata] = useState(); - const uri = `https://synbiohub.org/${url}`; + const { theme } = useTheme(); const [urlExists, setUrlExists] = useState(true); // New state for URL existence const backenduri = `${publicRuntimeConfig.backend}/${url}`; @@ -65,13 +66,20 @@ export default function View({ data, error }) { marginTop: '-10vh', }; + let uri; + // let uri = `https://dan.org/${url}`; + if (theme) { + uri = `${theme.uriPrefix}${url}`; + } + + useEffect(() => { // Check if URL exists axios.get(backenduri) .then(response => { // URL exists setUrlExists(true); - if (!metadata) + if (!metadata && uri) getQueryResponse(dispatch, getMetadata, { uri: uri }, token).then( metadata => setMetadata(metadata) ); diff --git a/frontend/public/commitHash.txt b/frontend/public/commitHash.txt index 8c8584ae..1b08bb50 100644 --- a/frontend/public/commitHash.txt +++ b/frontend/public/commitHash.txt @@ -1 +1 @@ -35018640cb85726c5305f5a619ea4b275bbe811f \ No newline at end of file +f6f9da07901a90dad77c15690464facfc1fa8e67 \ No newline at end of file diff --git a/frontend/sparql/tools/getQueryResponse.js b/frontend/sparql/tools/getQueryResponse.js index a945b64e..c6d02cc5 100644 --- a/frontend/sparql/tools/getQueryResponse.js +++ b/frontend/sparql/tools/getQueryResponse.js @@ -13,6 +13,8 @@ export default async function getQueryResponse( admin, urlOverride ) { +console.log(options); + query = loadTemplate(query, options); const currentURL = window.location.href; @@ -23,7 +25,9 @@ export default async function getQueryResponse( const result = regex.exec(currentURL)[0]; const lastSlash = result.lastIndexOf('/'); const graphURL = result.substring(0, lastSlash); - graphEx = `&default-graph-uri=https://synbiohub.org${graphURL}`; + const uriPrefix = getUrlBeforeThirdSlash(options.uri); + console.log(`${uriPrefix}${graphURL}`); + graphEx = `&default-graph-uri=${uriPrefix}${graphURL}`; } const params = admin ? '/admin/sparql?query=' : '/sparql?query='; @@ -32,6 +36,9 @@ export default async function getQueryResponse( urlOverride || publicRuntimeConfig.backend }${params}${encodeURIComponent(query)}${graph}`; + console.log(options); + console.log(url); + const headers = { 'Content-Type': 'application/json', Accept: 'application/json', @@ -66,3 +73,14 @@ const processResults = results => { return resultObject; }); }; + +function getUrlBeforeThirdSlash(url) { + if (typeof url !== 'string') return ''; + let slashCount = 0, result = ''; + for (let i = 0; i < url.length; i++) { + if (url[i] === '/') slashCount++; + if (slashCount === 3) break; + result += url[i]; + } + return result; +} diff --git a/frontend/specialAccess/setup.js b/frontend/specialAccess/setup.js index c6dd999c..ec705371 100644 --- a/frontend/specialAccess/setup.js +++ b/frontend/specialAccess/setup.js @@ -22,7 +22,8 @@ export default function Setup({ setInSetupMode }) { const [logo, setLogo] = useState(undefined); const [allowPublicSignup, setAllowPublicSignup] = useState(true); - const [instanceURL, setInstanceURL] = useState('http://localhost:7777/'); + const [frontendURL, setFrontendURL] = useState('http://localhost:3333/'); + const [backendURL, setBackendURL] = useState('http://localhost:7777/'); const [uriPrefix, setUriPrefix] = useState('http://localhost:7777/'); const [userName, setUserName] = useState(''); @@ -110,11 +111,20 @@ export default function Setup({ setInSetupMode }) { content={
setInstanceURL(event.target.value)} - inputName="Instance URL" + labelText="Frontend URL: We need to know where this SynBioHub instance is is displayed. If the URL below is incorrect, please change it" + placeholder="Frontend URL" + value={frontendURL} + onChange={event => setFrontendURL(event.target.value)} + inputName="Frontend URL" + containerStyling={styles.inputcontainer} + /> + + setBackendURL(event.target.value)} + inputName="Backend URL" containerStyling={styles.inputcontainer} /> @@ -141,7 +151,7 @@ export default function Setup({ setInSetupMode }) { inputName="username" containerStyling={styles.inputcontainer} pattern="^[a-zA-Z0-9\-_\.~]+$" - title="Usernames can contain letters, numbers, and the symbols - _ . ~" + title="Usernames can only contain letters, numbers, and the symbols - _ . ~" /> @@ -206,7 +216,8 @@ export default function Setup({ setInSetupMode }) { `${publicRuntimeConfig.backend}/setup`, { instanceName, - instanceURL, + frontendURL, + backendURL, uriPrefix, userName, affiliation,