Skip to content

Commit aa3bf1d

Browse files
committed
Enable role based admin access
1 parent 21fb7c0 commit aa3bf1d

File tree

9 files changed

+144
-61
lines changed

9 files changed

+144
-61
lines changed

public/api/swagger.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4257,6 +4257,8 @@ definitions:
42574257
properties:
42584258
token:
42594259
type: string
4260+
roles:
4261+
type: string
42604262
AdminRole:
42614263
type: boolean
42624264
x-omitempty: false

src/adabas/admin.ts

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -187,42 +187,39 @@ export class AdabasAdmin {
187187
headers: authHeader("application/json"),
188188
useCredentails: true,
189189
};
190-
try {
191190
return axios
192191
.put(config.Url() + "/adabas/database/"
193-
+ this.status.Dbid + "?name=" + newName, {}, getConfig);
194-
}
195-
catch (error) {
192+
+ this.status.Dbid + "?name=" + newName, {}, getConfig)
193+
.catch((error:any) => {
196194
if (error.response) {
197195
if (error.response.status == 401 || error.response.status == 403) {
198196
userService.logout();
199197
location.reload(true);
200198
}
201199
}
202200
throw error;
203-
}
201+
});
204202
}
205203
// Adabas file number can be renumbered
206204
async renumberFile(file: number, newNr: string): Promise<any> {
207205
const getConfig = {
208206
headers: authHeader("application/json"),
209207
useCredentails: true,
210208
};
211-
try {
212-
return axios
213-
.put(config.Url() + "/adabas/database/"
209+
return axios
210+
.put(config.Url() + "/adabas/database/"
214211
+ this.status.Dbid + "/file/" + file
215-
+ ":renumber?number=" + newNr, {}, getConfig);
216-
}
217-
catch (error) {
212+
+ ":renumber?number=" + newNr, {}, getConfig)
213+
.catch ((error: any) => {
214+
console.log("E: "+JSON.stringify(error));
218215
if (error.response) {
219216
if (error.response.status == 401 || error.response.status == 403) {
220217
userService.logout();
221218
location.reload(true);
222219
}
223220
}
224221
throw error;
225-
}
222+
});
226223
}
227224
// Refresh content of a given Adabas file number (attention: data is lost)!!!
228225
async refreshFile(file: number): Promise<any> {

src/components/DatabaseInfos.vue

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
<template>
1717
<div class="databaseinfos p-2">
18+
<ErrorModal />
1819
<div class="card">
1920
<div class="card-header h5">Adabas Database information</div>
2021
<div class="card-body">
@@ -46,7 +47,6 @@
4647
</b-modal>
4748
<b-table
4849
class="w-100 p-3"
49-
5050
striped
5151
bordered
5252
hover
@@ -66,12 +66,14 @@ import Sidebar from "./Sidebar.vue";
6666
import StatusBar from "./StatusBar.vue";
6767
import store from "../store/index";
6868
import Url from "./Url.vue";
69+
import ErrorModal from "@/components/ErrorModal.vue";
6970
7071
@Component({
7172
components: {
7273
Sidebar,
7374
StatusBar,
7475
Url,
76+
ErrorModal,
7577
},
7678
})
7779
export default class ParameterList extends Vue {
@@ -158,9 +160,22 @@ export default class ParameterList extends Vue {
158160
}
159161
renameDatabase(): void {
160162
if (this.$data.newName !== "") {
161-
this.$data.db.renameDatabase(this.$data.newName).then(()=> {
162-
this.queryInformation();
163-
});
163+
this.$data.db
164+
.renameDatabase(this.$data.newName)
165+
.then(() => {
166+
this.queryInformation();
167+
})
168+
.catch((error: any) => {
169+
let errorText = "unknown error to rename database";
170+
if (error.response !== undefined) {
171+
errorText =
172+
error.response.data.Error.code +
173+
": " +
174+
error.response.data.Error.message;
175+
}
176+
this.$root.$emit("errorMessage", errorText);
177+
this.$root.$emit("bv::show::modal", "modal-error", "#btnShow");
178+
});
164179
}
165180
this.$data.newName = "";
166181
}

src/components/ErrorModal.vue

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<!--
2+
* Copyright (c) 2020 Software AG (http://www.softwareag.com/)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.-->
15+
16+
<template>
17+
<div class="errormodal p-2">
18+
<b-modal id="modal-error" header-bg-variant="danger" title="Error..." ok-only>
19+
<div class="d-block">Problem: {{ error }}</div>
20+
</b-modal>
21+
</div>
22+
</template>
23+
24+
<script lang="ts">
25+
import { Component, Prop, Vue } from "vue-property-decorator";
26+
27+
@Component
28+
export default class ErrorModal extends Vue {
29+
@Prop() private msg!: string;
30+
data() {
31+
return {
32+
error: "xx",
33+
};
34+
}
35+
created() {
36+
this.$root.$on("errorMessage", (data: any) => {
37+
this.$data.error = data;
38+
});
39+
}
40+
}
41+
</script>
42+
43+
<!-- Add "scoped" attribute to limit CSS to this component only -->
44+
<style scoped lang="scss">
45+
h3 {
46+
margin: 40px 0 0;
47+
}
48+
ul {
49+
list-style-type: none;
50+
padding: 0;
51+
}
52+
li {
53+
display: inline-block;
54+
margin: 0 10px;
55+
}
56+
a {
57+
color: #42b983;
58+
}
59+
</style>

src/components/Header.vue

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333
<b-dropdown-item to="/metadata">Adabas Map Metadata</b-dropdown-item>
3434
<b-dropdown-item to="/modify">Modify record</b-dropdown-item>
3535
</b-nav-item-dropdown>
36-
<b-nav-item to="/databases">Database Administration</b-nav-item>
37-
<b-nav-item to="/jobs">Job list</b-nav-item>
36+
<b-nav-item :disabled="!isAdministrator" to="/databases">Database Administration</b-nav-item>
37+
<b-nav-item :disabled="!isAdministrator" to="/jobs">Job list</b-nav-item>
3838
</b-navbar-nav>
3939
<b-navbar-nav class="ml-auto" right>
4040
<b-nav-item target="_blank" href="/api/">Swagger API</b-nav-item>
@@ -54,7 +54,7 @@
5454
>Descriptor read</b-dropdown-item
5555
>
5656
</b-nav-item-dropdown>
57-
<b-nav-item v-on:click="logout">Logout</b-nav-item>
57+
<b-nav-item v-on:click="logout">Logout<br/>&lt;{{user}}&gt;</b-nav-item>
5858
</b-navbar-nav>
5959
</b-collapse>
6060
</b-navbar>
@@ -73,6 +73,7 @@ import {
7373
import "bootstrap/dist/css/bootstrap.css";
7474
import "bootstrap-vue/dist/bootstrap-vue.css";
7575
import { userService } from "../user/service";
76+
import { authHeader, adminRole } from '../user/auth-header';
7677
7778
Vue.use(NavbarPlugin);
7879
Vue.use(ButtonPlugin);
@@ -91,14 +92,14 @@ export default Vue.extend({
9192
name: "Header",
9293
data() {
9394
return {
95+
user: "",
96+
isAdministrator: false,
9497
checked: true,
9598
};
9699
},
97100
created() {
98-
// console.log("Created Header, read maps");
99-
// store.dispatch('INIT_MAPS');
100-
// console.log("Created Header, read databases");
101-
// store.dispatch('INIT_DATABASES');
101+
this.$data.isAdministrator = adminRole();
102+
this.$data.user = userService.getUsername()
102103
},
103104
methods: {
104105
logout() {

src/examples/ImageExample.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ export default class ImageExample extends Vue {
108108
],
109109
image: [],
110110
xURL:
111-
"/rest/map/LOBEXAMPLE?fields=Filename,Size,@Thumbnail,@Picture,Model,DateOriginal,EXIFinformation",
111+
"/rest/map/LOBEXAMPLE?fields=Filename,Size,@Thumbnail,@Picture,Model,DateOriginal,EXIFinformation&limit=0",
112112
};
113113
}
114114
created() {

src/store/config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ import Vue from 'vue';
2323
export function Url() {
2424
// console.log('Mode:' + process.env.NODE_ENV);
2525
if (process.env.NODE_ENV === 'development') {
26-
return 'http://localhost:8130'; // GO
27-
// return 'http://localhost:8091'; // Java
26+
// return 'http://localhost:8130'; // GO
27+
return 'http://localhost:8091'; // Java
2828
}
2929
return '.';
3030
}

src/user/auth-header.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,12 @@ export function adminRole() : boolean {
6565
return false;
6666
}
6767
const user = JSON.parse(x);
68-
return user.AdminRole;
68+
if (user.AdminRole!==undefined) {
69+
return user.AdminRole;
70+
}
71+
if (user.roles!==undefined) {
72+
const roles = user.roles.split(",");
73+
return roles.includes("aifadmin");
74+
}
75+
return false;
6976
}

src/user/service.ts

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,20 @@ function logout(): void {
2626
version();
2727
}
2828

29-
function handleResponse(response: Response) {
30-
return response.text().then((text: string) => {
31-
const data = text && JSON.parse(text);
32-
if (!response.ok) {
33-
if (response.status === 401 || response.status === 404) {
34-
// auto logout if 401 response returned from api
35-
logout();
36-
location.reload(true);
37-
}
38-
39-
const error = (data && data.message) || response.statusText;
40-
return Promise.reject(error);
29+
async function handleResponse(response: Response) {
30+
const text = await response.text();
31+
const data = text && JSON.parse(text);
32+
if (!response.ok) {
33+
if (response.status === 401 || response.status === 404) {
34+
// auto logout if 401 response returned from api
35+
logout();
36+
location.reload(true);
4137
}
42-
return data;
43-
});
38+
39+
const error = (data && data.message) || response.statusText;
40+
return Promise.reject(error);
41+
}
42+
return data;
4443
}
4544

4645
function handleVersionResponse(response: Response): Promise<Response>|any {
@@ -51,16 +50,18 @@ function handleVersionResponse(response: Response): Promise<Response>|any {
5150
return v;
5251
});
5352
}
54-
function version() {
53+
async function version() {
5554
const requestOptions = {
5655
method: 'GET',
5756
headers: { Accept: 'application/json' },
5857
};
5958

60-
return fetch(`${config.Url()}/version`, requestOptions).then(handleVersionResponse);
59+
const response = await fetch(`${config.Url()}/version`, requestOptions);
60+
return handleVersionResponse(response);
6161
}
6262

63-
function login(username: string, password: string): Promise<Response> {
63+
// call login with username and password
64+
async function login(username: string, password: string): Promise<Response> {
6465
const v = localStorage.getItem('version');
6566
if (v) {
6667
const version = JSON.parse(v).version;
@@ -70,25 +71,26 @@ function login(username: string, password: string): Promise<Response> {
7071
headers: authInitHeader(username, password),
7172
};
7273

73-
return fetch(`${config.Url()}/login`, requestOptions)
74-
.then(handleResponse)
75-
.then((user) => {
76-
// login successful if there's a user in the response
77-
if (user) {
78-
// store user details and basic auth credentials in local storage
79-
// to keep user logged in between page refreshes
80-
if (!user.token) {
81-
user.authdata = window.btoa(username + ':' + password);
82-
}
83-
user.username = username;
84-
localStorage.setItem('user', JSON.stringify(user));
85-
// console.log("Save user: " + JSON.stringify(user));
86-
}
87-
88-
return user;
89-
});
74+
const response = await fetch(`${config.Url()}/login`, requestOptions);
75+
const user = await handleResponse(response);
76+
// login successful if there's a user in the response
77+
if (user) {
78+
// store user details and basic auth credentials in local storage
79+
// to keep user logged in between page refreshes
80+
if (user.token===undefined) {
81+
user.authdata = window.btoa(username + ':' + password);
82+
}
83+
if (user.AdminRole===undefined) {
84+
user.AdminRole = true;
85+
}
86+
user.username = username;
87+
localStorage.setItem('user', JSON.stringify(user));
88+
// console.log("Save user: " + JSON.stringify(user));
89+
}
90+
return user;
9091
}
9192

93+
// get login user name
9294
function getUsername() {
9395
const x = localStorage.getItem('user');
9496
if (x === null) {

0 commit comments

Comments
 (0)