Skip to content

Commit

Permalink
Merge branch 'master' of github.com:vienthuong/Impersonation
Browse files Browse the repository at this point in the history
  • Loading branch information
vienthuong committed Aug 27, 2020
2 parents 98dd21c + 4d9000d commit 03f6aff
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -1,30 +1,45 @@
import template from './sw-page.html.twig';
import './sw-page.scss';
import initializeUserContext from 'src/app/init-post';
import { IMPERSONATING_ATTRIBUTE_KEY } from '../../../../constant/impersonation.constant';

const { Component } = Shopware;
const { Component, State, Service } = Shopware;

Component.override('sw-page', {
template,

data() {
return {
isLoading: false
}
},

computed: {
currentUser() {
return State.get('session').currentUser;
},

pageClasses() {
const classes = this.$super('pageClasses');
classes['has--leave-impersonation-button'] = this.isImpersonating;
return classes;
},

impersonationService() {
return Service('impersonationService');
},

isImpersonating() {
return !!localStorage.getItem(IMPERSONATING_ATTRIBUTE_KEY);
return this.impersonationService.isImpersonating();
}

},

methods: {
async leaveImpersonation() {
localStorage.removeItem(IMPERSONATING_ATTRIBUTE_KEY);
this.isLoading = true;

await this.impersonationService.leaveImpersonation();

await initializeUserContext.userInformation();
this.isLoading = false;

if (this.$route.name === 'sw.users.permissions.index') {
this.$router.go();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
<div class="sw-page__top-bar-actions" :style="topBarActionStyles">
{% block sw_page_leave_impersonation_button %}
<sw-button v-if="isImpersonating"
class="impersonation-btn"
variant="danger"
@click="leaveImpersonation">
{{ $tc('impersonation.actions.leaveImpersonation') }}
</sw-button>
size="x-small"
:disabled="isLoading"
:isLoading="isLoading"
@click="leaveImpersonation">{{ $tc('impersonation.actions.leaveImpersonation') }}</sw-button>
{% endblock %}

{% block sw_page_notification_center %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,20 @@
justify-content: space-evenly;
align-items: center;

.impersonation-btn {
z-index: 800;
max-width: 100px;
margin-right: 10px;

.sw-button__content {
word-break: break-word;
white-space: pre-wrap;
}
}

@media screen and (max-width: 700px) {
button {
z-index: 800;
.impersonation-btn {
max-width: initial;
border-radius: 0;
position: fixed;
bottom: 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,34 @@
import template from './sw-users-permissions-user-listing.html.twig';
import initializeUserContext from 'src/app/init-post';
import { IMPERSONATING_ATTRIBUTE_KEY } from '../../../../../constant/impersonation.constant';
const { Component } = Shopware;
const { Component, Service, State } = Shopware;

const componentConfiguration = {
computed: {
impersonationService() {
return Service('impersonationService');
},

currentUser() {
return Shopware.State.get('session').currentUser;
return State.get('session').currentUser;
},

canImpersonate() {
return !!this.currentUser.admin;
},

isImpersonating() {
return this.impersonationService.isImpersonating();
}
},

methods: {
async impersonate(userId) {
if (!this.canImpersonate) {
return;
}

this.isLoading = true;

localStorage.setItem(IMPERSONATING_ATTRIBUTE_KEY, userId);
await initializeUserContext.userInformation();
await this.impersonationService.impersonate(userId);

this.isLoading = false;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

{% block sw_settings_user_list_actions_impersonate %}
<sw-context-menu-item
v-if="canImpersonate && !isImpersonating"
:disabled="currentUser.id === item.id"
class="sw-settings-user-list__user-view-action"
@click="impersonate(item.id)">
Expand Down
11 changes: 11 additions & 0 deletions src/Resources/app/administration/src/init/impersonation.init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { IMPERSONATING_ATTRIBUTE_KEY } from '../constant/impersonation.constant';
import ImpersonationService from '../service/impersonation.service';

const { State, Application } = Shopware;
const initContainer = Application.getContainer('init');
const currentUser = State.get('session').currentUser;
const httpClient = initContainer.httpClient;

Application.addServiceProvider('impersonationService', (container) => {
return new ImpersonationService(currentUser, container, httpClient);
});
2 changes: 1 addition & 1 deletion src/Resources/app/administration/src/main.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import './init/impersonate-service';
import './init/impersonation.init';
import './extension/module/sw-users-permissions/components/sw-users-permissions-user-listing';
import './extension/component/structure/sw-page';

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { initializeUserNotifications } from 'src/app/state/notification.store';
import {IMPERSONATING_ATTRIBUTE_KEY} from "../constant/impersonation.constant";
const { State } = Shopware;

class ImpersonationService {
constructor(impersonatingUser, container, httpClient) {
this.name = 'impersonationService';
const {userService, localeHelper, loginService} = container;

this.userService = userService;
this.localeHelper = localeHelper;
this.loginService = loginService;
this.impersonatingUser = impersonatingUser;
this.httpClient = httpClient;

this._initializeService();
}

async impersonate(userId) {
localStorage.setItem(IMPERSONATING_ATTRIBUTE_KEY, userId);

const response = await this.userService.getUser({}, {
[IMPERSONATING_ATTRIBUTE_KEY]: userId
});

const { data: { password, ...user } } = response;

await this._initializeUser(user);
}

async leaveImpersonation() {
localStorage.removeItem(IMPERSONATING_ATTRIBUTE_KEY);

await this._initializeUser(this.impersonatingUser);
}

isImpersonating() {
return !!localStorage.getItem(IMPERSONATING_ATTRIBUTE_KEY)
}

async _initializeUser(user) {
State.commit('setCurrentUser', user);

await this.localeHelper.setLocaleWithId(user.localeId);

State.commit('context/setApiLanguageId', State.get('session').languageId);

initializeUserNotifications();
}

_initializeService() {
this.httpClient.interceptors.request.use(config => {
if (this.isImpersonating()) {
config.headers = config.headers || {};
config.headers[IMPERSONATING_ATTRIBUTE_KEY] = localStorage.getItem(IMPERSONATING_ATTRIBUTE_KEY);
}

return config;
});

this._registerLogInListener();

if (this.isImpersonating()) {
this.impersonate(localStorage.getItem(IMPERSONATING_ATTRIBUTE_KEY));
}
}
_registerLogInListener() {
this.loginService.addOnLoginListener(async () => {
if (this.isImpersonating()) {
await this.leaveImpersonation();
}
});
}
}

export default ImpersonationService;
2 changes: 1 addition & 1 deletion src/Resources/public/administration/css/impersonation.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/Resources/public/administration/js/impersonation.js

Large diffs are not rendered by default.

0 comments on commit 03f6aff

Please sign in to comment.