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

logout and hasPermission updates #1290

Merged
merged 5 commits into from
Aug 15, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 0 additions & 4 deletions client/modules/accounts/templates/dropdown/dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ Template.loginDropdown.events({
if (error) {
Logger.warn("Failed to logout.", error);
}
// go home on logout
Reaction.Subscriptions.Manager.reset();
Reaction.Router.reload();
Reaction.Router.go("/");
});
},

Expand Down
120 changes: 80 additions & 40 deletions client/modules/core/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Logger from "/client/modules/logger";
import { Countries } from "/client/collections";
import { localeDep } from "/client/modules/i18n";
import { Packages, Shops } from "/lib/collections";
import { Router } from "/client/modules/router";

/**
* Reaction namespace
Expand Down Expand Up @@ -77,56 +78,95 @@ export default {
hasPermission(checkPermissions, checkUserId, checkGroup) {
let group = this.getShopId();
let permissions = ["owner"];
let id = "";
const userId = checkUserId || this.userId || Meteor.userId();
//
// local roleCheck function
// is the bulk of the logic
// called out a userId is validated.
//
function roleCheck() {
// permissions can be either a string or an array
// we'll force it into an array and use that
if (checkPermissions === undefined) {
permissions = ["owner"];
} else if (typeof checkPermissions === "string") {
permissions = [checkPermissions];
} else {
permissions = checkPermissions;
}
// if the user has admin, owner permissions we'll always check if those roles are enough
permissions.push("owner");
permissions = _.uniq(permissions);

// default group to the shop or global if shop
// isn't defined for some reason.
if (checkGroup !== undefined && typeof checkGroup === "string") {
group = checkGroup;
}
if (!group) {
group = Roles.GLOBAL_GROUP;
//
// return if user has permissions in the group
//
if (Roles.userIsInRole(userId, permissions, group)) {
return true;
}
// global roles check
let sellerShopPermissions = Roles.getGroupsForUser(userId, "admin");
// we're looking for seller permissions.
if (sellerShopPermissions) {
// loop through shops roles and check permissions
for (let key in sellerShopPermissions) {
if (key) {
let shop = sellerShopPermissions[key];
if (Roles.userIsInRole(userId, permissions, shop)) {
return true;
}
}
}
}
// no specific permissions found returning false
return false;
}

// use current user if userId if not provided
// becauase you gotta have a user to check permissions
const userId = checkUserId || this.userId || Meteor.userId();
if (!userId) {
//
// check if a user id has been found
// in line 156 setTimeout
//
function validateUserId() {
if (Meteor.userId()) {
Meteor.clearTimeout(id);
Router.reload();
return roleCheck();
}
return false;
}
// permissions can be either a string or an array
// we'll force it into an array and use that
if (checkPermissions === undefined) {
permissions = ["owner"];
} else if (typeof checkPermissions === "string") {
permissions = [checkPermissions];
} else {
permissions = checkPermissions;
}
// if the user has admin, owner permissions we'll always check if those roles are enough
permissions.push("owner");
permissions = _.uniq(permissions);

//
// return if user has permissions in the group
// actual logic block to check permissions
// we'll bypass unecessary checks during
// a user logging, as we'll check again
// when everything is ready
//
if (Roles.userIsInRole(userId, permissions, group)) {
return true;
}
// global roles check
let sellerShopPermissions = Roles.getGroupsForUser(userId, "admin");
// we're looking for seller permissions.
if (sellerShopPermissions) {
// loop through shops roles and check permissions
for (let key in sellerShopPermissions) {
if (key) {
let shop = sellerShopPermissions[key];
if (Roles.userIsInRole(userId, permissions, shop)) {
return true;
}
}
if (Meteor.loggingIn() === false) {
//
// this userId check happens because when logout
// occurs it takes a few cycles for a new anonymous user
// to get created and during this time the user has no
// permission, not even guest permissions so we
// need to wait and reload the routes. This
// mainly affects the logout from dashboard pages
//
if (!userId) {
id = Meteor.setTimeout(validateUserId, 5000);
} else {
return roleCheck();
}

// default group to the shop or global if shop
// isn't defined for some reason.
if (checkGroup !== undefined && typeof checkGroup === "string") {
group = checkGroup;
}
if (!group) {
group = Roles.GLOBAL_GROUP;
}
}
// no specific permissions found returning false
// return false to be safe
return false;
},

Expand Down
11 changes: 6 additions & 5 deletions client/modules/core/subscriptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@ Subscriptions.Account = Subscriptions.Manager.subscribe("Accounts", Meteor.userI
/**
* General Subscriptions
*/
Subscriptions.Shops = Meteor.subscribe("Shops");
Subscriptions.Shops = Subscriptions.Manager.subscribe("Shops");

Subscriptions.Packages = Meteor.subscribe("Packages");
Subscriptions.Packages = Subscriptions.Manager.subscribe("Packages");

Subscriptions.Tags = Meteor.subscribe("Tags");
Subscriptions.Tags = Subscriptions.Manager.subscribe("Tags");

Subscriptions.Media = Meteor.subscribe("Media");
Subscriptions.Media = Subscriptions.Manager.subscribe("Media");

// admin only
// todo should we put this inside autorun and detect user changes
Subscriptions.Inventory = Meteor.subscribe("Inventory");
Subscriptions.Inventory = Subscriptions.Manager.subscribe("Inventory");

/**
* Subscriptions that need to reload on new sessions
Expand Down Expand Up @@ -70,4 +70,5 @@ Tracker.autorun(() => {
sessionId = Session.get("sessionId");
});
Subscriptions.Cart = Meteor.subscribe("Cart", sessionId, Meteor.userId());
Subscriptions.UserProfile = Meteor.subscribe("UserProfile", Meteor.userId());
});
11 changes: 6 additions & 5 deletions client/modules/router/main.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import _ from "lodash";
import { Session } from "meteor/session";
import { Meteor } from "meteor/meteor";
import { Tracker } from "meteor/tracker";
import { FlowRouter as Router } from "meteor/kadira:flow-router-ssr";
import { BlazeLayout } from "meteor/kadira:blaze-layout";
import { Reaction, Logger } from "/client/api";
import { Packages, Shops } from "/lib/collections";
import { MetaData } from "/lib/api/router/metadata";
import { Session } from "meteor/session";
import { Meteor } from "meteor/meteor";
import { Tracker } from "meteor/tracker";
import Hooks from "./hooks";


Expand All @@ -27,6 +28,7 @@ Router.Hooks = Hooks;
*/
function checkRouterPermissions(context) {
const routeName = context.route.name;

if (Reaction.hasPermission(routeName, Meteor.userId())) {
if (context.unauthorized === true) {
delete context.unauthorized;
Expand Down Expand Up @@ -171,7 +173,7 @@ Router.initPackageRoutes = () => {
//
// index / home route
// to overide layout, ie: home page templates
// set DEFAULT_LAYOUT, in config.js
// set INDEX_OPTIONS, in config.js
//
shop.route("/", {
name: "index",
Expand Down Expand Up @@ -256,7 +258,6 @@ Router.initPackageRoutes = () => {
Router.initialize();
} catch (e) {
Logger.error(e);
Router.reload();
}
}
};
Expand Down
13 changes: 13 additions & 0 deletions client/modules/router/startup.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,17 @@ Meteor.startup(function () {
}
}
});

//
// we need to sometimes force
// router reload on login to get
// the entire layout to rerender
// we only do this when the routes table
// has already been generated (existing user)
//
Accounts.onLogin(() => {
if (Meteor.loggingIn() === false && Router._routes.length > 0) {
Router.reload();
}
});
});