From 536c55dc5f9f80ea67e2ccb39c1b4a276fbddc07 Mon Sep 17 00:00:00 2001 From: Reed Garmsen Date: Wed, 7 Oct 2015 16:58:27 -0700 Subject: Initial changes to audit log along with structure for handling different audit types --- web/react/components/access_history_modal.jsx | 91 ++++++++++++++++++++++----- 1 file changed, 75 insertions(+), 16 deletions(-) (limited to 'web/react/components') diff --git a/web/react/components/access_history_modal.jsx b/web/react/components/access_history_modal.jsx index 2ad4d5b00..9aeb7f682 100644 --- a/web/react/components/access_history_modal.jsx +++ b/web/react/components/access_history_modal.jsx @@ -15,7 +15,7 @@ export default class AccessHistoryModal extends React.Component { this.onHide = this.onHide.bind(this); this.onShow = this.onShow.bind(this); - let state = this.getStateFromStoresForAudits(); + const state = this.getStateFromStoresForAudits(); state.moreInfo = []; this.state = state; @@ -54,29 +54,91 @@ export default class AccessHistoryModal extends React.Component { } render() { var accessList = []; - var currentHistoryDate = null; for (var i = 0; i < this.state.audits.length; i++) { var currentAudit = this.state.audits[i]; - var newHistoryDate = new Date(currentAudit.create_at); - var newDate = null; - - if (!currentHistoryDate || currentHistoryDate.toLocaleDateString() !== newHistoryDate.toLocaleDateString()) { - currentHistoryDate = newHistoryDate; - newDate = (
{currentHistoryDate.toDateString()}
); - } + var currentDate = new Date(currentAudit.create_at); if (!currentAudit.session_id && currentAudit.action.search('/users/login') !== -1) { currentAudit.session_id = 'N/A (Login attempt)'; } + const currentActionURL = currentAudit.action.replace(/\/api\/v[1-9]/, ''); + + let currentAuditDesc = ''; + + /* Handle specific audit type formatting semi-individually and + fall back to a best guess case if none exists + + Supported audits: + /channels + - Create Channel X + - Update Channel X + - Update Channel Description X + - Delete Channel X + - Add User to Channel X + - Remove User from Channel X + + /oauth + - Register X + - Allow Attempt/Success/Failure X + + /team + - Revoke All Sessions X (NO CORRESPONDING ADDRESS) + + - Update (users - ?) X + - Update Notify (?) X + - Login Attempt X + - Login (success/failure) X + - Logout (/logout) X + */ + switch (currentActionURL) { + case '/channels/create': + break; + case '/channels/update': + break; + case '/channels/update_desc': + break; + case /\/channels\/[A-Za-z0-9]+\/delete/: + break; + case /\/channels\/[A-Za-z0-9]+\/add/: + break; + case /\/channels\/[A-Za-z0-9]+\/remove/: + break; + case '/oauth/register': + break; + case '/oauth/allow': + break; + case '/team/': + break; + default: + let currentActionDesc = ''; + + if (currentActionURL && currentActionURL.lastIndexOf('/') !== -1) { + currentActionDesc = currentActionURL.substring(currentActionURL.lastIndexOf('/') + 1).replace('_', ' '); + currentActionDesc = Utils.toTitleCase(currentActionDesc); + } + + let currentExtraInfoDesc = ''; + if (currentAudit.extra_info) { + currentExtraInfoDesc = currentAudit.extra_info; + + if (currentExtraInfoDesc.indexOf('=') !== -1) { + currentExtraInfoDesc = currentExtraInfoDesc.substring(currentExtraInfoDesc.indexOf('=') + 1); + } + } + + currentAuditDesc = currentActionDesc + ' ' + currentExtraInfoDesc; + break; + } + var moreInfo = ( - More info + {'More info'} ); @@ -84,7 +146,6 @@ export default class AccessHistoryModal extends React.Component { moreInfo = (
{'Session ID: ' + currentAudit.session_id}
-
{'URL: ' + currentAudit.action.replace(/\/api\/v[1-9]/, '')}
); } @@ -99,11 +160,9 @@ export default class AccessHistoryModal extends React.Component { key={'accessHistoryEntryKey' + i} className='access-history__table' > -
{newDate}
-
{newHistoryDate.toLocaleTimeString(navigator.language, {hour: '2-digit', minute: '2-digit'})}
+
{currentDate.toDateString() + ' - ' + currentDate.toLocaleTimeString(navigator.language, {hour: '2-digit', minute: '2-digit'}) + ' | ' + currentAuditDesc + ' from ' + currentAudit.ip_address}
-
{'IP: ' + currentAudit.ip_address}
{moreInfo}
{divider} @@ -138,13 +197,13 @@ export default class AccessHistoryModal extends React.Component { data-dismiss='modal' aria-label='Close' > - +

- Access History + {'Access History'}

Date: Fri, 9 Oct 2015 16:35:59 -0700 Subject: Finished structure for formatting audits and began writing individual formatting for each audit --- web/react/components/access_history_modal.jsx | 193 ++++++++++++++++++-------- 1 file changed, 132 insertions(+), 61 deletions(-) (limited to 'web/react/components') diff --git a/web/react/components/access_history_modal.jsx b/web/react/components/access_history_modal.jsx index 9aeb7f682..41a865df4 100644 --- a/web/react/components/access_history_modal.jsx +++ b/web/react/components/access_history_modal.jsx @@ -14,6 +14,7 @@ export default class AccessHistoryModal extends React.Component { this.handleMoreInfo = this.handleMoreInfo.bind(this); this.onHide = this.onHide.bind(this); this.onShow = this.onShow.bind(this); + this.formatAuditInfo = this.formatAuditInfo.bind(this); const state = this.getStateFromStoresForAudits(); state.moreInfo = []; @@ -52,74 +53,127 @@ export default class AccessHistoryModal extends React.Component { newMoreInfo[index] = true; this.setState({moreInfo: newMoreInfo}); } - render() { - var accessList = []; + formatAuditInfo(currentAudit) { + const currentActionURL = currentAudit.action.replace(/\/api\/v[1-9]/, ''); - for (var i = 0; i < this.state.audits.length; i++) { - var currentAudit = this.state.audits[i]; - var currentDate = new Date(currentAudit.create_at); + let currentAuditDesc = ' '; + + /* Handle audit formatting semi-individually for each type and + fall back to a best guess case if none exists + + Supported audits: + /channels + - Create Channel X + - Update Channel X + - Update Channel Description X + - Delete Channel X + - Add User to Channel X + - Remove User from Channel X + + /oauth + - Register X + - Allow Attempt/Success/Failure X + + /team + - Revoke All Sessions X (NO CORRESPONDING ADDRESS/FUNCTION) + + - Revoke Session X + - Update (users - ?) X + - Update Notify (?) X + - Login Attempt X + - Login (success/failure) X + - Logout (/logout) X + - Verify Email (/verify_email) X + */ + switch (currentActionURL) { + + /* BREAK UP CHANNEL INTO OWN SWITCH STATEMENT TO REUSE VARIABLES AND BE CLEAN */ + case '/channels/create': + const createChannelInfo = currentAudit.extra_info.split('='); + let channelName = ''; + + if (createChannelInfo[0] === 'name') { + channelName = createChannelInfo[1]; + } + + currentAuditDesc = 'Created a new channel/group named ' + channelName; + + break; + case '/channels/update': + const updateChannelInfo = currentAudit.extra_info.split('='); + let originalChannelName = ''; + + if (updateChannelInfo[0] === 'name') { + originalChannelName = updateChannelInfo[1]; + } + + currentAuditDesc = 'Updated the channel/group name for ' + originalChannelName; + break; - if (!currentAudit.session_id && currentAudit.action.search('/users/login') !== -1) { - currentAudit.session_id = 'N/A (Login attempt)'; + /* case '/channels/update_desc': + const updateChannelInfo = currentAudit.extra_info.split('='); + let originalChannelName = ''; + + if (updateChannelInfo[0] === 'name') { + originalChannelName = updateChannelInfo[1]; } - const currentActionURL = currentAudit.action.replace(/\/api\/v[1-9]/, ''); - - let currentAuditDesc = ''; - - /* Handle specific audit type formatting semi-individually and - fall back to a best guess case if none exists - - Supported audits: - /channels - - Create Channel X - - Update Channel X - - Update Channel Description X - - Delete Channel X - - Add User to Channel X - - Remove User from Channel X - - /oauth - - Register X - - Allow Attempt/Success/Failure X - - /team - - Revoke All Sessions X (NO CORRESPONDING ADDRESS) - - - Update (users - ?) X - - Update Notify (?) X - - Login Attempt X - - Login (success/failure) X - - Logout (/logout) X - */ - switch (currentActionURL) { - case '/channels/create': - break; - case '/channels/update': - break; - case '/channels/update_desc': - break; - case /\/channels\/[A-Za-z0-9]+\/delete/: - break; - case /\/channels\/[A-Za-z0-9]+\/add/: - break; - case /\/channels\/[A-Za-z0-9]+\/remove/: - break; - case '/oauth/register': - break; - case '/oauth/allow': - break; - case '/team/': - break; - default: - let currentActionDesc = ''; + currentAuditDesc = 'Updated the channel/group name for ' + originalChannelName; + break;*/ + case /\/channels\/[A-Za-z0-9]+\/delete/: + break; + case /\/channels\/[A-Za-z0-9]+\/add/: + break; + case /\/channels\/[A-Za-z0-9]+\/remove/: + break; + case '/oauth/register': + break; + case '/oauth/allow': + break; + case '/users/login': + break; + case '/users/revoke_session': + break; + case '/users/newimage': + break; + case '/users/update': + break; + case '/users/newpassword': + break; + case '/users/update_roles': + break; + case '/users/update_active': + break; + case '/users/send_password_reset': + break; + case '/users/reset_password': + break; + case '/users/update_notify': + break; + case '/logout': + break; + case '/hooks/incoming/create': + break; + case '/hooks/incoming/delete': + break; + case '/verify_email': + break; + case '/oauth/access_token': + break; + case '': + break; + default: + if (currentAudit.extra_info.indexOf('revoked_all=') >= 0) { + // do stuff + } else { + let currentActionDesc = ' '; if (currentActionURL && currentActionURL.lastIndexOf('/') !== -1) { currentActionDesc = currentActionURL.substring(currentActionURL.lastIndexOf('/') + 1).replace('_', ' '); currentActionDesc = Utils.toTitleCase(currentActionDesc); } - let currentExtraInfoDesc = ''; + let currentExtraInfoDesc = ' '; if (currentAudit.extra_info) { currentExtraInfoDesc = currentAudit.extra_info; @@ -127,11 +181,23 @@ export default class AccessHistoryModal extends React.Component { currentExtraInfoDesc = currentExtraInfoDesc.substring(currentExtraInfoDesc.indexOf('=') + 1); } } - currentAuditDesc = currentActionDesc + ' ' + currentExtraInfoDesc; - break; } + break; + } + + const currentDate = new Date(currentAudit.create_at); + const currentAuditInfo = currentDate.toDateString() + ' - ' + currentDate.toLocaleTimeString(navigator.language, {hour: '2-digit', minute: '2-digit'}) + ' | ' + currentAuditDesc; + return currentAuditInfo; + } + render() { + var accessList = []; + + for (var i = 0; i < this.state.audits.length; i++) { + const currentAudit = this.state.audits[i]; + const currentAuditInfo = this.formatAuditInfo(currentAudit); + var moreInfo = ( +
{'IP: ' + currentAudit.ip_address}
{'Session ID: ' + currentAudit.session_id}
); @@ -161,7 +232,7 @@ export default class AccessHistoryModal extends React.Component { className='access-history__table' >
-
{currentDate.toDateString() + ' - ' + currentDate.toLocaleTimeString(navigator.language, {hour: '2-digit', minute: '2-digit'}) + ' | ' + currentAuditDesc + ' from ' + currentAudit.ip_address}
+
{currentAuditInfo}
{moreInfo}
-- cgit v1.2.3-1-g7c22 From 63b0ca8e4b63231e7b3d7cdb8b2e35d70d328114 Mon Sep 17 00:00:00 2001 From: Reed Garmsen Date: Mon, 12 Oct 2015 17:00:27 -0700 Subject: Added more supported audits to audit log --- web/react/components/access_history_modal.jsx | 213 +++++++++++++++++--------- 1 file changed, 140 insertions(+), 73 deletions(-) (limited to 'web/react/components') diff --git a/web/react/components/access_history_modal.jsx b/web/react/components/access_history_modal.jsx index 41a865df4..cb50ee4e7 100644 --- a/web/react/components/access_history_modal.jsx +++ b/web/react/components/access_history_modal.jsx @@ -2,6 +2,7 @@ // See License.txt for license information. var UserStore = require('../stores/user_store.jsx'); +var ChannelStore = require('../stores/channel_store.jsx'); var AsyncClient = require('../utils/async_client.jsx'); var LoadingScreen = require('./loading_screen.jsx'); var Utils = require('../utils/utils.jsx'); @@ -56,16 +57,17 @@ export default class AccessHistoryModal extends React.Component { formatAuditInfo(currentAudit) { const currentActionURL = currentAudit.action.replace(/\/api\/v[1-9]/, ''); - let currentAuditDesc = ' '; + let currentAuditDesc = ''; /* Handle audit formatting semi-individually for each type and fall back to a best guess case if none exists Supported audits: /channels - - Create Channel X - - Update Channel X - - Update Channel Description X + - Create Channel + - Create Direct Channel + - Update Channel + - Update Channel Description - Delete Channel X - Add User to Channel X - Remove User from Channel X @@ -85,84 +87,147 @@ export default class AccessHistoryModal extends React.Component { - Logout (/logout) X - Verify Email (/verify_email) X */ - switch (currentActionURL) { + if (currentActionURL.indexOf('/channels') === 0) { + const channelInfo = currentAudit.extra_info.split(' '); + const channelNameField = channelInfo[0].split('='); - /* BREAK UP CHANNEL INTO OWN SWITCH STATEMENT TO REUSE VARIABLES AND BE CLEAN */ - case '/channels/create': - const createChannelInfo = currentAudit.extra_info.split('='); + let channelURL = ''; + let channelObj; let channelName = ''; - - if (createChannelInfo[0] === 'name') { - channelName = createChannelInfo[1]; + if (channelNameField.indexOf('name') >= 0) { + channelURL = channelNameField[channelNameField.indexOf('name') + 1]; + channelObj = ChannelStore.getByName(channelURL); + if (channelObj) { + channelName = channelObj.display_name; + } else { + channelName = channelURL; + } } - currentAuditDesc = 'Created a new channel/group named ' + channelName; + switch (currentActionURL) { + case '/channels/create': + currentAuditDesc = 'Created the ' + channelName + ' channel/group'; + break; + case '/channels/create_direct': + currentAuditDesc = 'Established a direct message channel with ' + Utils.getDirectTeammate(channelObj.id).username; + break; + case '/channels/update': + currentAuditDesc = 'Updated the ' + channelName + ' channel/group name'; + break; + case '/channels/update_desc': + currentAuditDesc = 'Updated the ' + channelName + ' channel/group description'; + break; + default: + let userIdField = []; + let userId = ''; + let username = ''; + + if (channelInfo[1]) { + userIdField = channelInfo[1].split('='); + + if (userIdField.indexOf('user_id') >= 0) { + userId = userIdField[userIdField.indexOf('user_id') + 1]; + username = UserStore.getProfile(userId).username; + } + } - break; - case '/channels/update': - const updateChannelInfo = currentAudit.extra_info.split('='); - let originalChannelName = ''; + if (/\/channels\/[A-Za-z0-9]+\/delete/.test(currentActionURL)) { + currentAuditDesc = 'Deleted the channel/group with the URL ' + channelURL; + } else if (/\/channels\/[A-Za-z0-9]+\/add/.test(currentActionURL)) { + currentAuditDesc = 'Added ' + username + ' to the ' + channelName + ' channel/group'; + } else if (/\/channels\/[A-Za-z0-9]+\/remove/.test(currentActionURL)) { + currentAuditDesc = 'Removed ' + username + ' from the ' + channelName + ' channel/group'; + } - if (updateChannelInfo[0] === 'name') { - originalChannelName = updateChannelInfo[1]; + break; + } + } else if (currentActionURL.indexOf('/oauth') === 0) { + switch (currentActionURL) { + case '/oauth/register': + break; + case '/oauth/allow': + break; + case '/oauth/access_token': + break; + default: + break; } + } else if (currentActionURL.indexOf('/users') === 0) { + const userInfo = currentAudit.extra_info.split(' '); + switch (currentActionURL) { + case '/users/login': + if (userInfo[0] === 'attempt') { + currentAuditDesc = 'Login attempted'; + } else if (userInfo[0] === 'success') { + currentAuditDesc = 'Successful login attempt'; + } else if (userInfo[0]) { + currentAuditDesc = 'FAILED login attempt'; + } + + break; + case '/users/revoke_session': + const revokedSessionId = userInfo[0].split('=')[1]; + + currentAuditDesc = 'Revoked the session with id ' + revokedSessionId; + break; + case '/users/newimage': + currentAuditDesc = 'Updated your profile picture'; + break; + case '/users/update': + currentAuditDesc = 'Updated the general settings of your account'; + break; + case '/users/newpassword': + if (userInfo[0] === 'attempted') { + currentAuditDesc = 'Password change attempted'; + } else if (userInfo[0] === 'completed') { + currentAuditDesc = 'Password change success'; + } - currentAuditDesc = 'Updated the channel/group name for ' + originalChannelName; - break; + break; + case '/users/update_roles': + const userRoles = userInfo[0].split('=')[1]; - /* case '/channels/update_desc': - const updateChannelInfo = currentAudit.extra_info.split('='); - let originalChannelName = ''; + currentAuditDesc = 'Updated user role(s) to '; + if (userRoles.trim()) { + currentAuditDesc += userRoles; + } else { + currentAuditDesc += 'member'; + } - if (updateChannelInfo[0] === 'name') { - originalChannelName = updateChannelInfo[1]; + break; + case '/users/update_active': + break; + case '/users/send_password_reset': + break; + case '/users/reset_password': + break; + case '/users/update_notify': + break; + default: + break; + } + } else if (currentActionURL.indexOf('/hooks') === 0) { + switch (currentActionURL) { + case '/hooks/incoming/create': + break; + case '/hooks/incoming/delete': + break; + default: + break; + } + } else { + switch (currentActionURL) { + case '/logout': + break; + case '/verify_email': + break; + default: + break; } + } - currentAuditDesc = 'Updated the channel/group name for ' + originalChannelName; - break;*/ - case /\/channels\/[A-Za-z0-9]+\/delete/: - break; - case /\/channels\/[A-Za-z0-9]+\/add/: - break; - case /\/channels\/[A-Za-z0-9]+\/remove/: - break; - case '/oauth/register': - break; - case '/oauth/allow': - break; - case '/users/login': - break; - case '/users/revoke_session': - break; - case '/users/newimage': - break; - case '/users/update': - break; - case '/users/newpassword': - break; - case '/users/update_roles': - break; - case '/users/update_active': - break; - case '/users/send_password_reset': - break; - case '/users/reset_password': - break; - case '/users/update_notify': - break; - case '/logout': - break; - case '/hooks/incoming/create': - break; - case '/hooks/incoming/delete': - break; - case '/verify_email': - break; - case '/oauth/access_token': - break; - case '': - break; - default: + /* If all else fails... */ + if (!currentAuditDesc) { if (currentAudit.extra_info.indexOf('revoked_all=') >= 0) { // do stuff @@ -183,8 +248,6 @@ export default class AccessHistoryModal extends React.Component { } currentAuditDesc = currentActionDesc + ' ' + currentExtraInfoDesc; } - - break; } const currentDate = new Date(currentAudit.create_at); @@ -210,7 +273,11 @@ export default class AccessHistoryModal extends React.Component { if (this.state.moreInfo[i]) { if (!currentAudit.session_id && currentAudit.action.search('/users/login') !== -1) { - currentAudit.session_id = 'N/A (Login attempt)'; + if (currentAudit.extra_info === 'attempt') { + currentAudit.session_id = 'N/A (Login attempt)'; + } else { + currentAudit.session_id = 'N/A (Login failure)'; + } } moreInfo = ( -- cgit v1.2.3-1-g7c22 From e7e83b44d8be1f0081b70274a351486bade35d5b Mon Sep 17 00:00:00 2001 From: Reed Garmsen Date: Tue, 13 Oct 2015 11:15:44 -0700 Subject: Added more individual audit handling, primarily involving the user --- web/react/components/access_history_modal.jsx | 56 ++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 5 deletions(-) (limited to 'web/react/components') diff --git a/web/react/components/access_history_modal.jsx b/web/react/components/access_history_modal.jsx index cb50ee4e7..4a169258a 100644 --- a/web/react/components/access_history_modal.jsx +++ b/web/react/components/access_history_modal.jsx @@ -16,6 +16,7 @@ export default class AccessHistoryModal extends React.Component { this.onHide = this.onHide.bind(this); this.onShow = this.onShow.bind(this); this.formatAuditInfo = this.formatAuditInfo.bind(this); + this.handleRevokedSession = this.handleRevokedSession.bind(this); const state = this.getStateFromStoresForAudits(); state.moreInfo = []; @@ -54,6 +55,9 @@ export default class AccessHistoryModal extends React.Component { newMoreInfo[index] = true; this.setState({moreInfo: newMoreInfo}); } + handleRevokedSession(sessionId) { + return 'The session with id ' + sessionId + ' was revoked'; + } formatAuditInfo(currentAudit) { const currentActionURL = currentAudit.action.replace(/\/api\/v[1-9]/, ''); @@ -142,6 +146,7 @@ export default class AccessHistoryModal extends React.Component { break; } } else if (currentActionURL.indexOf('/oauth') === 0) { + /* NEEDS TO BE DONE */ switch (currentActionURL) { case '/oauth/register': break; @@ -166,9 +171,7 @@ export default class AccessHistoryModal extends React.Component { break; case '/users/revoke_session': - const revokedSessionId = userInfo[0].split('=')[1]; - - currentAuditDesc = 'Revoked the session with id ' + revokedSessionId; + currentAuditDesc = this.handleRevokedSession(userInfo[0].split('=')[1]); break; case '/users/newimage': currentAuditDesc = 'Updated your profile picture'; @@ -196,30 +199,73 @@ export default class AccessHistoryModal extends React.Component { break; case '/users/update_active': + const updateType = userInfo[0].split('=')[0]; + const updateField = userInfo[0].split('=')[1]; + + /* Either describes account activation/deactivation or a revoked session as part of an account deactivation */ + if (updateType === 'active') { + if (updateField === 'true') { + currentAuditDesc = 'Account made active'; + } else if (updateField === 'false') { + currentAuditDesc = 'Account made inactive'; + } + + const actingUserInfo = userInfo[1].split('='); + if (actingUserInfo[0] === 'session_user') { + const actingUser = UserStore.getProfile(actingUserInfo[1]); + const currentUser = UserStore.getCurrentUser(); + if (currentUser && actingUser && (Utils.isAdmin(currentUser.roles) || Utils.isSystemAdmin(currentUser.roles))) { + currentAuditDesc += ' by ' + actingUser.username; + } else if (currentUser && actingUser) { + currentAuditDesc += ' by an admin'; + } + } + } else if (updateType === 'session_id') { + currentAuditDesc = this.handleRevokedSession(updateField); + } + break; case '/users/send_password_reset': + currentAuditDesc = 'Sent an email to ' + userInfo[0].split('=')[1] + ' to reset your password'; break; case '/users/reset_password': + + /* NEEDS TO BE TESTED! */ + if (userInfo[0] === 'attempted') { + currentAuditDesc = 'Password reset attempted'; + } else if (userInfo[0] === 'completed') { + currentAuditDesc = 'Password reset success'; + } + break; case '/users/update_notify': + currentAuditDesc = 'Updated your global notification settings'; break; default: break; } } else if (currentActionURL.indexOf('/hooks') === 0) { + /* NEEDS TO BE TESTED */ switch (currentActionURL) { case '/hooks/incoming/create': + currentAuditDesc = 'Attempted to create a webhook'; + currentAuditDesc = 'Successfully created a webhook'; break; case '/hooks/incoming/delete': + currentAuditDesc = 'Attempted to delete a webhook'; + currentAuditDesc = 'Successfully deleted a webhook'; break; default: break; } } else { + /* NEEDS TO BE TESTED */ switch (currentActionURL) { case '/logout': + currentAuditDesc = 'Logged out of your account'; break; case '/verify_email': + currentAuditDesc = 'Sucessfully verified your email address'; break; default: break; @@ -228,9 +274,9 @@ export default class AccessHistoryModal extends React.Component { /* If all else fails... */ if (!currentAuditDesc) { + /* Currently not called anywhere */ if (currentAudit.extra_info.indexOf('revoked_all=') >= 0) { - - // do stuff + currentAuditDesc = 'Revoked all current sessions for the team'; } else { let currentActionDesc = ' '; if (currentActionURL && currentActionURL.lastIndexOf('/') !== -1) { -- cgit v1.2.3-1-g7c22 From 48c69b86d81b417a912c0bab0a28d39ca8c49cfd Mon Sep 17 00:00:00 2001 From: Reed Garmsen Date: Wed, 14 Oct 2015 15:00:03 -0700 Subject: Added all remaining audit descriptions to supported audits --- web/react/components/access_history_modal.jsx | 106 ++++++++++++++------------ 1 file changed, 59 insertions(+), 47 deletions(-) (limited to 'web/react/components') diff --git a/web/react/components/access_history_modal.jsx b/web/react/components/access_history_modal.jsx index 4a169258a..58523feeb 100644 --- a/web/react/components/access_history_modal.jsx +++ b/web/react/components/access_history_modal.jsx @@ -63,34 +63,6 @@ export default class AccessHistoryModal extends React.Component { let currentAuditDesc = ''; - /* Handle audit formatting semi-individually for each type and - fall back to a best guess case if none exists - - Supported audits: - /channels - - Create Channel - - Create Direct Channel - - Update Channel - - Update Channel Description - - Delete Channel X - - Add User to Channel X - - Remove User from Channel X - - /oauth - - Register X - - Allow Attempt/Success/Failure X - - /team - - Revoke All Sessions X (NO CORRESPONDING ADDRESS/FUNCTION) - - - Revoke Session X - - Update (users - ?) X - - Update Notify (?) X - - Login Attempt X - - Login (success/failure) X - - Logout (/logout) X - - Verify Email (/verify_email) X - */ if (currentActionURL.indexOf('/channels') === 0) { const channelInfo = currentAudit.extra_info.split(' '); const channelNameField = channelInfo[0].split('='); @@ -146,25 +118,53 @@ export default class AccessHistoryModal extends React.Component { break; } } else if (currentActionURL.indexOf('/oauth') === 0) { - /* NEEDS TO BE DONE */ + const oauthInfo = currentAudit.extra_info.split(' '); + switch (currentActionURL) { case '/oauth/register': + const clientIdField = oauthInfo[0].split('='); + + if (clientIdField[0] === 'client_id') { + currentAuditDesc = 'Attempted to register a new OAuth Application with ID ' + clientIdField[1]; + } + break; case '/oauth/allow': + if (oauthInfo[0] === 'attempt') { + currentAuditDesc = 'Attempted to allow a new OAuth service access'; + } else if (oauthInfo[0] === 'success') { + currentAuditDesc = 'Successfully gave a new OAuth service access'; + } else if (oauthInfo[0] === 'fail - redirect_uri did not match registered callback') { + currentAuditDesc = 'Failed to allow a new OAuth service access - the redirect URI did not match the previously registered callback'; + } + break; case '/oauth/access_token': + if (oauthInfo[0] === 'attempt') { + currentAuditDesc = 'Attempted to get an OAuth access token'; + } else if (oauthInfo[0] === 'success') { + currentAuditDesc = 'Successfully added a new OAuth service'; + } else { + const oauthTokenFailure = oauthInfo[0].split('-'); + + if (oauthTokenFailure[0].trim() === 'fail' && oauthTokenFailure[1]) { + currentAuditDesc = 'Failed to get an OAuth access token - ' + oauthTokenFailure[1].trim(); + } + } + break; default: break; } } else if (currentActionURL.indexOf('/users') === 0) { const userInfo = currentAudit.extra_info.split(' '); + switch (currentActionURL) { case '/users/login': if (userInfo[0] === 'attempt') { - currentAuditDesc = 'Login attempted'; + currentAuditDesc = 'Attempted to login'; } else if (userInfo[0] === 'success') { - currentAuditDesc = 'Successful login attempt'; + currentAuditDesc = 'Successfully logged in'; } else if (userInfo[0]) { currentAuditDesc = 'FAILED login attempt'; } @@ -181,9 +181,11 @@ export default class AccessHistoryModal extends React.Component { break; case '/users/newpassword': if (userInfo[0] === 'attempted') { - currentAuditDesc = 'Password change attempted'; + currentAuditDesc = 'Attempted to change password'; } else if (userInfo[0] === 'completed') { - currentAuditDesc = 'Password change success'; + currentAuditDesc = 'Successfully changed password'; + } else if (userInfo[0] === 'failed - tried to update user password who was logged in through oauth') { + currentAuditDesc = 'Failed to change password - tried to update user password who was logged in through oauth'; } break; @@ -229,12 +231,10 @@ export default class AccessHistoryModal extends React.Component { currentAuditDesc = 'Sent an email to ' + userInfo[0].split('=')[1] + ' to reset your password'; break; case '/users/reset_password': - - /* NEEDS TO BE TESTED! */ - if (userInfo[0] === 'attempted') { - currentAuditDesc = 'Password reset attempted'; - } else if (userInfo[0] === 'completed') { - currentAuditDesc = 'Password reset success'; + if (userInfo[0] === 'attempt') { + currentAuditDesc = 'Attempted to reset password'; + } else if (userInfo[0] === 'success') { + currentAuditDesc = 'Successfully reset password'; } break; @@ -245,21 +245,33 @@ export default class AccessHistoryModal extends React.Component { break; } } else if (currentActionURL.indexOf('/hooks') === 0) { - /* NEEDS TO BE TESTED */ + const webhookInfo = currentAudit.extra_info.split(' '); + switch (currentActionURL) { case '/hooks/incoming/create': - currentAuditDesc = 'Attempted to create a webhook'; - currentAuditDesc = 'Successfully created a webhook'; + if (webhookInfo[0] === 'attempt') { + currentAuditDesc = 'Attempted to create a webhook'; + } else if (webhookInfo[0] === 'success') { + currentAuditDesc = 'Successfully created a webhook'; + } else if (webhookInfo[0] === 'fail - bad channel permissions') { + currentAuditDesc = 'Failed to create a webhook - bad channel permissions'; + } + break; case '/hooks/incoming/delete': - currentAuditDesc = 'Attempted to delete a webhook'; - currentAuditDesc = 'Successfully deleted a webhook'; + if (webhookInfo[0] === 'attempt') { + currentAuditDesc = 'Attempted to delete a webhook'; + } else if (webhookInfo[0] === 'success') { + currentAuditDesc = 'Successfully deleted a webhook'; + } else if (webhookInfo[0] === 'fail - inappropriate conditions') { + currentAuditDesc = 'Failed to delete a webhook - inappropriate conditions'; + } + break; default: break; } } else { - /* NEEDS TO BE TESTED */ switch (currentActionURL) { case '/logout': currentAuditDesc = 'Logged out of your account'; @@ -278,13 +290,13 @@ export default class AccessHistoryModal extends React.Component { if (currentAudit.extra_info.indexOf('revoked_all=') >= 0) { currentAuditDesc = 'Revoked all current sessions for the team'; } else { - let currentActionDesc = ' '; + let currentActionDesc = ''; if (currentActionURL && currentActionURL.lastIndexOf('/') !== -1) { currentActionDesc = currentActionURL.substring(currentActionURL.lastIndexOf('/') + 1).replace('_', ' '); currentActionDesc = Utils.toTitleCase(currentActionDesc); } - let currentExtraInfoDesc = ' '; + let currentExtraInfoDesc = ''; if (currentAudit.extra_info) { currentExtraInfoDesc = currentAudit.extra_info; -- cgit v1.2.3-1-g7c22 From 04ddb3e1b3e4648790b396dba148cfae24a5802c Mon Sep 17 00:00:00 2001 From: Reed Garmsen Date: Wed, 14 Oct 2015 15:10:50 -0700 Subject: Properly handle missing session IDs regardless of case --- web/react/components/access_history_modal.jsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'web/react/components') diff --git a/web/react/components/access_history_modal.jsx b/web/react/components/access_history_modal.jsx index 58523feeb..909639859 100644 --- a/web/react/components/access_history_modal.jsx +++ b/web/react/components/access_history_modal.jsx @@ -330,11 +330,15 @@ export default class AccessHistoryModal extends React.Component { ); if (this.state.moreInfo[i]) { - if (!currentAudit.session_id && currentAudit.action.search('/users/login') !== -1) { - if (currentAudit.extra_info === 'attempt') { - currentAudit.session_id = 'N/A (Login attempt)'; - } else { - currentAudit.session_id = 'N/A (Login failure)'; + if (!currentAudit.session_id) { + currentAudit.session_id = 'N/A'; + + if (currentAudit.action.search('/users/login') >= 0) { + if (currentAudit.extra_info === 'attempt') { + currentAudit.session_id += ' (Login attempt)'; + } else { + currentAudit.session_id += ' (Login failure)'; + } } } -- cgit v1.2.3-1-g7c22