Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
feudal
feudalWebpage
Commits
b27c7d04
Commit
b27c7d04
authored
Feb 01, 2019
by
Lukas Burgey
Browse files
Rework IdP selection
parent
5170363d
Changes
8
Show whitespace changes
Inline
Side-by-side
src/app/header/header.component.css
View file @
b27c7d04
.header-bar
{
width
:
100%
;
}
.header-bar
>*
{
float
:
right
;
}
src/app/header/header.component.html
View file @
b27c7d04
<mat-toolbar
color=
"primary"
class=
"mat-typography"
>
<mat-toolbar-row>
<mat-toolbar-row
style=
"display: flex; justify-content: space-between; width: 100%;"
>
<div>
<h1>
Federated User Credential Deployment Portal
</h1>
<div
class=
"header-bar"
>
</div>
<div>
<span
*ngIf=
"(userService.userSrc() | async) as user; else notLoggedIn"
>
<button
mat-button
mat-icon-button
(click)=
"dialog.openAccount()"
>
<mat-icon>
settings
</mat-icon>
...
...
@@ -19,17 +21,18 @@
</button>
</span>
<ng-template
#notLoggedIn
>
<span
*ngIf=
"(idps$ | async) as idps"
>
<form
*ngIf=
"(selectedIdP$ | async) as selectedIdP"
(ngSubmit)=
"userService.login(selectedIdP)"
#loginForm
="
ngForm
"
>
<span
*ngIf=
"(userService.connectIdPInfo() | async) as idpInfo"
>
<form
(ngSubmit)=
"userService.login(selected)"
#loginForm
="
ngForm
"
>
<mat-form-field>
<mat-select
name=
"idp"
required
[(ngModel)]=
"selected
IdP
"
>
<mat-option
*ngFor=
"let idp of idps"
[value]=
"idp"
>
<mat-select
name=
"idp"
required
[(ngModel)]=
"selected
"
[compareWith]=
"idpCompare
"
>
<mat-option
*ngFor=
"let idp of
idpInfo.
idps"
[value]=
"idp"
>
{{ idp.name }}
</mat-option>
</mat-select>
</mat-form-field>
<button
mat-raised-button
[disabled]=
"!loginForm.form.valid"
color=
"accent"
type=
"submit"
>
Login
</button>
<button
mat-raised-button
[disabled]=
"!loginForm.form.valid"
color=
"accent"
type=
"submit"
>
Login
</button>
</form>
</span>
</ng-template>
...
...
src/app/header/header.component.ts
View file @
b27c7d04
...
...
@@ -3,7 +3,6 @@ import { Component, OnInit } from '@angular/core';
import
{
Observable
}
from
'
rxjs
'
;
import
{
UserService
}
from
'
../user.service
'
;
import
{
IdpService
}
from
'
../idp.service
'
;
import
{
DialogService
}
from
'
../dialogues/dialog.service
'
;
import
{
ProfileDialogService
}
from
'
../dialogues/profile-dialog.service
'
;
import
{
IdP
}
from
'
../types/types.module
'
;
...
...
@@ -15,19 +14,24 @@ import { IdP } from '../types/types.module';
})
export
class
HeaderComponent
implements
OnInit
{
public
idps$
:
Observable
<
IdP
[]
>
;
public
selectedIdP$
:
Observable
<
IdP
>
;
selected
:
IdP
;
constructor
(
private
idpService
:
IdpService
,
public
dialog
:
DialogService
,
public
profileDialog
:
ProfileDialogService
,
public
userService
:
UserService
,
)
{
this
.
idps$
=
this
.
idpService
.
subscribeIdps
();
this
.
selectedIdP$
=
this
.
idpService
.
subscribeSelectedIdp
();
}
ngOnInit
()
{
this
.
userService
.
connectIdPInfo
().
subscribe
(
info
=>
{
this
.
selected
=
info
.
selectedIdP
;
}
);
}
idpCompare
(
a
:
IdP
,
b
:
IdP
):
boolean
{
return
a
!=
undefined
&&
b
!=
undefined
&&
a
.
id
==
b
.
id
;
}
}
src/app/idp.service.ts
deleted
100644 → 0
View file @
5170363d
import
{
Injectable
}
from
'
@angular/core
'
;
import
{
HttpClient
}
from
'
@angular/common/http
'
;
import
{
Observable
,
BehaviorSubject
}
from
'
rxjs
'
;
import
{
CookieService
}
from
'
ngx-cookie-service
'
;
import
{
environment
}
from
'
../environments/environment
'
;
import
{
IdP
,
AuthInfo
}
from
'
./types/types.module
'
;
@
Injectable
({
providedIn
:
'
root
'
})
export
class
IdpService
{
idps
:
IdP
[];
idps$
:
BehaviorSubject
<
IdP
[]
>
;
selectedIdp
:
IdP
;
selectedIdp$
:
BehaviorSubject
<
IdP
>
;
constructor
(
public
http
:
HttpClient
,
public
cookieService
:
CookieService
,
)
{
this
.
initializeDataService
();
}
private
initializeDataService
()
{
if
(
!
this
.
idps$
)
{
this
.
idps$
=
<
BehaviorSubject
<
IdP
[]
>>
new
BehaviorSubject
(
undefined
);
}
if
(
!
this
.
selectedIdp$
)
{
this
.
selectedIdp$
=
<
BehaviorSubject
<
IdP
>>
new
BehaviorSubject
(
undefined
);
}
this
.
apiCall
();
}
private
apiCall
():
void
{
// initialize the subject with data
this
.
http
.
get
(
'
/backend/auth/v1/info
'
).
subscribe
(
(
info
:
AuthInfo
)
=>
{
this
.
idps
=
info
.
idps
;
this
.
idps$
.
next
(
this
.
idps
);
let
preferredIdP
:
IdP
=
this
.
idps
.
find
((
idp
:
IdP
)
=>
idp
.
id
===
this
.
getIdPPreference
());
let
defaultIdP
:
IdP
=
this
.
idps
.
find
((
idp
:
IdP
)
=>
idp
.
id
===
info
.
default
);
if
(
preferredIdP
)
{
this
.
selectedIdp
=
preferredIdP
;
}
else
if
(
defaultIdP
)
{
this
.
selectedIdp
=
defaultIdP
;
}
else
if
(
this
.
idps
.
length
>
0
)
{
this
.
selectedIdp
=
this
.
idps
[
0
];
}
else
{
console
.
log
(
"
No IdPs available. Unable to login
"
);
}
this
.
selectedIdp$
.
next
(
this
.
selectedIdp
);
}
);
}
private
getIdPPreference
():
number
{
return
Number
(
this
.
cookieService
.
get
(
environment
.
idpCookieName
));
}
public
subscribeIdps
():
Observable
<
IdP
[]
>
{
return
this
.
idps$
.
asObservable
();
}
public
subscribeSelectedIdp
():
Observable
<
IdP
>
{
return
this
.
selectedIdp$
.
asObservable
();
}
public
setIdPPreference
(
idp
:
IdP
)
{
this
.
cookieService
.
set
(
environment
.
idpCookieName
,
String
(
idp
.
id
));
}
}
src/app/preferences/preferences.service.ts
View file @
b27c7d04
import
{
Injectable
}
from
'
@angular/core
'
;
import
{
BehaviorSubject
,
Observable
}
from
'
rxjs
'
;
import
{
IdP
}
from
'
../types/types.module
'
;
export
const
prefsKey
=
"
feudalPrefs
"
;
export
interface
Prefs
{
showEmptyVOs
?:
boolean
;
preferredIdP
?:
IdP
;
};
@
Injectable
({
...
...
@@ -20,16 +23,25 @@ export class PreferencesService {
}
public
save
(
prefs
:
Prefs
):
void
{
console
.
log
(
"
Saved prefs:
"
,
prefs
);
localStorage
.
setItem
(
prefsKey
,
JSON
.
stringify
(
prefs
));
console
.
log
(
"
Saved preferences:
"
,
prefs
);
}
public
load
():
void
{
this
.
prefs
=
JSON
.
parse
(
localStorage
.
getItem
(
prefsKey
));
if
(
this
.
prefs
!=
null
&&
this
.
prefs
!=
undefined
)
{
this
.
prefs$
.
next
(
this
.
prefs
);
const
loaded
=
JSON
.
parse
(
localStorage
.
getItem
(
prefsKey
));
if
(
loaded
!=
null
)
{
this
.
prefs
=
loaded
;
this
.
prefs$
.
next
(
loaded
);
console
.
log
(
"
Loaded preferences:
"
,
this
.
prefs
);
}
else
{
console
.
log
(
"
No preferences to load
"
);
}
}
console
.
log
(
"
Loaded prefs:
"
,
this
.
prefs
);
public
setPreferredIdP
(
idp
:
IdP
):
void
{
this
.
prefs
.
preferredIdP
=
idp
;
this
.
save
(
this
.
prefs
);
this
.
prefs$
.
next
(
this
.
prefs
);
}
public
connect
():
Observable
<
Prefs
>
{
...
...
src/app/types/types.module.ts
View file @
b27c7d04
...
...
@@ -6,9 +6,11 @@ import { CommonModule } from '@angular/common';
export
interface
IdP
{
id
:
number
;
name
:
string
;
issuer_uri
:
string
;
}
export
interface
AuthInfo
{
export
interface
IdPInfo
{
selectedIdP
?:
IdP
;
idps
:
IdP
[];
default
:
number
;
}
...
...
src/app/user.service.ts
View file @
b27c7d04
import
{
Injectable
}
from
'
@angular/core
'
;
import
{
HttpClient
,
HttpErrorResponse
}
from
'
@angular/common/http
'
;
import
{
throwError
as
observableThrowError
,
Observable
,
BehaviorSubject
,
of
,
EMPTY
}
from
'
rxjs
'
;
import
{
Observable
,
BehaviorSubject
,
AsyncSubject
,
throwError
as
observableThrowError
,
of
,
EMPTY
}
from
'
rxjs
'
;
import
{
map
,
catchError
,
combineLatest
,
tap
}
from
'
rxjs/operators
'
;
import
{
CookieService
}
from
'
ngx-cookie-service
'
;
...
...
@@ -9,11 +8,10 @@ import { StompConfig, StompRService } from '@stomp/ng2-stompjs';
import
{
Message
}
from
'
@stomp/stompjs
'
;
import
{
SnackBarService
}
from
'
./snackbar.service
'
;
import
{
IdpService
}
from
'
./idp.service
'
;
import
{
PreferencesService
,
Prefs
}
from
'
./preferences/preferences.service
'
;
import
{
VO
,
User
,
Update
,
State
,
Deployment
,
DeploymentState
,
SSHKey
,
NewSSHKey
,
IdP
,
Service
,
Site
,
JSONObject
VO
,
User
,
Update
,
State
,
Deployment
,
DeploymentState
,
SSHKey
,
NewSSHKey
,
IdP
,
Service
,
Site
,
JSONObject
,
IdPInfo
}
from
'
./types/types.module
'
;
export
interface
Combination
{
...
...
@@ -26,7 +24,9 @@ export class UserService {
private
initialized
=
false
;
private
loggedIn
=
false
;
private
observerDebugging
=
true
;
private
idpInfo
:
AsyncSubject
<
IdPInfo
>
=
new
AsyncSubject
();
private
observerDebugging
=
false
;
// relogin on failed XHR calls
// is turned off when the user is deactivated
...
...
@@ -52,7 +52,6 @@ export class UserService {
private
cookieService
:
CookieService
,
private
http
:
HttpClient
,
private
snackBar
:
SnackBarService
,
private
idpService
:
IdpService
,
private
stompService
:
StompRService
,
private
prefs
:
PreferencesService
,
)
{
...
...
@@ -62,6 +61,7 @@ export class UserService {
// PRIVATE API
private
connect
():
void
{
this
.
fetch
();
this
.
fetchIdPInfo
();
this
.
userSrc
().
subscribe
(
(
newUser
:
User
)
=>
{
...
...
@@ -255,18 +255,68 @@ export class UserService {
private
tapLogger
(
name
:
string
):
(
e
:
any
)
=>
void
{
return
e
=>
{
if
(
this
.
observerDebugging
)
{
if
(
name
===
'
userSrc
'
)
{
this
.
userEmissions
++
;
console
.
log
(
name
,
this
.
userEmissions
,
e
);
}
else
{
console
.
log
(
name
,
e
);
}
}
}
}
private
fetchIdPInfo
():
void
{
this
.
http
.
get
<
IdPInfo
>
(
'
/backend/auth/v1/info
'
).
subscribe
(
idpInfo
=>
{
this
.
idpInfo
.
next
(
idpInfo
);
this
.
idpInfo
.
complete
();
}
);
}
// PUBLIC API
public
connectIdPInfo
():
Observable
<
IdPInfo
>
{
return
this
.
idpInfo
.
asObservable
().
pipe
(
combineLatest
(
this
.
prefs
.
connect
(),
(
authInfo
,
prefs
)
=>
{
const
defaultIdP
:
IdP
=
authInfo
.
idps
.
find
((
idp
:
IdP
)
=>
idp
.
id
===
authInfo
.
default
);
if
(
prefs
!=
undefined
&&
prefs
.
preferredIdP
!=
undefined
)
{
authInfo
.
selectedIdP
=
prefs
.
preferredIdP
;
}
else
if
(
defaultIdP
)
{
authInfo
.
selectedIdP
=
defaultIdP
;
}
else
if
(
authInfo
.
idps
.
length
>
0
)
{
authInfo
.
selectedIdP
=
authInfo
.
idps
[
0
];
}
else
{
console
.
log
(
"
No IdPs available. Unable to login
"
);
}
return
authInfo
;
},
),
);
}
public
login
(
idp
?:
IdP
):
void
{
if
(
idp
)
{
this
.
idpService
.
setIdPPreference
(
idp
);
const
redirect
=
(
idp
:
IdP
)
=>
{
window
.
location
.
href
=
'
/?idp=
'
+
encodeURIComponent
(
idp
.
issuer_uri
);
};
if
(
idp
!=
undefined
)
{
this
.
prefs
.
setPreferredIdP
(
idp
);
redirect
(
idp
);
}
else
{
this
.
prefs
.
connect
().
subscribe
(
prefs
=>
{
if
(
prefs
.
preferredIdP
!=
undefined
)
{
redirect
(
prefs
.
preferredIdP
);
}
}
)
}
window
.
location
.
href
=
'
/backend/auth/v1/request
'
;
console
.
log
(
'
Unable to login: No IdP
'
)
;
}
public
logout
():
void
{
...
...
src/styles.css
View file @
b27c7d04
...
...
@@ -105,6 +105,10 @@ mat-checkbox {
margin-right
:
15px
;
}
.mat-form-field-infix
{
width
:
220px
!important
;
}
.scrolling-dialog
.mat-dialog-container
{
margin
:
70px
0px
6px
0px
;
height
:
unset
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment