Started backend app search engine

This commit is contained in:
frikky
2020-05-22 19:09:24 +02:00
parent 0819a926a7
commit 376dc67bf6
4 changed files with 113 additions and 44 deletions
+3 -2
View File
@@ -5743,15 +5743,16 @@ func init() {
r.HandleFunc("/api/v1/streams", handleWorkflowQueue).Methods("POST")
r.HandleFunc("/api/v1/streams/results", handleGetStreamResults).Methods("POST", "OPTIONS")
// App specific
r.HandleFunc("/api/v1/apps/get_existing", loadSpecificApps).Methods("POST", "OPTIONS")
r.HandleFunc("/api/v1/apps/validate", validateAppInput).Methods("POST", "OPTIONS")
r.HandleFunc("/api/v1/apps/{appId}", deleteWorkflowApp).Methods("DELETE", "OPTIONS")
r.HandleFunc("/api/v1/apps/{appId}/config", getWorkflowAppConfig).Methods("GET", "OPTIONS")
r.HandleFunc("/api/v1/apps", getWorkflowApps).Methods("GET", "OPTIONS")
r.HandleFunc("/api/v1/apps", setNewWorkflowApp).Methods("PUT", "OPTIONS")
r.HandleFunc("/api/v1/apps/search", getSpecificApps).Methods("POST", "OPTIONS")
// Legacy things
// Legacy app things
r.HandleFunc("/api/v1/workflows/apps/validate", validateAppInput).Methods("POST", "OPTIONS")
r.HandleFunc("/api/v1/workflows/apps", getWorkflowApps).Methods("GET", "OPTIONS")
r.HandleFunc("/api/v1/workflows/apps", setNewWorkflowApp).Methods("PUT", "OPTIONS")
+45
View File
@@ -2917,6 +2917,51 @@ func handleGetfile(resp http.ResponseWriter, request *http.Request) ([]byte, err
return buf.Bytes(), nil
}
func getSpecificApps(resp http.ResponseWriter, request *http.Request) {
cors := handleCors(resp, request)
if cors {
return
}
// Just need to be logged in
// FIXME - should have some permissions?
_, err := handleApiAuthentication(resp, request)
if err != nil {
log.Printf("Api authentication failed in set new app: %s", err)
resp.WriteHeader(401)
resp.Write([]byte(`{"success": false}`))
return
}
body, err := ioutil.ReadAll(request.Body)
if err != nil {
log.Printf("Error with body read: %s", err)
resp.WriteHeader(401)
resp.Write([]byte(`{"success": false}`))
return
}
type tmpStruct struct {
Search string `json:"search"`
}
var tmpBody tmpStruct
err = json.Unmarshal(body, &tmpBody)
if err != nil {
log.Printf("Error with unmarshal tmpBody: %s", err)
resp.WriteHeader(401)
resp.Write([]byte(`{"success": false}`))
return
}
// FIXME - continue the search here with github repos etc.
// Caching might be smart :D
log.Printf("Body: %s", string(body))
resp.WriteHeader(200)
resp.Write([]byte(fmt.Sprintf(`{"success": true}`)))
}
func validateAppInput(resp http.ResponseWriter, request *http.Request) {
cors := handleCors(resp, request)
if cors {
+27 -13
View File
@@ -90,8 +90,8 @@ const AngularWorkflow = (props) => {
const [cystyle, ] = useState(cytoscapestyle)
const [cy, setCy] = React.useState()
const [appSearch, setAppSearch] = React.useState("")
const [currentView, setCurrentView] = React.useState("apps")
const [, setAppSearchValue] = React.useState("")
const [triggerAuthentication, setTriggerAuthentication] = React.useState({})
const [triggerFolders, setTriggerFolders] = React.useState([])
@@ -1385,10 +1385,6 @@ const AngularWorkflow = (props) => {
});
}
const setAppSearch = (event) => {
setFilteredApps(apps.filter(app => app.name.includes(event.target.value)))
}
const appViewStyle = {
marginLeft: "5px",
marginRight: "5px",
@@ -1568,6 +1564,7 @@ const AngularWorkflow = (props) => {
}
const HandleLeftView = () => {
// Defaults to apps.
var thisview = <AppView />
if (currentView === "triggers") {
thisview = <TriggersView />
@@ -1577,14 +1574,6 @@ const AngularWorkflow = (props) => {
return(
<div>
<div style={{cursor: "pointer", height: 20, marginLeft: 10, marginTop: 10}} onClick={() => {
setLeftViewOpen(false)
setLeftBarSize(50)
}}>
<Tooltip color="primary" title="Minimize" placement="top">
<KeyboardArrowLeftIcon />
</Tooltip>
</div>
<Divider style={{marginTop: 10, height: 1, width: "100%", backgroundColor: "rgb(91, 96, 100)"}}/>
<div style={{minHeight: bodyHeight-appBarSize-150, maxHeight: bodyHeight-appBarSize-100}}>
{thisview}
@@ -1981,11 +1970,36 @@ const AngularWorkflow = (props) => {
overflowX: "hidden",
}
const runAppSearch = (event) => {
setAppSearch(event.target.value)
setFilteredApps(apps.filter(app => app.name.toLowerCase().includes(event.target.value.trim().toLowerCase())))
}
const AppView = () => {
return(
<div style={appViewStyle}>
<div style={{flex: "1"}}>
<div style={appScrollStyle}>
{/*
<TextField
style={{backgroundColor: inputColor}}
InputProps={{
style:{
color: "white",
minHeight: "50px",
marginLeft: "5px",
maxWidth: "95%",
fontSize: "1em",
},
}}
fullWidth
color="primary"
placeholder={"Search apps"}
onChange={(event) => {
runAppSearch(event)
}}
/>
*/}
{filteredApps.map(app=> {
// FIXME - add label to apps, as this might be slow with A LOT of apps
var newAppname = app.name
+38 -29
View File
@@ -38,6 +38,7 @@ const Apps = (props) => {
const [filteredApps, setFilteredApps] = React.useState([])
const [validation, setValidation] = React.useState(false)
const [isLoading, setIsLoading] = React.useState(false)
const [appSearchLoading, setAppSearchLoading] = React.useState(false)
const [openApi, setOpenApi] = React.useState("")
const [openApiData, setOpenApiData] = React.useState("")
@@ -109,7 +110,7 @@ const Apps = (props) => {
if (responseJson.length > 0) {
setSelectedApp(responseJson[0])
}
})
})
.catch(error => {
alert.error(error.toString())
});
@@ -254,33 +255,6 @@ const Apps = (props) => {
marginBottom: 10,
}
//const handleFile = (event) =>{
// const formData = new FormData();
// formData.append('file', event.target.files[0]);
// fetch(globalUrl+"/api/v1/workflows/apps/validate", {
// method: 'POST',
// headers: {
// 'Accept': 'application/json',
// },
// body: formData,
// credentials: "include",
// })
// .then((response) => {
// if (response.status !== 200) {
// console.log("Status not 200 for apps :O!")
// return
// }
// return response.json()
// })
// .then((responseJson) => {
// console.log(responseJson)
// })
// .catch(error => {
// alert.error(error.toString())
// });
//}
const UploadView = () => {
//var imageline = selectedApp.large_image === undefined || selectedApp.large_image.length === 0 ?
// <img alt="" style={{width: "80px"}} />
@@ -386,7 +360,13 @@ const Apps = (props) => {
const handleSearchChange = (event) => {
const searchfield = event.target.value.toLowerCase()
const newapps = apps.filter(data => data.name.toLowerCase().includes(searchfield) || data.description.toLowerCase().includes(searchfield))
setFilteredApps(newapps)
if (newapps.length === 0 && !appSearchLoading) {
setAppSearchLoading(true)
runAppSearch(searchfield)
} else {
setFilteredApps(newapps)
}
}
const appView = isLoggedIn ?
@@ -461,6 +441,12 @@ const Apps = (props) => {
<h4>
Try a broader search term. E.g. "http" or "TheHive"
</h4>
<div/>
{appSearchLoading ?
<CircularProgress color="primary" style={{margin: "auto"}}/>
: null
}
</Paper>
:
<Paper square style={uploadViewPaperStyle}>
@@ -577,6 +563,29 @@ const Apps = (props) => {
});
}
const runAppSearch = (searchterm) => {
const data = {"search": searchterm}
fetch(globalUrl+"/api/v1/apps/search", {
method: 'POST',
headers: {
'Accept': 'application/json',
},
body: JSON.stringify(data),
credentials: "include",
})
.then((response) => {
setAppSearchLoading(false)
return response.json()
})
.then((responseJson) => {
console.log(responseJson)
})
.catch(error => {
alert.error(error.toString())
});
}
const validateRemote = () => {
setValidation(true)