Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Session handling #865

Merged
merged 36 commits into from
Aug 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
5c16834
Allow to get the unix timestamp of the user session timeout
bjoernricks Aug 2, 2018
36ba11a
Allow to access user_renew_session from the outside of gsad_user.c
bjoernricks Aug 2, 2018
4b02c60
Don't renew the user session automatically
bjoernricks Aug 2, 2018
1bbc976
Don't crash if address is not defined
bjoernricks Aug 2, 2018
bb6746f
Add new gmp cmd api for renewing the user session
bjoernricks Aug 2, 2018
127ee9d
Allow to renew the users session via http post
bjoernricks Aug 2, 2018
ed5997c
Add gmp.user.renewSession() method
bjoernricks Aug 2, 2018
1e36289
Remove params from gsad response
bjoernricks Aug 9, 2018
8d5c6b7
Import moment from gmp/models/date
bjoernricks Aug 9, 2018
eda7c0e
Add session timeout in unix seconds to the envelope data
bjoernricks Aug 9, 2018
478c16b
Pass NULL als extra_xml at login function to envelope_gmp
bjoernricks Aug 9, 2018
a02dc3d
Always renew user session on post requests
bjoernricks Aug 9, 2018
23d8438
Allow to put the session timeout into the redux store
bjoernricks Aug 9, 2018
b6063cb
Use camelCase API in Login model
bjoernricks Aug 9, 2018
79d648e
Use locale instead of i18n in Login model
bjoernricks Aug 9, 2018
8cfa6bf
Add sessionTimeout to Login model
bjoernricks Aug 9, 2018
54aca9c
Return sessionTimeout from gmp.login
bjoernricks Aug 9, 2018
ba8dcbe
Only init timezone nd username if they are defined
bjoernricks Aug 9, 2018
ac6ecd3
Set sessionTimeout in redux store after login
bjoernricks Aug 9, 2018
5acbba1
Add a SessionObserver component
bjoernricks Aug 9, 2018
181bf39
Use SessionObserver to renew session after login
bjoernricks Aug 9, 2018
69af4e1
Add a renewSessionTimeout action creator function
bjoernricks Aug 10, 2018
60ce523
Use renewSessionTimeout action in SessionObserver
bjoernricks Aug 10, 2018
7074a9d
Pass renewSessionTimeout function to EntitesContainer
bjoernricks Aug 10, 2018
0d409bc
Improve debounce wait parameter documentation
bjoernricks Aug 10, 2018
8fe6c3f
Only renew user session if location has really changed
bjoernricks Aug 10, 2018
332e4ea
Renew the session after user interactions at list pages
bjoernricks Aug 10, 2018
ad7f322
Extract UserLink into an own js module
bjoernricks Aug 10, 2018
a0f74f4
Display session timeout at user link
bjoernricks Aug 10, 2018
eb4e407
Call gmp logout after redirect to login page
bjoernricks Aug 10, 2018
8faef91
Only refresh if timeout is greater then zero
bjoernricks Aug 10, 2018
8f3a5cc
Update to React 16.4 api
bjoernricks Aug 10, 2018
7e8bddb
Renew user session on dashboard changes
bjoernricks Aug 10, 2018
c8b0e8e
Renew user session if task dialogs are opened and closed
bjoernricks Aug 10, 2018
43508f4
Clear the token when redirecting to login page
bjoernricks Aug 10, 2018
fc72925
Renew session if entity data has changed
bjoernricks Aug 10, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions gsa/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ set (GSA_JS_SRC_FILES
${GSA_SRC_DIR}/src/web/components/link/manuallink.js
${GSA_SRC_DIR}/src/web/components/link/protocoldoclink.js
${GSA_SRC_DIR}/src/web/components/link/target.js
${GSA_SRC_DIR}/src/web/components/link/userlink.js
${GSA_SRC_DIR}/src/web/components/menu/iconmenu.js
${GSA_SRC_DIR}/src/web/components/menu/menu.js
${GSA_SRC_DIR}/src/web/components/menu/menuentry.js
Expand All @@ -289,6 +290,7 @@ set (GSA_JS_SRC_FILES
${GSA_SRC_DIR}/src/web/components/notification/dialognotification.js
${GSA_SRC_DIR}/src/web/components/notification/withDialogNotifiaction.js
${GSA_SRC_DIR}/src/web/components/observer/localeobserver.js
${GSA_SRC_DIR}/src/web/components/observer/sessionobserver.js
${GSA_SRC_DIR}/src/web/components/pagination/pagination.js
${GSA_SRC_DIR}/src/web/components/panel/infopanel.js
${GSA_SRC_DIR}/src/web/components/powerfilter/applyoverridesgroup.js
Expand Down
16 changes: 16 additions & 0 deletions gsa/src/gmp/commands/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,18 @@ import {forEach, map} from '../utils/array';
import {isDefined} from '../utils/identity';

import Capabilities from '../capabilities/capabilities';

import moment from '../models/date';

import User, {
AUTH_METHOD_LDAP,
AUTH_METHOD_NEW_PASSWORD,
AUTH_METHOD_RADIUS,
} from '../models/user';
import Settings from '../models/settings';

import {parseInt} from '../parser';

import EntitiesCommand from './entities';
import EntityCommand from './entity';

Expand Down Expand Up @@ -261,6 +266,17 @@ class UserCommand extends EntityCommand {
});
}

