Skip to content

Commit

Permalink
Merge pull request #908 from bjoernricks/auto-logout
Browse files Browse the repository at this point in the history
Auto logout
  • Loading branch information
swaterkamp authored Sep 4, 2018
2 parents 59ce350 + 4a86521 commit da5e44a
Show file tree
Hide file tree
Showing 8 changed files with 191 additions and 41 deletions.
1 change: 1 addition & 0 deletions gsa/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,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/locationobserver.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
Expand Down
6 changes: 6 additions & 0 deletions gsa/src/gmp/commands/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,12 @@ class UserCommand extends EntityCommand {
});
}

ping() {
return this.httpGet({
cmd: 'ping',
});
}

getElementFromRoot(root) {
return root.get_user.get_users_response.user;
}
Expand Down
97 changes: 97 additions & 0 deletions gsa/src/web/components/observer/locationobserver.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/* Greenbone Security Assistant
*
* Authors:
* Björn Ricks <[email protected]>
*
* Copyright:
* Copyright (C) 2018 Greenbone Networks GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import React from 'react';

import {connect} from 'react-redux';

import {withRouter} from 'react-router-dom';

import Logger from 'gmp/log';

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

import compose from 'web/utils/compose';
import PropTypes from 'web/utils/proptypes';
import withGmp from 'web/utils/withGmp';

const log = Logger.getLogger('web.observer.locationobserver');

const locationChanged = (loc, prevLoc) =>
loc.pathname !== prevLoc.pathname || loc.search !== prevLoc.search;

class LocationObserver extends React.Component {

constructor(...args) {
super(...args);

this.state = {
location: this.props.location,
};
}

static getDerivedStateFromProps(props, state) {
if (locationChanged(props.location, state.location)) {
return {
location: props.location,
locationHasChanged: true,
};
}
return {
locationHasChanged: false,
};
}

componentDidMount() {
// init session timeout in store
// this is necessary for page reloads
this.props.renewSessionTimeout();
}

componentDidUpdate() {
if (this.state.locationHasChanged) {
log.debug('Location has changed. Renewing session.');

this.props.renewSessionTimeout();
}
}

render() {
return this.props.children;
}
}

LocationObserver.propTypes = {
gmp: PropTypes.gmp.isRequired,
location: PropTypes.object.isRequired,
renewSessionTimeout: PropTypes.func.isRequired,
};

export default compose(
withGmp,
withRouter,
connect(undefined, (dispatch, {gmp}) => ({
renewSessionTimeout: () => dispatch(renewSessionTimeout(gmp)()),
})),
)(LocationObserver);

// vim: set ts=2 sw=2 tw=80:
101 changes: 62 additions & 39 deletions gsa/src/web/components/observer/sessionobserver.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,74 +24,97 @@ import React from 'react';

import {connect} from 'react-redux';

import {withRouter} from 'react-router-dom';

import Logger from 'gmp/log';

import {renewSessionTimeout} from 'web/store/usersettings/actions';
import moment from 'gmp/models/date';

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

import {getSessionTimeout} from 'web/store/usersettings/selectors';

import compose from 'web/utils/compose';
import PropTypes from 'web/utils/proptypes';
import withGmp from 'web/utils/withGmp';

const log = Logger.getLogger('web.observer.sessionobserver');

const locationChanged = (loc, prevLoc) =>
loc.pathname !== prevLoc.pathname || loc.search !== prevLoc.search;
const DELAY = 15 * 1000; // 15 seconds in milliseconds

class SessionObserver extends React.Component {
class Ping extends React.Component {

constructor(...args) {
super(...args);

this.state = {
location: this.props.location,
};
this.handlePing = this.handlePing.bind(this);
}

static getDerivedStateFromProps(props, state) {
if (locationChanged(props.location, state.location)) {
return {
location: props.location,
locationHasChanged: true,
};
}
return {
locationHasChanged: false,
};
componentDidMount() {
this.startTimer();
}

componentDidMount() {
// init session timeout in store
// this is necessary for page reloads
this.props.renewSessionTimeout();
componentWillUnmount() {
this.clearTimer();
}

componentDidUpdate() {
if (this.state.locationHasChanged) {
log.debug('Location has changed. Renewing session.');
clearTimer() {
if (isDefined(this.timer)) {
log.debug('clearing ping timer', this.timer);

this.props.renewSessionTimeout();
global.clearTimeout(this.timer);
}
}

startTimer() {
const {sessionTimeout} = this.props;

const timeout = sessionTimeout.diff(moment()) + DELAY;

if (timeout > 0) {
this.timer = global.setTimeout(this.handlePing, timeout);

log.debug('started ping timer', this.timer, 'timeout', timeout,
'milliseconds');
}
}

handlePing() {
const {gmp} = this.props;

this.timer = undefined;

gmp.user.ping();
}

render() {
return this.props.children;
return null;
}
}

SessionObserver.propTypes = {
Ping.propTypes = {
gmp: PropTypes.gmp.isRequired,
location: PropTypes.object.isRequired,
renewSessionTimeout: PropTypes.func.isRequired,
sessionTimeout: PropTypes.date.isRequired,
};

Ping = withGmp(Ping);

const SessionObserver = ({sessionTimeout}) => {
if (!isDefined(sessionTimeout)) {
return null;
}

return (
<Ping
key={sessionTimeout.unix()}
sessionTimeout={sessionTimeout}
/>
);
};

SessionObserver.propTypes = {
sessionTimeout: PropTypes.date,
};

export default compose(
withGmp,
withRouter,
connect(undefined, (dispatch, {gmp}) => ({
renewSessionTimeout: () => dispatch(renewSessionTimeout(gmp)()),
})),
)(SessionObserver);
export default connect(rootState => ({
sessionTimeout: getSessionTimeout(rootState),
}))(SessionObserver);

// vim: set ts=2 sw=2 tw=80:
6 changes: 4 additions & 2 deletions gsa/src/web/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {createBrowserHistory} from 'history';
import {stringify, parse} from 'qs';
import qhistory from 'qhistory';

import LocationObserver from 'web/components/observer/locationobserver';
import SessionObserver from 'web/components/observer/sessionobserver';

import AssetsPage from './pages/assets/page';
Expand Down Expand Up @@ -153,7 +154,8 @@ class Routes extends React.Component {
<Switch>
<Route path="/login" component={LoginPage}/>
<Authorized>
<SessionObserver>
<SessionObserver/>
<LocationObserver>
<Page>
<Switch>
<Route
Expand Down Expand Up @@ -444,7 +446,7 @@ class Routes extends React.Component {
<Route component={PageNotFound}/>
</Switch>
</Page>
</SessionObserver>
</LocationObserver>
</Authorized>
</Switch>
</Router>
Expand Down
2 changes: 2 additions & 0 deletions gsad/src/gsad.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,7 @@ init_validator ()
"|(move_task)"
"|(new_alert)"
"|(new_task)"
"|(ping)"
"|(renew_session)"
"|(report_alert)"
"|(restore)"
Expand Down Expand Up @@ -2211,6 +2212,7 @@ exec_gmp_get (http_connection_t *con,
ELSE (get_config_nvt)
ELSE (get_nvts)
ELSE (get_protocol_doc)
ELSE (ping)
ELSE (sync_config)
ELSE (wizard)
ELSE (wizard_get)
Expand Down
17 changes: 17 additions & 0 deletions gsad/src/gsad_gmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -23854,6 +23854,23 @@ renew_session_gmp (gvm_connection_t *connection, credentials_t * credentials,
return html;
}

/**
* @brief Get assets, envelope the result.
*
* @param[in] connection Connection to manager.
* @param[in] credentials Username and password for authentication.
* @param[in] params Request parameters.
* @param[out] response_data Extra data return for the HTTP response.
*
* @return Enveloped XML object.
*/
char *
ping_gmp (gvm_connection_t *connection, credentials_t * credentials,
params_t *params, cmd_response_data_t* response_data)
{
return action_result (connection, credentials, params, response_data,
"ping", "pong", NULL, NULL);
}

/* Manager communication. */

Expand Down
2 changes: 2 additions & 0 deletions gsad/src/gsad_gmp.h
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,8 @@ char * get_assets_chart_gmp (gvm_connection_t *, credentials_t *,

char * renew_session_gmp (gvm_connection_t *, credentials_t *,
params_t *, cmd_response_data_t*);
char * ping_gmp (gvm_connection_t *, credentials_t *,
params_t *, cmd_response_data_t*);

int login (http_connection_t *con, params_t *params,
cmd_response_data_t *response_data, const char *client_address);
Expand Down

0 comments on commit da5e44a

Please sign in to comment.