Skip to content

Commit 1cad542

Browse files
thquadrichard-cox
authored andcommitted
Admins can create personal endpoints (#4876)
Signed-off-by: Thomas Quandt <[email protected]>
1 parent 18add26 commit 1cad542

File tree

8 files changed

+36
-44
lines changed

8 files changed

+36
-44
lines changed

src/frontend/packages/core/src/features/endpoints/create-endpoint/create-endpoint-cf-step-1/create-endpoint-cf-step-1.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
<h1 class="create-endpoint__section-title">{{endpoint.definition.label}} Information</h1>
33
<mat-form-field>
44
<input matInput id="name" name="name" formControlName="nameField" placeholder="Name"
5-
[appUnique]="(customEndpoints | async)?.names">
5+
[appUnique]="registerForm.value.createUserEndpointField ? (existingPersonalEndpoints | async)?.names : (customEndpoints | async)?.names">
66
<mat-error *ngIf="registerForm.controls.nameField.errors?.required">Name is required</mat-error>
77
<mat-error *ngIf="registerForm.controls.nameField.errors?.appUnique">Name is not unique</mat-error>
88
</mat-form-field>
99
<mat-form-field novalidate>
1010
<input matInput id="url" name="url" formControlName="urlField" type="url" required placeholder="Endpoint Address"
1111
pattern="{{urlValidation}}"
12-
[appUnique]="(customEndpoints | async)?.urls">
12+
[appUnique]="registerForm.value.createUserEndpointField ? (existingPersonalEndpoints | async)?.urls : (customEndpoints | async)?.urls">
1313
<mat-error *ngIf="registerForm.controls.urlField.errors?.required">URL is required</mat-error>
1414
<mat-error *ngIf="registerForm.controls.urlField.errors?.pattern">Invalid API URL</mat-error>
1515
<mat-error *ngIf="registerForm.controls.urlField.errors?.appUnique">URL is not unique</mat-error>

src/frontend/packages/core/src/features/endpoints/create-endpoint/create-endpoint-helper.ts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,28 @@ export class CreateEndpointHelperComponent {
1616

1717
userEndpointsAndIsAdmin: Observable<boolean>;
1818
customEndpoints: EndpointObservable;
19+
existingSystemEndpoints: EndpointObservable;
20+
existingPersonalEndpoints: EndpointObservable;
21+
existingEndpoints: EndpointObservable;
1922

2023
constructor(
2124
public sessionService: SessionService,
2225
public currentUserPermissionsService: CurrentUserPermissionsService
2326
) {
2427
const currentPage$ = stratosEntityCatalog.endpoint.store.getAll.getPaginationMonitor().currentPage$;
25-
const existingAdminEndpoints = currentPage$.pipe(
28+
this.existingSystemEndpoints = currentPage$.pipe(
2629
map(endpoints => ({
27-
names: endpoints.filter(ep => ep.creator.admin).map(ep => ep.name),
28-
urls: endpoints.filter(ep => ep.creator.admin).map(ep => getFullEndpointApiUrl(ep)),
30+
names: endpoints.filter(ep => ep.creator.system).map(ep => ep.name),
31+
urls: endpoints.filter(ep => ep.creator.system).map(ep => getFullEndpointApiUrl(ep)),
2932
}))
3033
);
31-
const existingUserEndpoints = currentPage$.pipe(
34+
this.existingPersonalEndpoints = currentPage$.pipe(
3235
map(endpoints => ({
33-
names: endpoints.filter(ep => !ep.creator.admin).map(ep => ep.name),
34-
urls: endpoints.filter(ep => !ep.creator.admin).map(ep => getFullEndpointApiUrl(ep)),
36+
names: endpoints.filter(ep => !ep.creator.system).map(ep => ep.name),
37+
urls: endpoints.filter(ep => !ep.creator.system).map(ep => getFullEndpointApiUrl(ep)),
3538
}))
3639
);
37-
const existingEndpoints = currentPage$.pipe(
40+
this.existingEndpoints = currentPage$.pipe(
3841
map(endpoints => ({
3942
names: endpoints.map(ep => ep.name),
4043
urls: endpoints.map(ep => getFullEndpointApiUrl(ep)),
@@ -54,16 +57,16 @@ export class CreateEndpointHelperComponent {
5457
this.customEndpoints = combineLatest([
5558
userEndpointsNotDisabled,
5659
isAdmin,
57-
existingEndpoints,
58-
existingAdminEndpoints,
59-
existingUserEndpoints
60+
this.existingEndpoints,
61+
this.existingSystemEndpoints,
62+
this.existingPersonalEndpoints
6063
]).pipe(
61-
map(([userEndpointsEnabled, admin, endpoints, adminEndpoints, userEndpoints]) => {
64+
map(([userEndpointsEnabled, admin, endpoints, systemEndpoints, personalEndpoints]) => {
6265
if (userEndpointsEnabled){
6366
if (admin){
64-
return adminEndpoints;
67+
return systemEndpoints;
6568
}else{
66-
return userEndpoints;
69+
return personalEndpoints;
6770
}
6871
}
6972
return endpoints;

src/frontend/packages/core/src/shared/components/list/list-types/endpoint/base-endpoints-data-source.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ export class BaseEndpointsDataSource extends ListDataSource<EndpointModel> {
125125
sso_allowed: false,
126126
creator: {
127127
name: '',
128-
admin: false
128+
admin: false,
129+
system: false
129130
}
130131
}),
131132
paginationKey: action.paginationKey,

src/frontend/packages/git/src/shared/components/git-registration/git-registration.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ <h3>Select the type of {{gitTypes[epSubType].label}} to register</h3>
1919
<div *ngIf="showEndpointFields" class="select-step__endpoint-form">
2020
<mat-form-field>
2121
<input matInput id="name" name="name" formControlName="nameField" placeholder="Name"
22-
[appUnique]="(customEndpoints | async)?.names">
22+
[appUnique]="registerForm.value.createUserEndpointField ? (existingPersonalEndpoints | async)?.names : (customEndpoints | async)?.names">
2323
<mat-error *ngIf="registerForm.controls.nameField.errors?.required">Name is required</mat-error>
2424
<mat-error *ngIf="registerForm.controls.nameField.errors?.appUnique">Name is not unique</mat-error>
2525
</mat-form-field>
2626
<mat-form-field novalidate>
2727
<input matInput id="url" name="url" formControlName="urlField" type="url" required
2828
placeholder="Endpoint Address" pattern="{{urlValidation}}"
29-
[appUnique]="(customEndpoints | async)?.urls">
29+
[appUnique]="registerForm.value.createUserEndpointField ? (existingPersonalEndpoints | async)?.urls : (customEndpoints | async)?.urls">
3030
<mat-error *ngIf="registerForm.controls.urlField.errors?.required">URL is required</mat-error>
3131
<mat-error *ngIf="registerForm.controls.urlField.errors?.pattern">Invalid API URL</mat-error>
3232
<mat-error *ngIf="registerForm.controls.urlField.errors?.appUnique">URL is not unique</mat-error>

src/frontend/packages/store/src/types/endpoint.types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ export interface EndpointUser {
6868
export interface CreatorInfo {
6969
name: string;
7070
admin: boolean;
71+
system: boolean;
7172
}
7273

7374
export interface EndpointState {

src/jetstream/cnsi.go

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ func (p *portalProxy) DoRegisterEndpoint(cnsiName string, apiEndpoint string, sk
150150
// check if we've already got this APIEndpoint in this DB
151151
for _, duplicate := range duplicateEndpoints {
152152
// cant create same system endpoint
153-
if len(duplicate.Creator) == 0 && isAdmin {
153+
if len(duplicate.Creator) == 0 && isAdmin && !createUserEndpoint {
154154
return interfaces.CNSIRecord{}, interfaces.NewHTTPShadowError(
155155
http.StatusBadRequest,
156156
"Can not register same system endpoint multiple times",
@@ -159,7 +159,6 @@ func (p *portalProxy) DoRegisterEndpoint(cnsiName string, apiEndpoint string, sk
159159
}
160160

161161
// cant create same user endpoint
162-
// can create same user endpoint if overwriteEndpoint true
163162
if duplicate.Creator == userId {
164163
return interfaces.CNSIRecord{}, interfaces.NewHTTPShadowError(
165164
http.StatusBadRequest,
@@ -168,28 +167,11 @@ func (p *portalProxy) DoRegisterEndpoint(cnsiName string, apiEndpoint string, sk
168167
)
169168
}
170169
}
171-
172-
/*
173-
if isAdmin && overwriteEndpoints {
174-
for _, duplicate := range duplicateEndpoints {
175-
log.Infof("An administrator is registering an endpoint with the same API URL ('%+v') as an endpoint administrator's. The existing duplicate endpoint ('%+v') will be removed", apiEndpoint, duplicate.GUID)
176-
err := p.doUnregisterCluster(duplicate.GUID)
177-
if err != nil {
178-
return interfaces.CNSIRecord{}, interfaces.NewHTTPShadowError(
179-
http.StatusInternalServerError,
180-
"Failed to unregister cluster",
181-
"Failed to unregister cluster: %v",
182-
err)
183-
}
184-
}
185-
}
186-
*/
187-
188170
}
189171

190172
h := sha1.New()
191173
// see why its generated this way in Issue #4753 / #3031
192-
if p.GetConfig().UserEndpointsEnabled != config.UserEndpointsConfigEnum.Disabled && !isAdmin {
174+
if p.GetConfig().UserEndpointsEnabled != config.UserEndpointsConfigEnum.Disabled && (!isAdmin || createUserEndpoint) {
193175
// Make the new guid unique per api url AND user id
194176
h.Write([]byte(apiEndpointURL.String() + userId))
195177
} else {
@@ -222,7 +204,7 @@ func (p *portalProxy) DoRegisterEndpoint(cnsiName string, apiEndpoint string, sk
222204
newCNSI.SubType = subType
223205

224206
// admins currently can't create user endpoints
225-
if p.GetConfig().UserEndpointsEnabled != config.UserEndpointsConfigEnum.Disabled && !isAdmin {
207+
if p.GetConfig().UserEndpointsEnabled != config.UserEndpointsConfigEnum.Disabled && (!isAdmin || createUserEndpoint) {
226208
newCNSI.Creator = userId
227209
}
228210

src/jetstream/info.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,18 +102,22 @@ func (p *portalProxy) getInfo(c echo.Context) (*interfaces.Info, error) {
102102

103103
// set the creator preemptively as admin, if no id is found
104104
endpoint.Creator = &interfaces.CreatorInfo{
105-
Name: "admin",
106-
Admin: true,
105+
Name: "system",
106+
Admin: false,
107+
System: true,
107108
}
108109

109110
// assume it's a user when len != 0
110111
if len(cnsi.Creator) != 0 {
111-
endpoint.Creator.Admin = false
112+
endpoint.Creator.System = false
112113
u, err := p.StratosAuthService.GetUser(cnsi.Creator)
114+
// add an anonymous user if no user is found
113115
if err != nil {
114116
endpoint.Creator.Name = "user"
117+
endpoint.Creator.Admin = false
115118
} else {
116119
endpoint.Creator.Name = u.Name
120+
endpoint.Creator.Admin = u.Admin
117121
}
118122
}
119123

src/jetstream/repository/interfaces/structs.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,9 @@ type ConnectedUser struct {
195195

196196
// CreatorInfo - additional information about the user who created an endpoint
197197
type CreatorInfo struct {
198-
Name string `json:"name"`
199-
Admin bool `json:"admin"`
198+
Name string `json:"name"`
199+
Admin bool `json:"admin"`
200+
System bool `json:"system"`
200201
}
201202

202203
type JWTUserTokenInfo struct {

0 commit comments

Comments
 (0)