renewSession() {
return this.httpPost({
cmd: 'renew_session',
}).then(response => {
const {data} = response;
const {action_result} = data;
const seconds = parseInt(action_result.message);
return response.setData(moment.unix(seconds));
});
}

getElementFromRoot(root) {
return root.get_user.get_users_response.user;
}
Expand Down
8 changes: 5 additions & 3 deletions gsa/src/gmp/gmp.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,19 +130,21 @@ class Gmp {
const {
token,
timezone,
i18n,
locale,
sessionTimeout,
} = login;

this.settings.username = username;
this.settings.timezone = timezone;
this.settings.token = token;
this.settings.locale = i18n;
this.settings.locale = locale;

return {
locale: i18n === BROWSER_LANGUAGE ? undefined : i18n,
locale: locale === BROWSER_LANGUAGE ? undefined : locale,
username,
token,
timezone,
sessionTimeout,
};
});
}
Expand Down
16 changes: 13 additions & 3 deletions gsa/src/gmp/models/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,29 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import {parseInt} from 'gmp/parser';

import moment from 'gmp/models/date';

import {isDefined} from 'gmp/utils/identity';

class Login {

constructor(elem) {
this.client_address = elem.client_address;
this.clientAddress = elem.client_address;
this.guest = elem.guest;
this.i18n = elem.i18n;
this.locale = elem.i18n;
this.role = elem.role;
this.severity = elem.severity;
this.timezone = elem.timezone;
this.token = elem.token;
this.vendor_version = elem.vendor_version;
this.vendorVersion = elem.vendor_version;
this.version = elem.version;

const unixSeconds = parseInt(elem.session);

this.sessionTimeout = isDefined(unixSeconds) ?
moment.unix(unixSeconds) : undefined;
}
}

