diff --git a/backend.dockerfile b/backend.dockerfile index ec04ec9..7bd6acf 100644 --- a/backend.dockerfile +++ b/backend.dockerfile @@ -18,6 +18,9 @@ ARG WP_SECURE_AUTH_SALT ARG WP_LOGGED_IN_SALT ARG WP_NONCE_SALT ARG WP_JWT_AUTH_SECRET_KEY +ARG WP_SENDGRID_API_KEY +ARG WP_SENDGRID_FROM_EMAIL +ARG WP_SENDGRID_FROM_NAME ENV WP_ENV ${WP_ENV} ENV WP_HOME ${API_URL} @@ -37,6 +40,10 @@ ENV WP_LOGGED_IN_SALT ${WP_LOGGED_IN_SALT} ENV WP_NONCE_SALT ${WP_NONCE_SALT} ENV WP_JWT_AUTH_SECRET_KEY ${WP_JWT_AUTH_SECRET_KEY} +ENV WP_SENDGRID_API_KEY ${WP_SENDGRID_API_KEY} +ENV WP_SENDGRID_FROM_EMAIL ${WP_SENDGRID_FROM_EMAIL} +ENV WP_SENDGRID_FROM_NAME ${WP_SENDGRID_FROM_NAME} + ENV WIAAS_CUSTOMER_INTERFACE ${WIAAS_CUSTOMER_INTERFACE} RUN apt-get update && apt-get install -y git unzip gnupg mysql-client sudo @@ -52,6 +59,7 @@ RUN chmod +x /init-scripts/setup.sh RUN docker-php-ext-install pdo pdo_mysql mysqli RUN a2enmod rewrite ssl +COPY docker/php/000-default.conf /etc/apache2/sites-available COPY backend /home/wiaas/backend @@ -62,6 +70,8 @@ WORKDIR /home/wiaas RUN rm -rf backend/app/uploads RUN cp -r backend/* /var/www/html/ +WORKDIR home +RUN rm -rf wiaas WORKDIR /var/www/html RUN ln -s ../html api diff --git a/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-organization.php b/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-organization.php index 708083f..c063411 100644 --- a/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-organization.php +++ b/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-organization.php @@ -226,7 +226,7 @@ class Wiaas_Admin_Organization { // get current user $current_user = wp_get_current_user(); - update_user_meta($current_user->ID, '_wiaas_current_user_admin_role', $role->name); + update_user_meta($current_user->ID, '_wiaas_admin_role', $role->name); // switch user role $current_user->set_role($role->name); diff --git a/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-product.php b/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-product.php index 9e9a047..532ebb3 100644 --- a/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-product.php +++ b/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-product.php @@ -107,10 +107,6 @@ class Wiaas_Admin_Product { $value = get_field('_wiaas_product_country', $post_id, true); $type = get_field('_wiaas_product_type', $post_id, true); - error_log($status); - error_log($value); - - if (!empty($value) && $status === '_wiaas_no_country' ) { wp_set_object_terms($post_id, $value, 'product_country', true); diff --git a/backend/app/plugins/wiaas/includes/admin/pricing/class-wiaas-admin-package-pricing.php b/backend/app/plugins/wiaas/includes/admin/pricing/class-wiaas-admin-package-pricing.php index 2db6915..0bca39d 100644 --- a/backend/app/plugins/wiaas/includes/admin/pricing/class-wiaas-admin-package-pricing.php +++ b/backend/app/plugins/wiaas/includes/admin/pricing/class-wiaas-admin-package-pricing.php @@ -148,6 +148,8 @@ class Wiaas_Admin_Package_Pricing { $pricing_rules, $commission, $max_cost_margin); + + Wiaas_Access_Management::maybe_handle_product_access($package_id, get_post($package_id)); } } diff --git a/backend/app/plugins/wiaas/includes/api/class-wiaas-rest-delivery-process-api.php b/backend/app/plugins/wiaas/includes/api/class-wiaas-rest-delivery-process-api.php index de409a7..76416f8 100644 --- a/backend/app/plugins/wiaas/includes/api/class-wiaas-rest-delivery-process-api.php +++ b/backend/app/plugins/wiaas/includes/api/class-wiaas-rest-delivery-process-api.php @@ -31,6 +31,7 @@ class Wiass_REST_Delivery_Process_API { register_rest_route( self::$namespace, 'next-delivery-steps', array( 'methods' => 'GET', 'callback' => array(__CLASS__, 'get_next_actions_for_user'), + 'permission_callback' => 'is_user_logged_in' ) ); register_rest_route( self::$namespace, 'customer-acceptance/(?P\d+)', array( diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-authentication.php b/backend/app/plugins/wiaas/includes/class-wiaas-authentication.php index 45c2045..c49c0f1 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-authentication.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-authentication.php @@ -9,192 +9,165 @@ */ class Wiaas_Authentication { - const SUPER_ADMIN_USER_ID = 1; + const SUPER_ADMIN_USER_ID = 1; - public static function init() { - // authenticate current user - add_action('determine_current_user', array(__CLASS__, 'authenticate_current_user'), 999); + public static function init() { + // authenticate current user + add_action('determine_current_user', array(__CLASS__, 'authenticate_current_user'), 999); - // authenticates user on login - add_filter( 'authenticate', array( __CLASS__, 'authenticate_user_on_login' ), 999, 3); + // authenticates user on login + add_filter( 'authenticate', array( __CLASS__, 'authenticate_user_on_login' ), 999, 3); - // retrieve preferred user role for user - add_filter('get_user_metadata', array(__CLASS__, 'maybe_filter_user_roles'), 10, 3); + add_filter('jwt_auth_token_before_dispatch', array(__CLASS__, 'authenticate_rest_user_on_login'), 999, 2); - // redirect to dashboard after login - add_filter( 'login_redirect', array( __CLASS__, 'login_redirect' ) ); + // redirect to dashboard after login + add_filter( 'login_redirect', array( __CLASS__, 'login_redirect' ) ); + } - // add role selector to login form - add_action('login_form', array(__CLASS__, 'pick_role_on_login')); - } - - /** - * Redirect admin user to dashboard - * - * @return string - */ - public static function login_redirect() { - return admin_url('index.php') ; - } - - /** - * Add role selector to login form - */ - public static function pick_role_on_login() { - ?> -

-

- ID === 1 || $is_rest_api) { - return $user; - } + if ( empty($role) || ! user_can($user_id, 'wiaas_' . $role)) { + // not available roles for user + $current_user->set_role(''); - if (empty($_POST['role'])) { - return new WP_Error('error', 'You must selected role to login!'); - } + return new WP_Error('wiaas_authentication_error', 'No set permissions!'); + } - // get selected role - $requested_role = sanitize_key($_POST['role']); + // authenticate valid admin panel user + $current_user->set_role($role); - // validate can user have requested role - $result = self::_can_user_have_role($user->ID, $requested_role, false); + return $user_id; + } - // if user organization has no requested role prevent access - if (is_wp_error($result)) { - return $result; - } - - // remember role for user and continue - update_user_meta($user->ID, '_wiaas_current_user_admin_role', $requested_role); - - return $user; - } + /** + * Authenticate wiaas user on login based on roles assigned to organization + * + * If this is non admin panel request authenticate user if he can be customer. + * + * If this is admin panel login request user will be authenticated with previously selected or first available role + * from his organization roles. + * + * @param WP_User $user + * @return WP_User|WP_Error + */ + public static function authenticate_user_on_login($user) { + // do nothing if there is an error already, + // user is super admin + if (is_wp_error($user) || $user->ID === self::SUPER_ADMIN_USER_ID ) { + return $user; + } - /** - * - * Filters user roles retrieval so that selected user role is retrieved for admin panel - * and customer role is retrieved for JSON API request - * - * @param $null - * @param int $user_id - * @param string $meta_key - * @return array|null - */ - public static function maybe_filter_user_roles($null, $user_id, $meta_key) { - - global $wpdb; - - if ($user_id !== 0 && $user_id !== self::SUPER_ADMIN_USER_ID && $meta_key === $wpdb->get_blog_prefix() . 'capabilities') { - - $is_rest_api = strpos($_SERVER['REQUEST_URI'], rest_get_url_prefix()); - - $role = $is_rest_api ? - 'customer' : - get_user_meta($user_id, '_wiaas_current_user_admin_role', true); - - return array( array ( "$role" => true )); - } - - return null; - } + $rest_api_slug = rest_get_url_prefix(); + $valid_api_uri = strpos($_SERVER['REQUEST_URI'], $rest_api_slug); + /** + * CUSTOMER API AUTHENTICATION + */ + // validate customer user login + if ($valid_api_uri) { - // PRIVATE + $role = user_can($user->ID, 'wiaas_customer') ? 'customer' : ''; + $user->set_role($role); - /** - * Determines if user can have requested role based on his organization roles - * - * @param int $user_id - * @param string $user_role - * @param bool $is_rest_api - * @return bool|WP_Error - */ - private static function _can_user_have_role($user_id, $user_role, $is_rest_api) { - // check if role valid for access - if (! wp_roles()->is_role($user_role)) { - return new WP_Error('error', 'Role is not valid!'); - } + return empty($role) ? + new WP_Error('wiaas_authentication_error', 'No Customer permissions!') : + $user; + } - // only customer role can access API - if ($is_rest_api && $user_role !== 'customer') { - return new WP_Error('error', 'No access!'); - } + /** + * ADMIN PANEL AUTHENTICATION + */ - // customer role cannot access admin backend - if (! $is_rest_api && $user_role === 'customer') { - return new WP_Error('error', 'No access!'); - } + // retrieve selected role for user + $role = get_user_meta($user->ID, '_wiaas_admin_role', true); + // if user has selected role then use it + if (! empty($role) && user_can($user->ID, 'wiaas_' . $role)) { + return $user; + } - // import organization functions (during user authentication it is not yet loaded) - require_once dirname( __FILE__ ) . '/user/wiaas-organization-functions.php'; + // user does not have selected role so try to assign one in order of access + if (user_can($user->ID, 'wiaas_administrator')) { + $role = 'administrator'; + } else if (user_can($user->ID, 'wiaas_commercial_lead')) { + $role = 'commercial_lead'; + } else if (user_can($user->ID, 'wiaas_supplier')) { + $role = 'supplier'; + } - // get user organization - $organization_id = wiaas_get_user_organization_id($user_id); + if (empty($role)) { + return new WP_Error('wiaas_authentication_error', 'No permissions!'); + } - // validate if user has organization - if (empty( $organization_id)) { - return new WP_Error('error', 'Account not completed!'); - } - // get organization roles - $roles = wiaas_get_organization_roles($organization_id); + update_user_meta($user->ID, '_wiaas_admin_role', $role); - // validate if user has organization roles - if (!in_array($user_role, $roles)) { - return new WP_Error( 'error', 'Your account is not authorized for requested role. Please contact us for help.' ); - } + $user->set_role($role); + + return $user; + } + + /** + * validate that successfully logged in rest api user can be customer + * + * @param array $data + * @param WP_User $user + * @return array | WP_Error + * + */ + + public static function authenticate_rest_user_on_login($data, $user) { + $role = user_can($user->ID, 'wiaas_customer') ? 'customer' : ''; + $user->set_role($role); + + return empty($role) ? + new WP_Error('wiaas_authentication_error', 'No Customer permissions!') : + $data; + } - return true; - } } Wiaas_Authentication::init(); diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-db-update.php b/backend/app/plugins/wiaas/includes/class-wiaas-db-update.php index 876ea6e..f53db56 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-db-update.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-db-update.php @@ -5,7 +5,6 @@ defined( 'ABSPATH' ) || exit; class Wiaas_DB_Update { private static $db_updates = array( - '20180728222206' => 'wiaas_db_update_enable_product_by_user_role', '20180801222206' => 'wiaas_db_update_setup_gravity', '20180802222206' => 'wiaas_db_update_add_delivery_process_forms', '20180811134511' => 'wiaas_db_update_enable_orders_access_management', @@ -13,18 +12,19 @@ class Wiaas_DB_Update { '20180826153509' => 'wiaas_create_broker_access_group', '20180911101010' => 'wiaas_db_setup_exclusive_taxonomies', '20181003164100' => 'wiaas_db_setup_customer_capabilities', - '201810121644700' => 'wiaas_db_update_add_user_organization_ui_fields', - '201810171645700' => 'wiaas_db_update_create_default_roles', - '201810171745700' => 'wiaas_db_import_aam_role_settings', - '201810180145700' => 'wiaas_db_update_update_supplier_capabilities', - '201810180245700' => 'wiaas_db_update_update_admin_capabilities', - '201810180345700' => 'wiaas_create_role_access_groups', - '201810180444700' => 'wiaas_db_setup_create_customer_commercial_lead_table', - '201810180544702' => 'wiaas_db_update_update_commercial_lead_capabilities', - '201810180644703' => 'wiaas_db_update_add_organization_info_ui_fields', - '201910190145700' => 'wiaas_db_update_add_general_ui_fields', - '201910190146700' => 'wiaas_db_update_add_product_properties_ui_fields', - '201810190644704' => 'wiaas_db_update_add_reference_ui_field' + '20181012164450' => 'wiaas_db_update_add_user_organization_ui_fields', + '20181017164550' => 'wiaas_db_update_create_default_roles', + '20181017174550' => 'wiaas_db_import_aam_role_settings', + '20181018014550' => 'wiaas_db_update_update_supplier_capabilities', + '20181018024550' => 'wiaas_db_update_update_admin_capabilities', + '20181018034550' => 'wiaas_admin_create_role_access_groups', + '20181018044450' => 'wiaas_db_setup_create_customer_commercial_lead_table', + '20181018054450' => 'wiaas_db_update_update_commercial_lead_capabilities', + '20181018064450' => 'wiaas_db_update_add_organization_info_ui_fields', + '20191019014550' => 'wiaas_db_update_add_general_ui_fields', + '20191019014650' => 'wiaas_db_update_add_product_properties_ui_fields', + '20181019064450' => 'wiaas_db_update_add_reference_ui_field', + '20191020014650' => 'wiaas_create_organization_roles_capabilities' ); public static function execute() { diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-shop.php b/backend/app/plugins/wiaas/includes/class-wiaas-shop.php index 073ddb6..fe0d1cc 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-shop.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-shop.php @@ -19,9 +19,9 @@ class Wiaas_Shop { // update prices search terms for package after prices extras have been updated add_action('wiaas_package_prices_extras_set', array(__CLASS__, 'update_package_prices_search_terms'), 10, 4); - // create new shop if organization was assigned commercial lead role - // or remove shop if commercial lead role was removed for organization - add_action('wiaas_organization_roles_updated', array(__CLASS__, 'maybe_manage_shop_for_commercial_lead'), 10, 2); + // remove customer shop relationships for all deactivated and removed shops + add_action('wiaas_organization_roles_updated', array(__CLASS__, 'remove_deactivated_shop')); + add_action('wiaas_organization_deleted', array(__CLASS__, 'remove_shop')); } public static function get_shop_customers($owner_id) { @@ -86,18 +86,24 @@ class Wiaas_Shop { } /** - * Creates shop for new shop owner (organization with commercial lead role) or - * deletes existing shop if that role has been removed + * Remove shop for organization that is no longer commercial lead * * @param int $owner_id - * @param array $roles */ - public static function maybe_manage_shop_for_commercial_lead($owner_id, $roles) { - $is_commercial_lead = in_array('commercial_lead', $roles); + public static function remove_deactivated_shop($owner_id) { + $roles = wiaas_get_organization_roles($owner_id); - $is_commercial_lead ? - self::_maybe_create_shop($owner_id) : - self::_maybe_remove_shop($owner_id); + if (! in_array('commercial_lead', $roles)) { + self::remove_shop($owner_id); + } + } + + /** + * remove shop + * @param int $owner_id + */ + public static function remove_shop($owner_id) { + Wiaas_Shop_DB::remove_shop($owner_id); } /** @@ -132,7 +138,7 @@ class Wiaas_Shop { * $extra_price_payment_type => { * @type bool visible Indicates if payment type is visible to customer * } - * } + * } * @param array $old_cl_extras { * $extra_price_payment_type => { * @type bool visible Indicates if payment type is visible to customer @@ -156,49 +162,6 @@ class Wiaas_Shop { // PRIVATE - /** - * Each shop will be registered as product attribute. - * This will persist shops information into database. - * Also every attribute has taxonomy associated with it which will enable us to have multiple - * catalogues in one shop - * - * @param int $owner_id - */ - private static function _maybe_create_shop($owner_id) { - $shop_name = 'wiaas_shop_' . $owner_id; - - $attribute_id = wc_attribute_taxonomy_id_by_name($shop_name); - - if ($attribute_id === 0) { - // create shop attribute - wc_create_attribute(array( 'slug' => $shop_name, 'name' => 'Shop' )); - - $taxonomy_name = wc_attribute_taxonomy_name($shop_name); - - // since attribute taxonomies are registered once on load - // we will register new attribute taxonomy here so default catalogue can be added - register_taxonomy($taxonomy_name, array('product')); - - // add default catalogue option to shop - wp_insert_term( 'Default Catalogue', $taxonomy_name); - } - } - - /** - * Deleted associated attribute for shop. This will effectively remove shop and all of its potential catalogues - * - * @param int $owner_id - */ - private static function _maybe_remove_shop($owner_id) { - // get corresponding attribute for shop - $attribute_id = wc_attribute_taxonomy_id_by_name('wiaas_shop_' . $owner_id); - - // if shop attribute exists then remove it - if ($attribute_id > 0) { - wc_delete_attribute($attribute_id); - } - } - /** * Generate search terms from cl extras * @@ -242,7 +205,7 @@ class Wiaas_Shop { foreach ($cl_extras_per_customer as $customer_id => $visible) { $terms[] = '_' . $owner_id . '_customer_' . $customer_id . '_' . - ($visible ? 'visible' : 'hidden'); + ($visible ? 'visible' : 'hidden'); } return $terms; diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-user.php b/backend/app/plugins/wiaas/includes/class-wiaas-user.php index 24f3bd5..fb7e22a 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-user.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-user.php @@ -58,6 +58,10 @@ class Wiaas_User { * @return mixed */ public static function transform_jwt_token_response($data, $user) { + if (is_wp_error($data)) { + return $data; + } + return new WP_REST_Response(array( 'token' => $data['token'], 'userInfo' => array( diff --git a/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-general.php b/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-general.php index e5a7c42..011e8b4 100644 --- a/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-general.php +++ b/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-general.php @@ -6,14 +6,6 @@ * General functions for updating wiaas database to latest version */ - -/** - * Enable restricting visibility by user roles for products - */ -function wiaas_db_update_enable_product_by_user_role() { - update_option('wcj_product_by_user_role_enabled', 'yes'); -} - function wiaas_db_update_setup_gravity() { // Gravity Form settings update_option('gform_pending_installation', false); @@ -145,4 +137,12 @@ function wiaas_db_setup_create_customer_commercial_lead_table() { "; dbDelta( $sql ); +} + + +function wiaas_create_organization_roles_capabilities() { + $roles = array( 'commercial_lead', 'supplier', 'customer', 'administrator'); + foreach ($roles as $role) { + Groups_Capability::create( array( 'capability' => 'wiaas_' . $role )); + } } \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-roles.php b/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-roles.php index 19488c6..c1ae6ff 100644 --- a/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-roles.php +++ b/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-roles.php @@ -10,126 +10,269 @@ function wiaas_db_update_create_default_roles() { - $roles = array( - 'customer', // this role will be created by woocommerce so we do not have to create it here - 'supplier', - 'commercial_lead' - ); + $roles = array( + 'customer', // this role will be created by woocommerce so we do not have to create it here + 'supplier', + 'commercial_lead' + ); - // remove wordpress default roles - remove_role('author'); - remove_role('contributor'); - remove_role('editor'); - remove_role('subscriber'); + // remove wordpress default roles + remove_role('author'); + remove_role('contributor'); + remove_role('editor'); + remove_role('subscriber'); - // remove woocoommerce shop manager role - remove_role('shop_manager'); + // remove woocoommerce shop manager role + remove_role('shop_manager'); - // Dummy gettext calls to get strings in the catalog. - /* translators: user role */ - _x( 'Supplier', 'User role', 'wiaas' ); - /* translators: user role */ - _x( 'Commercial Lead', 'User role', 'wiaas' ); + // Dummy gettext calls to get strings in the catalog. + /* translators: user role */ + _x( 'Supplier', 'User role', 'wiaas' ); + /* translators: user role */ + _x( 'Commercial Lead', 'User role', 'wiaas' ); - // Add wiaas roles - add_role( - 'commercial_lead', - array( - 'read' => true, - ) - ); + // Add wiaas roles + add_role( + 'commercial_lead', + 'Commercial Lead', + array( + 'read' => true, + ) + ); - add_role( - 'supplier', - array( - 'read' => true, - ) - ); + add_role( + 'supplier', + 'Supplier', + array( + 'read' => true, + ) + ); - add_role( - 'user', - array( - 'read' => true - ) - ); + add_role( + 'user', + 'User', + array( + 'read' => true + ) + ); - // set default wiaas role - update_option('default_role', 'user'); + // set default wiaas role + update_option('default_role', 'user'); - // capabilities + // capabilities - $capabilities = array(); + $capabilities = array(); - $capability_types = array( 'wiaas_doc' ); + $capability_types = array( 'wiaas_doc' ); - foreach ( $capability_types as $capability_type ) { + foreach ( $capability_types as $capability_type ) { - $capabilities[ $capability_type ] = array( - // Post type. - "edit_{$capability_type}", - "read_{$capability_type}", - "delete_{$capability_type}", - "edit_{$capability_type}s", - "edit_others_{$capability_type}s", - "publish_{$capability_type}s", - "read_private_{$capability_type}s", - "delete_{$capability_type}s", - "delete_private_{$capability_type}s", - "delete_published_{$capability_type}s", - "delete_others_{$capability_type}s", - "edit_private_{$capability_type}s", - "edit_published_{$capability_type}s", + $capabilities[ $capability_type ] = array( + // Post type. + "edit_{$capability_type}", + "read_{$capability_type}", + "delete_{$capability_type}", + "edit_{$capability_type}s", + "edit_others_{$capability_type}s", + "publish_{$capability_type}s", + "read_private_{$capability_type}s", + "delete_{$capability_type}s", + "delete_private_{$capability_type}s", + "delete_published_{$capability_type}s", + "delete_others_{$capability_type}s", + "edit_private_{$capability_type}s", + "edit_published_{$capability_type}s", - // Terms. - "manage_{$capability_type}_terms", - "edit_{$capability_type}_terms", - "delete_{$capability_type}_terms", - "assign_{$capability_type}_terms", - ); - } + // Terms. + "manage_{$capability_type}_terms", + "edit_{$capability_type}_terms", + "delete_{$capability_type}_terms", + "assign_{$capability_type}_terms", + ); + } - foreach ( $capabilities as $cap_group ) { - foreach ( $cap_group as $cap ) { - wp_roles()->add_cap( 'administrator', $cap ); - wp_roles()->add_cap( 'commercial_lead', $cap ); - } - } + foreach ( $capabilities as $cap_group ) { + foreach ( $cap_group as $cap ) { + wp_roles()->add_cap( 'administrator', $cap ); + wp_roles()->add_cap( 'commercial_lead', $cap ); + } + } } function wiaas_db_import_aam_role_settings() { - // update role settings that are imported - $content = file_get_contents( dirname( __FILE__ ) . '/data/aam-settings.json' ); + // update role settings that are imported + $content = file_get_contents( dirname( __FILE__ ) . '/data/aam-settings.json' ); - $importer = new AAM_Core_Importer($content); + $importer = new AAM_Core_Importer($content); - $importer->run(); + $importer->run(); - // update toolbar settins manually since it does not get imported - update_option('aam_toolbar_default', array ( - 'about' => '1', - 'toolbar-wp-logo' => '1', - 'wporg' => '1', - 'documentation' => '1', - 'support-forums' => '1', - 'feedback' => '1', - 'toolbar-site-name' => '0', - 'view-site' => '1', - 'view-store' => '1', - 'toolbar-updates' => '1', - 'toolbar-comments' => '1', - 'toolbar-new-content' => '1', - 'new-post' => '1', - 'new-media' => '1', - 'new-page' => '1', - 'new-product' => '1', - 'new-shop_order' => '1', - 'new-shop_coupon' => '1', - 'new-wiaas_doc' => '1', - 'new-user' => '1', - 'gravityforms-new-form' => '1', - ) - ); + // update toolbar settins manually since it does not get imported + update_option('aam_toolbar_default', array ( + 'about' => '1', + 'toolbar-wp-logo' => '1', + 'wporg' => '1', + 'documentation' => '1', + 'support-forums' => '1', + 'feedback' => '1', + 'toolbar-site-name' => '0', + 'view-site' => '1', + 'view-store' => '1', + 'toolbar-updates' => '1', + 'toolbar-comments' => '1', + 'toolbar-new-content' => '1', + 'new-post' => '1', + 'new-media' => '1', + 'new-page' => '1', + 'new-product' => '1', + 'new-shop_order' => '1', + 'new-shop_coupon' => '1', + 'new-wiaas_doc' => '1', + 'new-user' => '1', + 'gravityforms-new-form' => '1', + ) + ); + + update_option('aam_menu_default', array ( + 'menu-edit.php' => '1', + 'edit.php' => '1', + 'post-new.php' => '1', + 'edit-tags.php?taxonomy=category' => '1', + 'edit-tags.php?taxonomy=post_tag' => '1', + 'menu-edit.php?post_type=page' => '1', + 'edit.php?post_type=page' => '1', + 'post-new.php?post_type=page' => '1', + 'menu-woocommerce' => '1', + 'woocommerce' => '1', + 'edit.php?post_type=shop_coupon' => '1', + 'edit-tags.php?taxonomy=shop_order_project' => '1', + 'wc-reports' => '1', + 'wc-settings' => '1', + 'wc-status' => '1', + 'wc-addons' => '1', + 'wcj-tools' => '1', + 'admin.php?page=wc-settings&tab=jetpack' => '1', + 'menu-themes.php' => '1', + 'themes.php' => '1', + 'customize.php' => '1', + 'widgets.php' => '1', + 'nav-menus.php' => '1', + 'custom-header' => '1', + 'menu-tools.php' => '1', + 'tools.php' => '1', + 'import.php' => '1', + 'export.php' => '1', + 'export_personal_data' => '1', + 'remove_personal_data' => '1', + 'menu-options-general.php' => '1', + 'options-general.php' => '1', + 'options-writing.php' => '1', + 'options-reading.php' => '1', + 'options-discussion.php' => '1', + 'options-media.php' => '1', + 'options-permalink.php' => '1', + 'privacy.php' => '1', + 'radio-buttons-for-taxonomies' => '1', + 'sendgrid-settings' => '1', + 'menu-plugins.php' => '1', + 'plugins.php' => '1', + 'plugin-install.php' => '1', + 'menu-groups-admin' => '1', + 'groups-admin' => '1', + 'groups-admin-capabilities' => '1', + 'groups-admin-options' => '1', + 'groups-admin-add-ons' => '1', + ) + ); + + update_option('aam-utilities', array( + 'core.settings.getStarted' => '0', + 'ui.settings.renderAccessActionLink' => '0', + 'core.settings.secureLogin' => '0', + 'core.settings.xmlrpc' => '0', + 'core.settings.cron' => '0', + 'core.settings.extensionSupport' => '0', + 'ui.settings.renderAccessMetabox' => '0', + 'core.settings.apiAccessControl' => '0', + 'core.settings.frontendAccessControl' => '0', + + )); + + update_option('aam_menu_role_administrator', array( + 'menu-edit.php' => '1', + 'edit.php' => '1', + 'post-new.php' => '1', + 'edit-tags.php?taxonomy=category' => '1', + 'edit-tags.php?taxonomy=post_tag' => '1', + 'menu-edit.php?post_type=page' => '1', + 'edit.php?post_type=page' => '1', + 'post-new.php?post_type=page' => '1', + 'menu-woocommerce' => '1', + 'woocommerce' => '1', + 'edit.php?post_type=shop_coupon' => '1', + 'edit-tags.php?taxonomy=shop_order_project' => '1', + 'wc-reports' => '1', + 'wc-settings' => '1', + 'wc-status' => '1', + 'wc-addons' => '1', + 'wcj-tools' => '1', + 'admin.php?page=wc-settings&tab=jetpack' => '1', + 'menu-themes.php' => '1', + 'themes.php' => '1', + 'customize.php' => '1', + 'widgets.php' => '1', + 'nav-menus.php' => '1', + 'custom-header' => '1', + 'menu-tools.php' => '1', + 'tools.php' => '1', + 'import.php' => '1', + 'export.php' => '1', + 'export_personal_data' => '1', + 'remove_personal_data' => '1', + 'menu-options-general.php' => '1', + 'options-general.php' => '1', + 'options-writing.php' => '1', + 'options-reading.php' => '1', + 'options-discussion.php' => '1', + 'options-media.php' => '1', + 'options-permalink.php' => '1', + 'privacy.php' => '1', + 'radio-buttons-for-taxonomies' => '1', + 'sendgrid-settings' => '1', + 'menu-plugins.php' => '1', + 'plugins.php' => '1', + 'plugin-install.php' => '1', + 'menu-groups-admin' => '1', + 'groups-admin' => '1', + 'groups-admin-capabilities' => '1', + 'groups-admin-options' => '1', + 'groups-admin-add-ons' => '1', + 'menu-edit-comments.php' => '1', + )); + + update_option('aam_metabox_default', array( + 'dashboard' => + array ( + 'rg_forms_dashboard' => '1', + 'dashboard_quick_press' => '1', + 'dashboard_primary' => '1', + 'woocommerce_dashboard_status' => '1', + 'dashboard_activity' => '1', + ), + )); + + update_option('aam_metabox_role_administrator', array( + 'dashboard' => + array ( + 'rg_forms_dashboard' => '1', + 'dashboard_quick_press' => '1', + 'dashboard_primary' => '1', + 'woocommerce_dashboard_status' => '1', + 'dashboard_activity' => '1', + 'dashboard_right_now' => '1', + ), + )); } function wiaas_db_update_update_commercial_lead_capabilities() { @@ -163,20 +306,8 @@ function wiaas_db_update_update_admin_capabilities() { } -function wiaas_create_role_access_groups() { +function wiaas_admin_create_role_access_groups() { Groups_Group::create(array( 'name' => 'admin', )); - - Groups_Group::create(array( - 'name' => 'commercial_lead', - )); - - Groups_Group::create(array( - 'name' => 'supplier', - )); - - Groups_Group::create(array( - 'name' => 'customer', - )); } \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/db/class-wiaas-shop-db.php b/backend/app/plugins/wiaas/includes/db/class-wiaas-shop-db.php index 9a41f73..83bbd75 100644 --- a/backend/app/plugins/wiaas/includes/db/class-wiaas-shop-db.php +++ b/backend/app/plugins/wiaas/includes/db/class-wiaas-shop-db.php @@ -154,4 +154,20 @@ class Wiaas_Shop_DB { return $shops; } + + /** + * Remove shop + * + * @param int $owner_id + */ + public static function remove_shop($owner_id) { + global $wpdb; + + $wpdb->query( + $wpdb->prepare( + "DELETE FROM {$wpdb->prefix}wiaas_shop_customer_relationships + WHERE shop_owner_id = %d", + $owner_id ) + ); + } } \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/user/class-wiaas-user-organization.php b/backend/app/plugins/wiaas/includes/user/class-wiaas-user-organization.php index 28253b8..d5bd1df 100644 --- a/backend/app/plugins/wiaas/includes/user/class-wiaas-user-organization.php +++ b/backend/app/plugins/wiaas/includes/user/class-wiaas-user-organization.php @@ -38,22 +38,22 @@ class Wiaas_User_Organization extends WP_User_Taxonomy { add_action( 'pre_delete_term', array( __CLASS__, 'on_taxonomy_term_will_be_deleted' ), 10, 2); add_action( 'delete_' . self::TAXONOMY_NAME, array( __CLASS__, 'on_organization_deleted' )); - add_action('acf/save_post', array(__CLASS__, 'on_organization_roles_maybe_updated')); + add_action('acf/save_post', array(__CLASS__, 'on_organization_roles_maybe_updated'), 20); add_action('set_object_terms', array( __CLASS__, 'on_taxonomy_term_assigned' ), 10, 4); add_action('deleted_term_relationships', array( __CLASS__, 'on_taxonomy_term_unassigned' ), 10, 3); // Remove bulk editor for organizations on users list - remove_filter( 'admin_notices', array( $this, 'bulk_notice')); - remove_filter( 'bulk_actions-users', array( $this, 'bulk_actions')); - remove_filter( 'bulk_actions-users', array( $this, 'bulk_actions_sort')); - remove_action( 'handle_bulk_actions-users', array( $this, 'handle_bulk_actions')); + remove_filter( 'admin_notices', array( $this, 'bulk_notice')); + remove_filter( 'bulk_actions-users', array( $this, 'bulk_actions')); + remove_filter( 'bulk_actions-users', array( $this, 'bulk_actions_sort')); + remove_action( 'handle_bulk_actions-users', array( $this, 'handle_bulk_actions')); - // remove default organization info from profiles - // it will be handled by custom fields - remove_action( 'show_user_profile', array( $this, 'edit_user_relationships' ), 99); - remove_action( 'edit_user_profile', array( $this, 'edit_user_relationships' ), 99 ); + // remove default organization info from profiles + // it will be handled by custom fields + remove_action( 'show_user_profile', array( $this, 'edit_user_relationships' ), 99); + remove_action( 'edit_user_profile', array( $this, 'edit_user_relationships' ), 99 ); } // hooks functions @@ -61,12 +61,16 @@ class Wiaas_User_Organization extends WP_User_Taxonomy { /** * Creates corresponding access group for newly created organizational term * - * @param $organization_id id of the organization term + * @param int $organization_id id of the organization term */ public static function on_organization_added($organization_id) { self::_create_organization_access_group($organization_id); do_action('wiaas_organization_created', $organization_id); + + $roles = wiaas_get_organization_roles($organization_id); + + self::_assign_organization_roles_capabilities($organization_id, $roles); } /** @@ -104,6 +108,11 @@ class Wiaas_User_Organization extends WP_User_Taxonomy { //get organization id $id = absint(str_replace('term_', '', $id)); + if ($id) { + + self::_assign_organization_roles_capabilities($id, $roles); + } + do_action('wiaas_organization_roles_updated', $id, $roles); } } @@ -153,7 +162,7 @@ class Wiaas_User_Organization extends WP_User_Taxonomy { */ public static function get_user_organization_id($user_id = null) { if (!isset($user_id)) { - $user_id = get_current_user_id(); + $user_id = get_current_user_id(); } $organization_id = get_user_meta($user_id, '_wiaas_organization_id', true); @@ -284,4 +293,33 @@ class Wiaas_User_Organization extends WP_User_Taxonomy { } } } + + /** + *Reflect organization roles in access group + * + * This will be used when assigning roles to user + * + * @param int $organization_id + * @param array $roles + */ + + private static function _assign_organization_roles_capabilities($organization_id, $roles) { + $access_group_id = self::_get_organization_access_group_id($organization_id); + + $all_roles = array( 'commercial_lead', 'supplier', 'customer', 'administrator'); + foreach ($all_roles as $role) { + $cap = Groups_Capability::read_by_capability('wiaas_' . $role); + + Groups_Group_Capability::delete($access_group_id, $cap->capability_id); + } + + foreach ($roles as $role) { + $cap = Groups_Capability::read_by_capability('wiaas_' . $role); + + Groups_Group_Capability::create(array( + 'group_id' => $access_group_id, + 'capability_id' => $cap->capability_id + )); + } + } } \ No newline at end of file diff --git a/backend/composer.json b/backend/composer.json index a811490..0055984 100644 --- a/backend/composer.json +++ b/backend/composer.json @@ -64,6 +64,7 @@ "wpackagist-plugin/radio-buttons-for-taxonomies": "1.8.3", "wpackagist-plugin/advanced-access-manager": "5.4.3.2", "wpackagist-plugin/advanced-custom-fields" : "5.7.7", + "wpackagist-plugin/sendgrid-email-delivery-simplified" : "1.11.8", "3rdparty/gravityforms": "*", "3rdparty/gravityflow": "*", @@ -100,6 +101,7 @@ "wp plugin activate radio-buttons-for-taxonomies", "wp plugin activate advanced-access-manager", "wp plugin activate advanced-custom-fields", + "wp plugin activate sendgrid-email-delivery-simplified", "wp plugin activate wiaas" ], "update-db": [ diff --git a/backend/composer.lock b/backend/composer.lock index 60488eb..c33147d 100644 --- a/backend/composer.lock +++ b/backend/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "da3d7fa874b9a31355d3c3d4df50ae94", + "content-hash": "857a647e51fe2f0aaa596a2d303c8b98", "packages": [ { "name": "3rdparty/gravityflow", @@ -494,11 +494,11 @@ "source": { "type": "svn", "url": "https://plugins.svn.wordpress.org/capability-manager-enhanced/", - "reference": "trunk" + "reference": "tags/1.5.9" }, "dist": { "type": "zip", - "url": "https://downloads.wordpress.org/plugin/capability-manager-enhanced.zip?timestamp=1532180189", + "url": "https://downloads.wordpress.org/plugin/capability-manager-enhanced.1.5.9.zip", "reference": null, "shasum": null }, @@ -628,6 +628,26 @@ "type": "wordpress-plugin", "homepage": "https://wordpress.org/plugins/radio-buttons-for-taxonomies/" }, + { + "name": "wpackagist-plugin/sendgrid-email-delivery-simplified", + "version": "1.11.8", + "source": { + "type": "svn", + "url": "https://plugins.svn.wordpress.org/sendgrid-email-delivery-simplified/", + "reference": "tags/1.11.8" + }, + "dist": { + "type": "zip", + "url": "https://downloads.wordpress.org/plugin/sendgrid-email-delivery-simplified.1.11.8.zip", + "reference": null, + "shasum": null + }, + "require": { + "composer/installers": "~1.0" + }, + "type": "wordpress-plugin", + "homepage": "https://wordpress.org/plugins/sendgrid-email-delivery-simplified/" + }, { "name": "wpackagist-plugin/woocommerce-gateway-paypal-express-checkout", "version": "1.5.6", diff --git a/backend/config/application.php b/backend/config/application.php index e5cb4f6..da02a01 100644 --- a/backend/config/application.php +++ b/backend/config/application.php @@ -20,7 +20,7 @@ define('WP_ENV', env('WP_ENV') ?: 'development'); $env_config = __DIR__ . '/environments/' . WP_ENV . '.php'; if (file_exists($env_config)) { - require_once $env_config; + require_once $env_config; } /** @@ -63,6 +63,15 @@ define('NONCE_SALT', env('WP_NONCE_SALT')); define('JWT_AUTH_SECRET_KEY', env('WP_JWT_AUTH_SECRET_KEY')); define('JWT_AUTH_CORS_ENABLE', true); +/** + * Emails + * + */ + +define('SENDGRID_API_KEY', env('WP_SENDGRID_API_KEY')); +define('SENDGRID_FROM_EMAIL', env('WP_SENDGRID_FROM_EMAIL') ?: 'info@wiaas.com'); +define('SENDGRID_FROM_NAME', env('WP_SENDGRID_FROM_NAME' ?: 'Wiaas')); + /** * Wiaas Env variables */ @@ -79,5 +88,5 @@ define('DISALLOW_FILE_EDIT', true); * Bootstrap WordPress */ if (!defined('ABSPATH')) { - define('ABSPATH', $webroot_dir . '/wp/'); + define('ABSPATH', $webroot_dir . '/wp/'); } \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 1338b0e..70658c0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -21,6 +21,9 @@ services: - WP_LOGGED_IN_SALT - WP_NONCE_SALT - WP_JWT_AUTH_SECRET_KEY + - WP_SENDGRID_API_KEY + - WP_SENDGRID_FROM_EMAIL + - WP_SENDGRID_FROM_NAME volumes: - ./log/backend/:/var/log/apache2/ - ./docker/backend/uploads/:/var/www/html/app/uploads/ diff --git a/docker/php/000-default.conf b/docker/php/000-default.conf new file mode 100644 index 0000000..a451e71 --- /dev/null +++ b/docker/php/000-default.conf @@ -0,0 +1,49 @@ + + # The ServerName directive sets the request scheme, hostname and port that + # the server uses to identify itself. This is used when creating + # redirection URLs. In the context of virtual hosts, the ServerName + # specifies what hostname must appear in the request's Host: header to + # match this virtual host. For the default virtual host (this file) this + # value is not decisive as it is used as a last resort host regardless. + # However, you must set it for any further virtual host explicitly. + #ServerName www.example.com + + ServerAdmin webmaster@localhost + DocumentRoot /var/www/html + + + Options FollowSymLinks Indexes + AllowOverride None + + RewriteEngine On + RewriteBase / + RewriteRule ^index\.php$ - [L] + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule . /wp/index.php [L] + RewriteCond %{HTTP:Authorization} ^(.*) + RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1] + + SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 + + + + # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, + # error, crit, alert, emerg. + # It is also possible to configure the loglevel for particular + # modules, e.g. + LogLevel emerg + + ErrorLog ${APACHE_LOG_DIR}/error.log + # Do not log every request + CustomLog /dev/null combined + + # For most configuration files from conf-available/, which are + # enabled or disabled at a global level, it is possible to + # include a line for only one particular virtual host. For example the + # following line enables the CGI configuration for this host only + # after it has been globally disabled with "a2disconf". + #Include conf-available/serve-cgi-bin.conf + + +# vim: syntax=apache ts=4 sw=4 sts=4 sr noet diff --git a/environment.env b/environment.env index 69147d7..de01d25 100644 --- a/environment.env +++ b/environment.env @@ -27,3 +27,8 @@ WP_LOGGED_IN_SALT=generate_me WP_NONCE_SALT=generate_me WP_JWT_AUTH_SECRET_KEY=generate_me + +# Emails +WP_SENDGRID_FROM_EMAIL=set_me +WP_SENDGRID_FROM_NAME=Wiaas +WP_SENDGRID_API_KEY=set_me diff --git a/frontend/src/helpers/HtmlClient.js b/frontend/src/helpers/HtmlClient.js index 482440e..2fdc7a5 100644 --- a/frontend/src/helpers/HtmlClient.js +++ b/frontend/src/helpers/HtmlClient.js @@ -1,7 +1,7 @@ import axios from 'axios'; import qs from 'qs'; import {updateMessages} from '../actions/notification/notificationActions'; -import {authActivity} from '../constants/authConstants'; +import {authActivity, LOGOUT} from '../constants/authConstants'; import {notificationMessages} from '../constants/notificationConstants'; import {store} from '../configureStore'; @@ -76,6 +76,35 @@ class HtmlClient { }); store.dispatch(updateMessages(messages)); return; + case 'rest_forbidden': case 'woocommerce_rest_cannot_view': + store.dispatch( { + type: LOGOUT, + isLoggedIn: false, + errorMessage: 'LOGGED_OUT' + }); + store.dispatch(updateMessages([{ code: 'error', message: `No permission!` }])); + return; + case '[jwt_auth] empty_username': + store.dispatch(updateMessages([{ code: 'error', message: `Empty username!` }])); + return; + case '[jwt_auth] invalid_username': + store.dispatch(updateMessages([{ code: 'error', message: `Invalid username!` }])); + return; + case '[jwt_auth] empty_password': + store.dispatch(updateMessages([{ code: 'error', message: `Empty password!` }])); + return; + case '[jwt_auth] incorrect_password': + store.dispatch(updateMessages([{ code: 'error', message: `Invalid password!` }])); + return; + case '[jwt_auth] wiaas_authentication_error': + store.dispatch( { + type: LOGOUT, + isLoggedIn: false, + errorMessage: 'LOGGED_OUT' + }); + store.dispatch(updateMessages([{ code: 'error', message: `No Customer permission!` }])); + return; + } } store.dispatch(updateMessages([{code:'error', message: 'HTML_ERROR'}], notificationMessages));