Added frontend components to control certificates and the like for SSO

This commit is contained in:
frikky
2021-09-18 17:44:59 +02:00
parent 96cf883f08
commit e0aa368b24
3 changed files with 111 additions and 27 deletions
+5 -2
View File
@@ -857,6 +857,7 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) {
userInfo, err := shuffle.HandleApiAuthentication(resp, request)
if err != nil {
log.Printf("[WARNING] Api authentication failed in handleInfo: %s", err)
resp.WriteHeader(401)
resp.Write([]byte(`{"success": false}`))
return
@@ -1177,8 +1178,10 @@ func checkAdminLogin(resp http.ResponseWriter, request *http.Request) {
return
}
//ssoUrl = org.SSOConfig.SOSOEntrypoint
redirectUri := shuffle.SSOUrl
resp.WriteHeader(200)
resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "redirect"}`)))
resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "redirect", "sso_url": "%s"}`, redirectUri)))
}
func handleLogin(resp http.ResponseWriter, request *http.Request) {
@@ -5866,7 +5869,7 @@ func initHandlers() {
// Docker orborus specific - downloads an image
r.HandleFunc("/api/v1/get_docker_image", getDockerImage).Methods("POST", "OPTIONS")
r.HandleFunc("/api/v1/migrate_database", migrateDatabase).Methods("POST", "OPTIONS")
r.HandleFunc("/api/v1/login_sso", shuffle.HandleSSO).Methods("GET", "POST", "OPTIONS")
r.HandleFunc("/api/v1/login_sso", shuffle.HandleSSO).Methods("POST", "OPTIONS")
// Important for email, IDS etc. Create this by:
// PS: For cloud, this has to use cloud storage.
+86 -14
View File
@@ -36,6 +36,8 @@ const OrgHeader = (props) => {
const [appDownloadBranch, setAppDownloadBranch] = React.useState(selectedOrganization.defaults === undefined ? defaultBranch : selectedOrganization.defaults.app_download_branch === undefined || selectedOrganization.defaults.app_download_branch.length === 0 ? defaultBranch : selectedOrganization.defaults.app_download_branch)
const [workflowDownloadUrl, setWorkflowDownloadUrl] = React.useState(selectedOrganization.defaults === undefined ? "https://github.com/frikky/shuffle-apps" : selectedOrganization.defaults.workflow_download_repo === undefined || selectedOrganization.defaults.workflow_download_repo.length === 0 ? "https://github.com/frikky/shuffle-workflows" : selectedOrganization.defaults.workflow_download_repo)
const [workflowDownloadBranch, setWorkflowDownloadBranch] = React.useState(selectedOrganization.defaults === undefined ? defaultBranch : selectedOrganization.defaults.workflow_download_branch === undefined || selectedOrganization.defaults.workflow_download_branch.length === 0 ? defaultBranch : selectedOrganization.defaults.workflow_download_branch)
const [ssoEntrypoint, setSsoEntrypoint] = React.useState(selectedOrganization.sso_config === undefined ? "" : selectedOrganization.sso_config.sso_entrypoint === undefined || selectedOrganization.sso_config.sso_entrypoint.length === 0 ? "" : selectedOrganization.sso_config.sso_entrypoint)
const [ssoCertificate, setSsoCertificate] = React.useState(selectedOrganization.sso_config === undefined ? "" : selectedOrganization.sso_config.sso_certificate === undefined || selectedOrganization.sso_config.sso_certificate.length === 0 ? "" : selectedOrganization.sso_config.sso_certificate)
const [file, setFile] = React.useState("")
const [fileBase64, setFileBase64] = React.useState(selectedOrganization.image)
@@ -67,13 +69,14 @@ const OrgHeader = (props) => {
}
}
const handleEditOrg = (name, description, orgId, image, defaults) => {
const handleEditOrg = (name, description, orgId, image, defaults, sso_config) => {
const data = {
"name": name,
"description": description,
"org_id": orgId,
"image": image,
"defaults": defaults,
"sso_config": sso_config,
}
const url = globalUrl + `/api/v1/orgs/${selectedOrganization.id}`;
@@ -111,19 +114,25 @@ const OrgHeader = (props) => {
}
const orgSaveButton =
<Button
style={{ width: 150, height: 55, flex: 1 }}
variant="contained"
color="primary"
onClick={() => handleEditOrg(orgName, orgDescription, selectedOrganization.id, selectedOrganization.image, {
"app_download_repo": appDownloadUrl,
"app_download_branch": appDownloadBranch,
"workflow_download_repo": workflowDownloadUrl,
"workflow_download_branch": workflowDownloadBranch,
})}
>
<SaveIcon />
</Button>
<Tooltip title="Save any unsaved data" placement="bottom">
<Button
style={{ width: 150, height: 55, flex: 1 }}
variant="contained"
color="primary"
onClick={() => handleEditOrg(orgName, orgDescription, selectedOrganization.id, selectedOrganization.image, {
"app_download_repo": appDownloadUrl,
"app_download_branch": appDownloadBranch,
"workflow_download_repo": workflowDownloadUrl,
"workflow_download_branch": workflowDownloadBranch,
},
{
"sso_entrypoint": ssoEntrypoint,
"sso_certificate": ssoCertificate,
})}
>
<SaveIcon />
</Button>
</Tooltip>
var imageData = file.length > 0 ? file : fileBase64
imageData = imageData === undefined || imageData.length === 0 ? defaultImage : imageData
@@ -337,6 +346,69 @@ const OrgHeader = (props) => {
/>
</span>
</Grid>
<Grid item xs={6} style={{}}>
<span>
<Typography>
SSO Entrypoint
</Typography>
<TextField
required
style={{flex: "1", marginTop: "5px", marginRight: "15px", backgroundColor: theme.palette.inputColor}}
fullWidth={true}
type="name"
multiline={true}
rows={2}
disabled={selectedOrganization.manager_orgs !== undefined && selectedOrganization.manager_orgs !== null && selectedOrganization.manager_orgs.length > 0}
id="outlined-with-placeholder"
margin="normal"
variant="outlined"
placeholder="The entrypoint URL from your provider"
value={ssoEntrypoint}
onChange={e => {
setSsoEntrypoint(e.target.value)
}}
InputProps={{
classes: {
notchedOutline: classes.notchedOutline,
},
style:{
color: "white",
},
}}
/>
</span>
</Grid>
<Grid item xs={6} style={{}}>
<span>
<Typography>
SSO Certificate
</Typography>
<TextField
required
style={{flex: "1", marginTop: "5px", marginRight: "15px", backgroundColor: theme.palette.inputColor}}
fullWidth={true}
type="name"
id="outlined-with-placeholder"
margin="normal"
variant="outlined"
multiline={true}
rows={2}
placeholder="The X509 certificate to use"
value={ssoCertificate}
onChange={e => {
setSsoCertificate(e.target.value)
}}
InputProps={{
classes: {
notchedOutline: classes.notchedOutline,
},
style:{
color: "white",
},
}}
/>
</span>
</Grid>
{/*
<span style={{textAlign: "center"}}>
{expanded ?
+20 -11
View File
@@ -34,6 +34,7 @@ const LoginDialog = props => {
const [firstRequest, setFirstRequest] = useState(true);
const [loginLoading, setLoginLoading] = useState(false);
const [loginViewLoading, setLoginViewLoading] = useState(false);
const [ssoUrl, setSSOUrl] = useState("")
// Used to swap from login to register. True = login, false = register
@@ -62,6 +63,10 @@ const LoginDialog = props => {
if (responseJson["success"] === false) {
setLoginInfo(responseJson["reason"])
} else {
if (responseJson.sso_url !== undefined && responseJson.sso_url !== null) {
setSSOUrl(responseJson.sso_url)
}
if (loginViewLoading) {
setLoginViewLoading(false)
checkLogin()
@@ -306,17 +311,21 @@ const LoginDialog = props => {
<div style={{ marginTop: "10px" }}>
{loginInfo}
</div>
<Typography style={{textAlign: "center", }}>
Or
</Typography>
<div style={{textAlign: "center", margin: 10, }}>
<Button fullWidth color="secondary" variant="outlined" type="button" style={{ flex: "1", marginTop: 5}} onClick={() => {
console.log("CLICK")
window.location = "https://dev-23367303.okta.com/app/dev-23367303_shuffletest_1/exk1vg1j7bYUYEG0k5d7/sso/saml"
}}>
Use SSO
</Button>
</div>
{ssoUrl !== undefined && ssoUrl !== null && ssoUrl.length > 0 ?
<div>
<Typography style={{textAlign: "center", }}>
Or
</Typography>
<div style={{textAlign: "center", margin: 10, }}>
<Button fullWidth color="secondary" variant="outlined" type="button" style={{ flex: "1", marginTop: 5}} onClick={() => {
console.log("CLICK")
window.location = ssoUrl
}}>
Use SSO
</Button>
</div>
</div>
: null}
</form>
}
</Paper>