Expand Down
4 changes: 2 additions & 2 deletions gsa/src/gmp/utils/event.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ export const KeyCode = {
* Group multiple sequential calls in a single one
*
* @param {Function} func Function to call
* @param {Number} wait Wait time until no more calls to the wrapper
* function are fired
* @param {Number} wait Wait time in ms until no more calls to the
* wrapper function are fired
* @param {Boolean} immediate Call func initially
*
* @returns {Function} Wrapper function
Expand Down
12 changes: 10 additions & 2 deletions gsa/src/web/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ import React from 'react';
import {Provider as StoreProvider} from 'react-redux';

import Gmp from 'gmp';

import CacheFactory from 'gmp/cache';

import {isDefined} from 'gmp/utils/identity';

import LocaleObserver from 'web/components/observer/localeobserver';
Expand Down Expand Up @@ -57,8 +59,14 @@ window.gmp = gmp;
globalcss();

const initStore = () => {
store.dispatch(setTimezone(gmp.settings.timezone));
store.dispatch(setUsername(gmp.settings.username));
const {timezone, username} = gmp.settings;

if (isDefined(timezone)) {
store.dispatch(setTimezone(timezone));
}
if (isDefined(username)) {
store.dispatch(setUsername(username));
}
};

class App extends React.Component {
Expand Down
4 changes: 3 additions & 1 deletion gsa/src/web/authorized.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,13 @@ class Authorized extends React.Component {
toLoginPage() {
const {gmp, history} = this.props;

gmp.logout();
gmp.clearToken(); // ensure gmp.isLoggedIn returns false

history.replace('/login', {
next: this.props.location.pathname,
});

gmp.logout();
}

render() {
Expand Down
16 changes: 3 additions & 13 deletions gsa/src/web/components/bar/titlebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ import Divider from 'web/components/layout/divider';
import Layout from 'web/components/layout/layout';

import Link from 'web/components/link/link';
import UserLink from 'web/components/link/userlink';

import compose from 'web/utils/compose';
import PropTypes from 'web/utils/proptypes';
import Theme from 'web/utils/theme';
import withGmp from 'web/utils/withGmp';
import withUsername from 'web/utils/withUserName';

const TITLE_BAR_HEIGHT = '42px';

Expand All @@ -53,8 +53,6 @@ const LogoutLink = styled.a`
};
`;

const UserLink = LogoutLink.withComponent(Link);

const GreenboneIcon = styled(GBIcon)`
width: 40px;
height: 40px;
Expand Down Expand Up @@ -121,12 +119,8 @@ class Titlebar extends React.Component {
});
}


render() {
const {
gmp,
username,
} = this.props;
const {gmp} = this.props;
return (
<React.Fragment>
<TitlebarPlaceholder/>
Expand All @@ -141,9 +135,7 @@ class Titlebar extends React.Component {
</Link>
<Divider>
<span>{_('Logged in as ')}</span>
<UserLink to="usersettings">
<b>{username}</b>
</UserLink>
<UserLink/>
<span> | </span>
<LogoutLink onClick={this.handleLogout}>
{_('Logout')}
Expand All @@ -161,13 +153,11 @@ class Titlebar extends React.Component {
Titlebar.propTypes = {
gmp: PropTypes.gmp.isRequired,
history: PropTypes.object.isRequired,
username: PropTypes.string,
};

export default compose(
withGmp,
withRouter,
withUsername,
)(Titlebar);

// vim: set ts=2 sw=2 tw=80:
18 changes: 15 additions & 3 deletions gsa/src/web/components/dashboard/controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import NewIcon from '../icon/newicon';
import Icon from '../icon/icon';

import {getDisplay} from './registry';
import {renewSessionTimeout} from 'web/store/usersettings/actions.js';

export class DashboardControls extends React.Component {

Expand All @@ -74,14 +75,17 @@ export class DashboardControls extends React.Component {
} = this.props;

onResetClick(dashboardId);
this.renewSession();
}

handleNewClick() {
this.setState({showNewDialog: true});
this.renewSession();
}

handleNewDialoClose() {
this.setState({showNewDialog: false});
this.renewSession();
}

handleNewDisplay({displayId}) {
Expand All @@ -92,9 +96,15 @@ export class DashboardControls extends React.Component {

if (isDefined(onNewDisplay)) {
onNewDisplay(dashboardId, displayId);

this.renewSession();
}
}

renewSession() {
this.props.renewSessionTimeout();
}

render() {
const {showNewDialog} = this.state;
const {canAdd, displayIds = []} = this.props;
Expand Down Expand Up @@ -160,6 +170,7 @@ DashboardControls.propTypes = {
canAdd: PropTypes.bool.isRequired,
dashboardId: PropTypes.id.isRequired,
displayIds: PropTypes.arrayOf(PropTypes.string),
renewSessionTimeout: PropTypes.func.isRequired,
onNewDisplay: PropTypes.func.isRequired,
onResetClick: PropTypes.func.isRequired,
};
Expand All @@ -174,9 +185,10 @@ const mapStateToProps = (rootState, {dashboardId}) => {
};
};

const mapDispatchToProps = (dispatch, ownProps) => ({
onResetClick: (...args) => dispatch(resetSettings(ownProps)(...args)),
onNewDisplay: (...args) => dispatch(addDisplay(ownProps)(...args)),
const mapDispatchToProps = (dispatch, {gmp}) => ({
onResetClick: (...args) => dispatch(resetSettings({gmp})(...args)),
onNewDisplay: (...args) => dispatch(addDisplay({gmp})(...args)),
renewSessionTimeout: () => dispatch(renewSessionTimeout({gmp})),
});

export default compose(
Expand Down
10 changes: 7 additions & 3 deletions gsa/src/web/components/dashboard/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import withGmp from '../../utils/withGmp';
import compose from '../../utils/compose';

import {getDisplay} from './registry';
import {renewSessionTimeout} from 'web/store/usersettings/actions';

const log = Logger.getLogger('web.components.dashboard');

Expand Down Expand Up @@ -108,6 +109,7 @@ export class Dashboard extends React.Component {
maxItemsPerRow: PropTypes.number,
maxRows: PropTypes.number,
permittedDisplays: PropTypes.arrayOf(PropTypes.string).isRequired,
renewSessionTimeout: PropTypes.func.isRequired,
saveSettings: PropTypes.func.isRequired,
onFilterChanged: PropTypes.func,
}
Expand Down Expand Up @@ -178,6 +180,7 @@ export class Dashboard extends React.Component {
const {id} = this.props;

this.props.saveSettings(id, {rows: items});
this.props.renewSessionTimeout();
}

render() {
Expand Down Expand Up @@ -265,11 +268,12 @@ const mapStateToProps = (rootState, {id}) => {
};
};

const mapDispatchToProps = (dispatch, ownProps) => ({
const mapDispatchToProps = (dispatch, {gmp}) => ({
loadSettings: (id, defaults) =>
dispatch(loadSettings(ownProps)(id, defaults)),
dispatch(loadSettings({gmp})(id, defaults)),
saveSettings: (id, settings) =>
dispatch(saveSettings(ownProps)(id, settings)),
dispatch(saveSettings({gmp})(id, settings)),
renewSessionTimeout: () => dispatch(renewSessionTimeout({gmp})),
});

export default compose(
Expand Down
Loading