Skip to content

Commit

Permalink
2.5.0 Magento Plugin Update Add New Endpoints (#48)
Browse files Browse the repository at this point in the history
* Add a version endpoint

This endpoint should tell us what version of magento and our plugin is currently installed.

* Add endpoint for getting all product inventories

* Add pagination to response

* Add POST & GET

* Add Exceptions & Handler Plugin

The plugins work like wrappers

* Cannot use POST

There is a chance that the user hasn't set up their server to handle POST requests so instead of asking them to do more work we will switch this to just update records one at a time and handle it through query params.

* cleanup

* Break out inventory fetch and push

it turns out you can make post requests you just have to add a special header..

* Hide Status with in_stock

* Add Authorization to the plugin

* Fix API Authorization Plugin

It is now appropriately telling whether or not a user should have access to the resource.

* Add Orders Endpoint

* Add Gift Messages and Store Details

* Initial Attempt to wrangle sales orders export

* Remove Plugins in favor of abstract class

* Move Live to BaseController

* Introduce Traits

Added traits so classes that extend the base controllers don't need to constantly provide dependencies.

* Update order export

* Finish up SalesOrdersExport Mapping

* Update Inventory Fetch

Updating the inventory fetch method to match SEC

* Move Controllers

Trying to keep things more in line with SEC

* Add Order Source API Models

* Add Request Model

* Add Response Models

* Start Implementing Request & Response Values

* Migrate Inventory to use Wrappers

* ShipNotify implementation

* revert old ship notify

* Switch to Authorized Base Controller

* Bump Version

* Add Code Sniffer Fixes

* Update Github Action

* Update Github Action

* Update Action to consume report

* Fix Action

* Update Test Report

* Remove Reporting
  • Loading branch information
justin-robertson-git authored Oct 30, 2024
1 parent 296b341 commit dafc678
Show file tree
Hide file tree
Showing 109 changed files with 3,697 additions and 246 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/coding-standard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
on:
pull_request:
branches:
- master

jobs:
build:
runs-on: ubuntu-latest
steps:
# Step 1: Checkout the code
- name: Checkout code
uses: actions/checkout@v3

# Step 2: Set up Docker
- name: Generate CodeSniffer Report
uses: addnab/docker-run-action@v3
with:
image: markoshust/magento-php:8.3-fpm-2
options: -v ${{ github.workspace }}:/var/www/html/src/app/code/Auctane
run: |
composer require --dev magento/magento-coding-standard
composer config --no-plugins allow-plugins.dealerdirect/phpcodesniffer-composer-installer true
composer install
vendor/bin/phpcs --standard=Magento2 --runtime-set ignore_warnings_on_exit 1 /var/www/html/src/app/code/Auctane
17 changes: 0 additions & 17 deletions .github/workflows/test.yml

This file was deleted.

13 changes: 13 additions & 0 deletions Api/Api/AuthorizationInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php
namespace Auctane\Api\Api;

interface AuthorizationInterface
{
/**
* This method determines if a token is valid.
*
* @param string $token
* @return bool
*/
public function isAuthorized(string $token): bool;
}
2 changes: 0 additions & 2 deletions Api/Api/CheckInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@

use Auctane\Api\Exception\AuthenticationFailedException;


/**
* Interface CheckInterface
* @package Auctane\Api\Api
*/
interface CheckInterface
{
Expand Down
2 changes: 0 additions & 2 deletions Api/Api/ConfigureShipstationInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

namespace Auctane\Api\Api;


/**
* Interface ConfigureShipstationInterface
* @package Auctane\Api\Api
*/
interface ConfigureShipstationInterface
{
Expand Down
11 changes: 11 additions & 0 deletions Api/Api/HttpActionInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php
namespace Auctane\Api\Api;

use Magento\Framework\App\Action\HttpDeleteActionInterface;
use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\App\Action\HttpPostActionInterface;
use Magento\Framework\App\Action\HttpPutActionInterface;

interface HttpActionInterface extends HttpPostActionInterface, HttpGetActionInterface, HttpDeleteActionInterface, HttpPutActionInterface
{
}
5 changes: 0 additions & 5 deletions Api/Block/System/Config/ApiKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@
use Magento\Config\Block\System\Config\Form\Field;
use Magento\Framework\Data\Form\Element\AbstractElement;


/**
* Class ApiKey
* @package Auctane\Api\Block\System\Config
*/
class ApiKey extends Field
{
/**
Expand Down
5 changes: 0 additions & 5 deletions Api/Block/System/Config/GenerateApiKeyButton.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@
use Magento\Config\Block\System\Config\Form\Field;
use Magento\Framework\Data\Form\Element\AbstractElement;


/**
* Class GenerateApiKeyButton
* @package Auctane\Api\Block\System\Config
*/
class GenerateApiKeyButton extends Field
{
/**
Expand Down
8 changes: 1 addition & 7 deletions Api/Console/Command/DebugManagementCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
* Class DebugManagementCommand
*
* @package Auctane\Api\Console\Command
*/
class DebugManagementCommand extends Command
{
const COMMAND_NAME = 'auctane:api:debug';
Expand All @@ -31,8 +26,7 @@ class DebugManagementCommand extends Command
*/
public function __construct(
WriterInterface $config
)
{
) {
parent::__construct(self::COMMAND_NAME);

$this->config = $config;
Expand Down
8 changes: 1 addition & 7 deletions Api/Controller/Adminhtml/ApiKey/Index.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@
use Magento\Framework\Controller\Result\JsonFactory;
use Magento\Framework\Controller\ResultInterface;


/**
* Class Index
* @package Auctane\Api\Controller\Adminhtml\ApiKey
*/
class Index extends Action implements AuthorizationInterface
{
/**
Expand All @@ -37,8 +32,7 @@ public function __construct(
Context $context,
JsonFactory $resultJsonFactory,
ApiKeyGenerator $apiKeyGenerator
)
{
) {
parent::__construct($context);

$this->resultJsonFactory = $resultJsonFactory;
Expand Down
8 changes: 1 addition & 7 deletions Api/Controller/Auctane/Index.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@
use Magento\Store\Model\StoreManagerInterface;
use Psr\Log\LoggerInterface;


/**
* Class Index
* @package Auctane\Api\Controller\Auctane
*/
class Index extends Action implements CsrfAwareActionInterface
{
/** @var Authenticator */
Expand Down Expand Up @@ -59,8 +54,7 @@ public function __construct(
ShipNotify $shipNotify,
Authenticator $authenticator,
LoggerInterface $logger
)
{
) {
parent::__construct($context);

$this->dataHelper = $dataHelper;
Expand Down
29 changes: 29 additions & 0 deletions Api/Controller/BaseAuthorizedController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php
namespace Auctane\Api\Controller;

abstract class BaseAuthorizedController extends BaseController
{
use BaseAuthorizedControllerTrait;

/**
* Initializes BaseAuthenticatedController.
*/
public function __construct()
{
parent::__construct();
$this->initAuthorization();
}

/**
* Pulls auth information from the auth header
*
* @return bool
*/
public function getIsAuthorized(): bool
{
$authorizationHeader = $this->request->getHeader('Authorization');
// Token will be "Bearer token"
$accessToken = explode(" ", $authorizationHeader)[1];
return $this->authHandler->isAuthorized($accessToken);
}
}
20 changes: 20 additions & 0 deletions Api/Controller/BaseAuthorizedControllerTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php
namespace Auctane\Api\Controller;

use Auctane\Api\Api\AuthorizationInterface;
use Magento\Framework\App\ObjectManager;

trait BaseAuthorizedControllerTrait
{
/** @var AuthorizationInterface */
private AuthorizationInterface $authHandler;

/**
* Initialize the authorization handler.
*/
protected function initAuthorization(): void
{
$objectManager = ObjectManager::getInstance();
$this->authHandler = $objectManager->get(AuthorizationInterface::class);
}
}
90 changes: 90 additions & 0 deletions Api/Controller/BaseController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php
namespace Auctane\Api\Controller;

use Auctane\Api\Api\HttpActionInterface;
use Auctane\Api\Exception\ApiException;
use Auctane\Api\Exception\AuthorizationException;
use Magento\Framework\App\CsrfAwareActionInterface;
use Magento\Framework\App\Request\InvalidRequestException;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\Controller\Result\Json;

abstract class BaseController implements HttpActionInterface, CsrfAwareActionInterface
{
use BaseControllerTrait;

/**
* The base controller.
*
*/
public function __construct()
{
$this->initializeBaseControllerDependencies();
}

/**
* This method wraps the implementation with error handling and authorization.
*
* @return Json
*/
public function execute(): Json
{
try {
if (!$this->getIsAuthorized()) {
throw new AuthorizationException();
}
$response = $this->executeAction();
return $this->jsonFactory->create()->setData($response);
} catch (ApiException $apiException) {
return $this->jsonFactory->create()->setHttpResponseCode($apiException->getHttpStatusCode())->setData([
'status' => 'failure',
'message' => $apiException->getMessage()
]);
} catch (\Exception $e) {
return $this->jsonFactory->create()->setHttpResponseCode(500)->setData([
'status' => 'failure',
'message' => $e->getMessage()
]);
}
}

/**
* This method will be implemented by the controller and return the array payload.
*
* @return mixed
* @throws ApiException
*/
abstract protected function executeAction(): mixed;

/**
* This method determines whether a caller is authorized to make this call.
*
* @returns bool
*/
protected function getIsAuthorized():bool
{
return true;
}

/**
* This method is returning null because we will not be throwing a cross site request forgery error.
*
* @param RequestInterface $request
* @return InvalidRequestException|null
*/
public function createCsrfValidationException(RequestInterface $request): ?InvalidRequestException
{
return null;
}

/**
* This method disables cross site request forgery validation so external servers can call these api endpoints.
*
* @param RequestInterface $request
* @return bool|null
*/
public function validateForCsrf(RequestInterface $request): ?bool
{
return true;
}
}
30 changes: 30 additions & 0 deletions Api/Controller/BaseControllerTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php
namespace Auctane\Api\Controller;

use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\App\Request\Http;
use Magento\Framework\Controller\Result\JsonFactory;

trait BaseControllerTrait
{
/** @var JsonFactory */
protected JsonFactory $jsonFactory;
/** @var Http */
protected Http $request;
/** @var ScopeConfigInterface */
protected ScopeConfigInterface $scopeConfig;

/**
* This method initializes things necessary for the BaseControllers functionality.
*
* @return void
*/
public function initializeBaseControllerDependencies(): void
{
$objectManager = ObjectManager::getInstance();
$this->jsonFactory = $objectManager->get(JsonFactory::class);
$this->request = $objectManager->get(Http::class);
$this->scopeConfig = $objectManager->get(ScopeConfigInterface::class);
}
}
20 changes: 20 additions & 0 deletions Api/Controller/Diagnostics/Live.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php
namespace Auctane\Api\Controller\Diagnostics;

use Auctane\Api\Controller\BaseController;
use Magento\Framework\App\Action\HttpGetActionInterface;

class Live extends BaseController implements HttpGetActionInterface
{
/**
* Endpoint used to determine if site is reachable.
*
* @return array
*/
public function executeAction(): array
{
return [
'status' => 'alive'
];
}
}
Loading

0 comments on commit dafc678

Please sign in to comment.