Commit a5296f10 authored by henrik.prangel's avatar henrik.prangel
Browse files

JUT-81 & JUT-82 Add new user authorities for client support and data scientist

parent 3a5be07d
<?xml version="1.0" encoding="utf-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.9.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<!--
Added new roles
-->
<changeSet id="20201014152000-1" author="henrik_prangel">
<loadData
file="config/liquibase/data/scientist_and_support_authority.csv"
separator=";"
tableName="jhi_authority">
<column name="name" type="string"/>
</loadData>
</changeSet>
</databaseChangeLog>
......@@ -22,6 +22,7 @@
<include file="config/liquibase/changelog/20200805134015_added_entity_constraints_Feedback.xml" relativeToChangelogFile="false"/>
<include file="config/liquibase/changelog/20200928092200_added_new_user_and_roles.xml" relativeToChangelogFile="false"/>
<include file="config/liquibase/changelog/20200928151500_added_commitment_fields.xml" relativeToChangelogFile="false"/>
<include file="config/liquibase/changelog/20201014152000_created_new_user_roles.xml" relativeToChangelogFile="false"/>
<!-- jhipster-needle-liquibase-add-constraints-changelog - JHipster will add liquibase constraints changelogs here -->
<!-- jhipster-needle-liquibase-add-incremental-changelog - JHipster will add incremental liquibase changelogs here -->
</databaseChangeLog>
......@@ -9,6 +9,10 @@ export const SERVER_API_URL = process.env.SERVER_API_URL;
export const AUTHORITIES = {
ADMIN: 'ROLE_ADMIN',
USER: 'ROLE_USER',
PPA_USER: "ROLE_PPA",
RIA_USER: "ROLE_RIA",
CUSTOMER_SUPPORT: "ROLE_CUSTOMER_SUPPORT",
DATA_SCIENTIST: "ROLE_DATA_SCIENTIST"
};
export const messages = {
......
......@@ -11,7 +11,7 @@ import { ACTION_TYPES as AUTH_ACTIONS } from 'app/shared/reducers/authentication
import { SUCCESS, FAILURE } from 'app/shared/reducers/action-type.util';
import { BOT_NAMES, REMOVE_CHAT, USER_HAS_LEFT } from 'app/shared/util/customer-service.constants';
import { USER_ROLES } from "app/modules/administration/user-management/user-management.reducer";
import { AUTHORITIES } from "app/config/constants";
let stompClient = null;
......@@ -46,7 +46,7 @@ const subscribe = (actionPayloadData) => {
});
subscribers.push(trackerSubscriber);
if (actionPayloadData.authorities.includes(USER_ROLES.RIA)) {
if (actionPayloadData.authorities.includes(AUTHORITIES.RIA_USER)) {
const riaSubscriber = stompClient.subscribe(`/topic/admin/${BOT_NAMES.RIA}`, data => {
listenerObserver.next(JSON.parse(data.body));
});
......@@ -54,7 +54,7 @@ const subscribe = (actionPayloadData) => {
subscribers.push(riaSubscriber);
}
if (actionPayloadData.authorities.includes(USER_ROLES.PPA)) {
if (actionPayloadData.authorities.includes(AUTHORITIES.PPA_USER)) {
const ppaSubscriber = stompClient.subscribe(`/topic/admin/${BOT_NAMES.PPA}`, data => {
listenerObserver.next(JSON.parse(data.body));
});
......
......@@ -14,11 +14,6 @@ export const ACTION_TYPES = {
RESET: 'userManagement/RESET',
};
export const USER_ROLES = {
PPA: "ROLE_PPA",
RIA: "ROLE_RIA"
}
const initialState = {
loading: false,
errorMessage: null,
......
......@@ -8,11 +8,12 @@ import { setActiveChat, updateChat, startConversation } from "app/modules/custom
import { VISIBILITY_STATES } from "app/modules/customer-service/chats/customer-service-chat.reducer";
import { INSTITUTION_NAMES } from "app/modules/training-interface/training-interface.reducer";
import { BOT_NAMES, CHAT_INSTITUTION_CHANGED, REMOVE_CHAT } from "app/shared/util/customer-service.constants";
import { AUTHORITIES } from "app/config/constants";
export type IAdditionalContentProp = StateProps
export const AdditionalContent = (props: IAdditionalContentProp) => {
const {userLoginName, activeChat, authorFirstName, authorId} = props
const {userLoginName, activeChat, authorFirstName, userAuthorities, authorId} = props
const dispatch = useDispatch();
const history = useHistory();
const [chatAssignedToUser, setChatAssignedToUser] = useState(activeChat ? activeChat.committedAdmin === userLoginName : false)
......@@ -86,7 +87,9 @@ export const AdditionalContent = (props: IAdditionalContentProp) => {
</span>
<hr className="divider"/>
{activeChat.ended ? (
<Button className="room-button" onClick={() => history.push(`/training/labeling/${activeChat.id}`)}>
<Button disabled={!userAuthorities.includes(AUTHORITIES.DATA_SCIENTIST)}
className="room-button"
onClick={() => history.push(`/training/labeling/${activeChat.id}`)}>
<Translate contentKey="customerService.additionalContent.label">Label</Translate>
</Button>
) : (
......@@ -139,6 +142,7 @@ const mapStateToProps = storeState => {
activeChat: storeState.customerService.chats.activeChat,
authorId: storeState.authentication.account.id,
authorFirstName: storeState.authentication.account.firstName,
userAuthorities: storeState.authentication.account.authorities,
};
}
......
import axios from 'axios';
import { FAILURE, REQUEST, SUCCESS } from 'app/shared/reducers/action-type.util';
import { USER_ROLES } from "app/modules/administration/user-management/user-management.reducer";
import { INSTITUTION_NAMES } from "app/modules/training-interface/training-interface.reducer";
import { AUTHORITIES } from "app/config/constants";
export const ACTION_TYPES = {
FETCH_NLU_FILE: 'intents/FETCH_NLU_FILE',
......@@ -86,7 +86,7 @@ export default (state: IntentsState = initialState, action): IntentsState => {
}
};
const getBotUrlByUserRole = (userRoles, specifier) => {
const getBotUrlByUserAuthorities = (userAuthorities, specifier) => {
let botUrls;
if(process.env.NODE_ENV === "development") {
......@@ -102,10 +102,10 @@ const getBotUrlByUserRole = (userRoles, specifier) => {
}
}
if (userRoles.includes(USER_ROLES.PPA)) {
if (userAuthorities.includes(AUTHORITIES.PPA_USER)) {
return `${botUrls.PPA_BOT_DOMAIN}/files/${specifier}/${INSTITUTION_NAMES.PPA}`
}
if (userRoles.includes(USER_ROLES.RIA)) {
if (userAuthorities.includes(AUTHORITIES.RIA_USER)) {
return `${process.env.RIA_BOT_DOMAIN}/files/${specifier}/${INSTITUTION_NAMES.RIA}`
}
return null
......@@ -113,8 +113,8 @@ const getBotUrlByUserRole = (userRoles, specifier) => {
// Actions
export const getFile = (userRoles, fileType, callback) => async dispatch => {
const requestUrl = getBotUrlByUserRole(userRoles, fileType);
export const getFile = (userAuthorities, fileType, callback) => async dispatch => {
const requestUrl = getBotUrlByUserAuthorities(userAuthorities, fileType);
let actionType
switch (fileType) {
......@@ -136,8 +136,8 @@ export const getFile = (userRoles, fileType, callback) => async dispatch => {
});
};
export const getIntentsList = userRoles => async dispatch => {
const requestUrl = getBotUrlByUserRole(userRoles, "intents");
export const getIntentsList = userAuthorities => async dispatch => {
const requestUrl = getBotUrlByUserAuthorities(userAuthorities, "intents");
return await dispatch({
type: ACTION_TYPES.GET_INTENTS_LIST,
......@@ -145,19 +145,19 @@ export const getIntentsList = userRoles => async dispatch => {
});
};
export const postCurrentEditorFile = (userRoles, text, fileType) => {
export const postCurrentEditorFile = (userAuthorities, text, fileType) => {
// let requestUrl;
// let type;
// let payload
//
// switch (fileType) {
// case RASA_FILE_TYPES.STORIES:
// requestUrl = getBotUrlByUserRole(userRoles, fileType);
// requestUrl = getBotUrlByUserAuthorities(userAuthorities, fileType);
// type = ACTION_TYPES.UPDATE_STORIES_FILE;
// payload = axios.post(requestUrl, text, {headers: {['Content-Type']: 'text/plain'}})
// break
// case RASA_FILE_TYPES.NLU:
// requestUrl = getBotUrlByUserRole(userRoles, fileType);
// requestUrl = getBotUrlByUserAuthorities(userAuthorities, fileType);
// type = ACTION_TYPES.UPDATE_NLU_FILE
// payload = axios.post(requestUrl, text)
// break
......
......@@ -9,7 +9,7 @@ import '../training-interface.scss'
export type IIntentsProp = StateProps;
export const Intents = (props: IIntentsProp) => {
const {editorFile, userRoles} = props
const {editorFile, userAuthorities} = props
const [text, setText] = useState("")
const [newExample, setNewExample] = useState("")
const [activeIntent, setActiveIntent] = useState("")
......@@ -17,23 +17,23 @@ export const Intents = (props: IIntentsProp) => {
const dispatch = useDispatch();
const getNLUFile = () => {
dispatch(getFile(userRoles, RASA_FILE_TYPES.NLU, () => {
dispatch(getFile(userAuthorities, RASA_FILE_TYPES.NLU, () => {
setActiveIntent("")
setIntentExampleList([])
}))
}
const getStoriesFile = () => {
dispatch(getFile(userRoles, RASA_FILE_TYPES.STORIES, (value) => {
dispatch(getFile(userAuthorities, RASA_FILE_TYPES.STORIES, (value) => {
setText(value)
}))
}
const postCurrentlyOpenedFile = () => {
if (editorFile.type === RASA_FILE_TYPES.NLU) {
dispatch(postCurrentEditorFile(userRoles, editorFile.text, editorFile.type))
dispatch(postCurrentEditorFile(userAuthorities, editorFile.text, editorFile.type))
} else {
dispatch(postCurrentEditorFile(userRoles, text, editorFile.type))
dispatch(postCurrentEditorFile(userAuthorities, text, editorFile.type))
}
}
......@@ -153,7 +153,7 @@ export const Intents = (props: IIntentsProp) => {
const mapStateToProps = storeState => {
return {
editorFile: storeState.trainingInterface.intents.editorFile,
userRoles: storeState.authentication.account.authorities
userAuthorities: storeState.authentication.account.authorities
}
}
......
......@@ -9,12 +9,12 @@ import Avatar from "app/shared/common-components/avatar/avatar";
export interface ITrainingMessagesProp extends StateProps, RouteComponentProps<{ id: string }> {}
export const TrainingMessages = (props: ITrainingMessagesProp) => {
const {messages, activeLabelingChatId, expiredChats, userRoles, match} = props
const {messages, activeLabelingChatId, expiredChats, userAuthorities, match} = props
const dispatch = useDispatch();
const history = useHistory();
useEffect(() => {
dispatch(getIntentsList(userRoles))
dispatch(getIntentsList(userAuthorities))
}, [])
useEffect(() => {
......@@ -59,7 +59,7 @@ const mapStateToProps = storeState => {
expiredChats: storeState.trainingInterface.labeling.chats,
activeLabelingChatId: storeState.trainingInterface.labeling.activeLabelingChatId,
messages: storeState.trainingInterface.labeling.activeLabelingChatMessages,
userRoles: storeState.authentication.account.authorities,
userAuthorities: storeState.authentication.account.authorities,
}
}
......
......@@ -38,10 +38,10 @@ const Routes = () => (
<ErrorBoundaryRoute path="/account/reset/finish/:key?" component={PasswordResetFinish} />
<PrivateRoute path="/admin" component={Admin} hasAnyAuthorities={[AUTHORITIES.ADMIN]} />
<PrivateRoute path="/account" component={Account} hasAnyAuthorities={[AUTHORITIES.ADMIN, AUTHORITIES.USER]} />
<PrivateRoute path="/entities" component={Entities} hasAnyAuthorities={[AUTHORITIES.USER]} />
<PrivateRoute path="/training" component={TrainingInterface} hasAnyAuthorities={[AUTHORITIES.ADMIN]} />
<PrivateRoute path="/chats" component={CustomerService} hasAnyAuthorities={[AUTHORITIES.ADMIN]} />
<PrivateRoute path="/home" component={Home} hasAnyAuthorities={[AUTHORITIES.ADMIN]} />
<PrivateRoute path="/entities" component={Entities} hasAnyAuthorities={[AUTHORITIES.ADMIN]} />
<PrivateRoute path="/training" component={TrainingInterface} hasAnyAuthorities={[AUTHORITIES.ADMIN, AUTHORITIES.DATA_SCIENTIST]} />
<PrivateRoute path="/chats" component={CustomerService} hasAnyAuthorities={[AUTHORITIES.ADMIN, AUTHORITIES.CUSTOMER_SUPPORT]} />
<PrivateRoute path="/home" component={Home} hasAnyAuthorities={[AUTHORITIES.USER]} />
<Redirect path="/" to={"/home"}/>
<ErrorBoundaryRoute component={PageNotFound} />
</Switch>
......
......@@ -54,7 +54,7 @@ const Header = (props: IHeaderProps) => {
<Nav id="header-tabs" className="ml-auto" navbar>
<Home />
<Train />
{props.isAuthenticated && <EntitiesMenu />}
{props.isAuthenticated && props.isAdmin && <EntitiesMenu />}
{props.isAuthenticated && props.isAdmin && <AdminMenu showSwagger={props.isSwaggerEnabled} />}
<LocaleMenu currentLocale={props.currentLocale} onClick={handleLocaleChange} />
<AccountMenu isAuthenticated={props.isAuthenticated} />
......
......@@ -94,7 +94,7 @@ describe('Header', () => {
it('Renders a Header component in prod profile with logged in User', () => {
const nav = wrapper(userProps).find(Nav);
expect(nav.find(AdminMenu).length).toEqual(0);
expect(nav.find(EntitiesMenu).length).toEqual(1);
expect(nav.find(EntitiesMenu).length).toEqual(0);
const account = nav.find(AccountMenu);
expect(account.first().props().isAuthenticated).toEqual(true);
});
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment