#StackBounty: #java #json #api #plivo error : use 'application/json' Content-Type and raw POST with json data

Bounty: 50

The error message

error : use ‘application/json’ Content-Type and raw POST with json
data

is being appeared from cyclos application inside plivo console which a third API that need to be integrated in cyclos through

Gateway URL: https://api.plivo.com/v1/Account/auth-id/Message/

HTTP username:xxx

HTTP password: **** 

HTTP headers

{
      'content-type': 'application/json',
}

HTTP request type: POST

HTTP request POST body

{
    "src":"+xxxx",
    "dst":"+xxx",
    "text":"some test"
}


Get this bounty!!!

#StackBounty: #php #interview-questions #api #rest #symfony3 Build a set of REST interfaces using Symfony framework

Bounty: 500

I have got a technical challenge from a company but they reject my code and I’m not sure how to do this challenge in a more efficient way so I’m here to get some guidance.

The Technical challenge was:

Manage a list of products that have prices.

  • Enable the administrator to set concrete prices (such as 10EUR) and discounts to prices either by a concrete amount (-1 EUR) or by
    percentage (-10%).
  • Enable the administrator to group products together to form bundles (which is also a product) that have independent prices.
  • Enable customers to get the list of products and respective prices.
  • Enable customers to place an order for one or more products, and provide customers with the list of products and the total price.

I have used Symfony framework to build this API and I’m writing the company response here:

  • SingleProduct and BundleProduct should be polymorphic.
  • ConcretePrice, DiscountedPriceByAmount, DiscountedPriceByPercentage should be polymorphic.
  • The computation of the overall sum of prices for the order should make no assumption about how the individual price was calculated (fix
    price, or discounted).
  • The response should provide a deep object structure (as opposed to a flat list) that preserves the semantics of the model and is suitable
    for rendering.

/src/Entity/Product.php

<?php 

// src/Entity/Product.php

namespace AppEntity;

use DoctrineORMMapping as ORM;
use SymfonyComponentValidatorConstraints as Assert;


/**
 * @ORMEntity(repositoryClass="AppRepositoryProductRepository")
 * @ORMTable(name="products")
 */
class Product {
    /**
     * @ORMColumn(type="integer")
     * @ORMId
     * @ORMGeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
    * @AssertNotBlank()
    * @ORMColumn(type="string", length=150)
    */
    private $title;
    /**
     * @ORMColumn(type="text", length=150, nullable=true)
     */
    private $slug;
    /**
    * @AssertNotBlank()
    * @ORMColumn(type="float", scale=2)
    */
    private $price;
    /**
    * @ORMColumn(type="string", length=5)
    */
    private $currency = '€';
    /**
    * @ORMColumn(type="string", length=3, options={"comment":"Yes, No"})
    */
    private $isDiscount = 'No';
    /**
    * @ORMColumn(type="string", length=10, options={"comment":"Concrete amount (-1 EUR) or by Percentage (-10%)"}, nullable=true)
    */
    private $discountType;
    /**
    * @ORMColumn(type="integer", length=5, options={"comment":"1 or 10"})
    */
    private $discount = 0;
    /**
    * @ORMColumn(type="string", length=5, options={"comment":"No, Yes, if yes then save product ids in product bundle items"})
    */
    private $isProductBundle = 'No';
    /**
     * @ORMColumn(type="text", length=150, nullable=true)
    */
    private $sku;
    /**
    * @ORMColumn(type="string", length=15, options={"comment":"Active or Pending , only Active products will display to customers"})
    */
    private $status = 'Active';
    /**
    * @ORMColumn(type="string", length=150, options={"comment":"Upload or Link of image"})
    */
    private $imageType = 'Link';
    /**
     * @ORMColumn(type="text")
     */
    private $image = 'https://via.placeholder.com/400x300.png';
    /**
     * @ORMColumn(type="text", nullable=true)
     */
    private $description;
    /**
     * @ORMColumn(type="datetime", nullable=true)
     */
    private $createdAt;
    /**
     * @ORMColumn(type="datetime", nullable=true)
     */
    private $updatedAt;


    //Getters and Setters


}

/src/Entity/ProductBundleItem.php

<?php 

// src/Entity/ProductBundleItem.php

namespace AppEntity;

use DoctrineORMMapping as ORM;
use SymfonyComponentValidatorConstraints as Assert;


/**
 * @ORMEntity(repositoryClass="AppRepositoryProductBundleItemRepository")
 * @ORMTable(name="product_bundle_items")
 */
class ProductBundleItem {
    /**
     * @ORMColumn(type="integer")
     * @ORMId
     * @ORMGeneratedValue(strategy="AUTO")
     */
    private $id;
    /**
     * @ORMColumn(type="integer")
    */
    private $productBundleId;

    /**
    * @ORMColumn(type="integer")
    */
    private $productId;


    //Getters and Setters

/src/Repository/ProductRepository.php

<?php

namespace AppRepository;

use AppEntityProduct;
use DoctrineBundleDoctrineBundleRepositoryServiceEntityRepository;
use SymfonyBridgeDoctrineRegistryInterface;

/**
 * @method Product|null find($id, $lockMode = null, $lockVersion = null)
 * @method Product|null findOneBy(array $criteria, array $orderBy = null)
 * @method Product[]    findAll()
 * @method Product[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 */
class ProductRepository extends ServiceEntityRepository
{
    public function __construct(RegistryInterface $registry)
    {
        parent::__construct($registry, Product::class);
    }

    public function findAllQueryBuilder()
    {
        return $this->createQueryBuilder('products');
    }

    // /**
    //  * @return Product[] Returns an array of Product objects
    //  */
    /*
    public function findByExampleField($value)
    {
        return $this->createQueryBuilder('t')
            ->andWhere('t.exampleField = :val')
            ->setParameter('val', $value)
            ->orderBy('t.id', 'ASC')
            ->setMaxResults(10)
            ->getQuery()
            ->getResult()
        ;
    }
    */

    /*
    public function findOneBySomeField($value): ?Product
    {
        return $this->createQueryBuilder('t')
            ->andWhere('t.exampleField = :val')
            ->setParameter('val', $value)
            ->getQuery()
            ->getOneOrNullResult()
        ;
    }
    */
}

/src/Repository/ProductBundleItemRepository.php

<?php

namespace AppRepository;

use AppEntityProductBundleItem;
use DoctrineBundleDoctrineBundleRepositoryServiceEntityRepository;
use SymfonyBridgeDoctrineRegistryInterface;

/**
 * @method ProductBundleItem|null find($id, $lockMode = null, $lockVersion = null)
 * @method ProductBundleItem|null findOneBy(array $criteria, array $orderBy = null)
 * @method ProductBundleItem[]    findAll()
 * @method ProductBundleItem[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 */
class ProductBundleItemRepository extends ServiceEntityRepository
{
    public function __construct(RegistryInterface $registry)
    {
        parent::__construct($registry, ProductBundleItem::class);
    }

    public function findByProductBundleIdJoinedToProduct($productBundleId)
    {

        return $this->createQueryBuilder('pbi')
                ->select('p.id','p.title', 'p.price', 'p.currency')
                ->leftJoin('AppEntityProduct', 'p', 'WITH', 'p.id = pbi.productId')
                ->where('pbi.productBundleId = :productBundleIdParam')
                ->setParameter('productBundleIdParam', $productBundleId)
                ->getQuery()
                ->getResult();
    }


    // /**
    //  * @return ProductBundleItem[] Returns an array of ProductBundleItem objects
    //  */
    /*
    public function findByExampleField($value)
    {
        return $this->createQueryBuilder('t')
            ->andWhere('t.exampleField = :val')
            ->setParameter('val', $value)
            ->orderBy('t.id', 'ASC')
            ->setMaxResults(10)
            ->getQuery()
            ->getResult()
        ;
    }
    */

    /*
    public function findOneBySomeField($value): ?ProductBundleItem
    {
        return $this->createQueryBuilder('t')
            ->andWhere('t.exampleField = :val')
            ->setParameter('val', $value)
            ->getQuery()
            ->getOneOrNullResult()
        ;
    }
    */
}

/src/Controller/Api/ProductController.php

<?php

// src/Controller/Api/ProductController.php

namespace AppControllerApi;

use FOSRestBundleControllerAnnotations as Rest;
use FOSRestBundleControllerAbstractFOSRestController;
use FOSRestBundleViewView;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpFoundationResponse;
use AppServiceProductService;

class ProductController extends AbstractFOSRestController
{

    private $productService;

    public function __construct(ProductService $productService){

        $this->productService = $productService;
    }

    /**
     * Retrieves a collection of Product resource
     * @RestGet("/products")
     */

    public function getProducts(Request $request): View
    {

        $params['page'] = $request->query->getInt('page', 1);
        $params['limit'] = $request->query->getInt('limit', 10);

        $products = $this->productService->getProducts($params);

        return View::create($products, Response::HTTP_OK);
    }

    /**
     * Retrieves a Product resource
     * @RestGet("/products/{slug}")
     */

    public function getProduct(Request $request, $slug): View
    {
        $product = $this->productService->getProduct($slug);

        return View::create($product, Response::HTTP_OK);
    }

    /**
     * Creates an Product resource
     * @RestPost("/products")
     * @param Request $request
     * @return View
    */
    public function addProduct(Request $request): View
    {
        $user = $this->getUser();
        if(!in_array('ROLE_ADMIN',$user->getRoles())){
            return View::create([], Response::HTTP_UNAUTHORIZED);
        }
        $params = json_decode($request->getContent(), true);
        $product = $this->productService->addProduct($params);
        return View::create($product, Response::HTTP_OK);

    }

    /**
     * Creates an Product resource
     * @RestPut("/products/{id}")
     * @param Request $request
     * @return View
    */
    public function updateProduct(Request $request, $id): View
    {
        $user = $this->getUser();
        if(!in_array('ROLE_ADMIN',$user->getRoles())){
            return View::create([], Response::HTTP_UNAUTHORIZED);
        }
        $params = json_decode($request->getContent(), true);
        $product = $this->productService->updateProduct($params, $id);
        return View::create($product, Response::HTTP_OK);

    }

    /**
     * Removes the Product resource
     * @RestDelete("/products/{id}")
    */
    public function deleteProduct($id): View
    {
        $user = $this->getUser();
        if(!in_array('ROLE_ADMIN',$user->getRoles())){
            return View::create([], Response::HTTP_UNAUTHORIZED);
        }
        $this->productService->deleteProduct($id);
        return View::create([], Response::HTTP_NO_CONTENT);

    }
}

/src/Controller/Api/ProductBundleController.php

<?php

// src/Controller/Api/ProductController.php

namespace AppControllerApi;

use FOSRestBundleControllerAnnotations as Rest;
use FOSRestBundleControllerAbstractFOSRestController;
use FOSRestBundleViewView;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpFoundationResponse;
use AppServiceProductBundleService;

class ProductBundleController extends AbstractFOSRestController
{

    private $productBundleService;

    public function __construct(ProductBundleService $productBundleService){

        $this->productBundleService = $productBundleService;
    }

    /**
     * Retrieves a collection of Product bundle resource
     * @RestGet("/products-not-bundles")
     */

    public function getProductsIsNotBundles(): View
    {

        $products = $this->productBundleService->getProductsIsNotBundles();

        return View::create($products, Response::HTTP_OK);
    }


    /**
     * Retrieves a collection of Product bundle resource
     * @RestGet("/product-bundles")
     */

    public function getProductBundles(): View
    {

        $products = $this->productBundleService->getProducts();

        return View::create($products, Response::HTTP_OK);
    }

    /**
     * Retrieves a Product bundle resource
     * @RestGet("/product-bundles/{id}")
     */

    public function getProduct(Request $request, $id): View
    {
        $product = $this->productBundleService->getProduct($id);

        return View::create($product, Response::HTTP_OK);
    }

    /**
     * Creates an Product bundle resource
     * @RestPost("/product-bundles")
     * @param Request $request
     * @return View
    */
    public function addProduct(Request $request): View
    {
        $user = $this->getUser();
        if(!in_array('ROLE_ADMIN',$user->getRoles())){
            return View::create([], Response::HTTP_UNAUTHORIZED);
        }
        $params = json_decode($request->getContent(), true);
        $product = $this->productBundleService->addProduct($params);
        return View::create($product, Response::HTTP_OK);

    }

    /**
     * Update an Product bundle resource
     * @RestPut("/product-bundles/{id}")
     * @param Request $request
     * @return View
    */
    public function updateProduct(Request $request, $id): View
    {
        $user = $this->getUser();
        if(!in_array('ROLE_ADMIN',$user->getRoles())){
            return View::create([], Response::HTTP_UNAUTHORIZED);
        }
        $params = json_decode($request->getContent(), true);
        $product = $this->productBundleService->updateProduct($params, $id);
        return View::create($product, Response::HTTP_OK);

    }

    /**
     * Removes the Product bundle resource
     * @RestDelete("/product-bundles/{id}")
    */
    public function deleteProduct($id): View
    {
        $user = $this->getUser();
        if(!in_array('ROLE_ADMIN',$user->getRoles())){
            return View::create([], Response::HTTP_UNAUTHORIZED);
        }
        $this->productBundleService->deleteProduct($id);
        return View::create([], Response::HTTP_NO_CONTENT);

    }
}

/src/Service/ProductService.php

<?php

namespace AppService;

use DoctrineORMEntityManagerInterface;
use PagerfantaAdapterDoctrineORMAdapter;
use PagerfantaPagerfanta;
use AppRepositoryProductRepository;
use AppUtilsSlugger;
use AppEntityProduct;

final class ProductService
{
    /**
    * @var ProductRepository
    */
    private $productRepository;
    private $slugger;
    private $em;

    public function __construct(ProductRepository $productRepository, Slugger $slugger, EntityManagerInterface $em){

        $this->productRepository = $productRepository;
        $this->slugger = $slugger;
        $this->em = $em;
    }

    public function getProducts($params): ?array
    {
        $qb = $this->productRepository->findAllQueryBuilder();
        $adapter = new DoctrineORMAdapter($qb);
        $pagerfanta = new Pagerfanta($adapter);
        $pagerfanta->setMaxPerPage($params['limit']);
        $pagerfanta->setCurrentPage($params['page']);

        $products = [];
        foreach ($pagerfanta->getCurrentPageResults() as $result) {
            $products[] = $result;
        }

        $response =[
            'total' => $pagerfanta->getNbResults(),
            'count' => count($products),
            'products' => $products,
        ];
        return $response;


    }

    public function getProduct($slug){
        #Find by id
        //return $this->productRepository->find($id);
        #Or find by slug
        return $this->productRepository->findBy(['slug'=>$slug]);
    }

    public function addProduct($params){

        $product = new Product();
        foreach($params as $key=>$val){
            $property = 'set'.strtoupper($key);
            if(property_exists('AppEntityProduct',$key)){
                $product->$property($val);
            }
        }

        $slug = $this->slugger->slugify($product->getTitle());
        $product->setSlug($slug);
        $product->setCreatedAt(date("Y-m-d H:i:s"));
        $product->setUpdatedAt(date("Y-m-d H:i:s"));

        $this->em->persist($product);
        $this->em->flush();

        return $product;
    }

    public function updateProduct($params, $id){

        if(empty($id))
            return [];
        $product = $this->productRepository->find($id);
        if(!$product){
            return [];
        }
        foreach($params as $key=>$val){
            if($key=='id')
                continue;
            $property = 'set'.ucfirst($key);
            if(property_exists('AppEntityProduct',$key)){
                $product->$property($val);
            }
        }

        $slug = $this->slugger->slugify($product->getTitle());
        $product->setSlug($slug);
        $product->setUpdatedAt(date("Y-m-d H:i:s"));

        $this->em->persist($product);
        $this->em->flush();

        return $product;
    }

    public function deleteProduct($id){
        $product = $this->productRepository->find($id);
        if($product){
            $this->em->remove($product);
            $this->em->flush();
        }
    }
}

/src/Service/ProductBundleService.php

<?php

namespace AppService;

use DoctrineORMEntityManagerInterface;
use AppRepositoryProductRepository;
use AppRepositoryProductBundleItemRepository;
use AppUtilsSlugger;
use AppEntityProduct;
use AppEntityProductBundleItem;

final class ProductBundleService
{
    /**
    * @var ProductRepository
    */
    private $productRepository;
    private $productBundleItemRepository;
    private $slugger;
    private $em;


    public function __construct(ProductRepository $productRepository, Slugger $slugger, EntityManagerInterface $em, ProductBundleItemRepository $productBundleItemRepository){

        $this->productRepository = $productRepository;
        $this->productBundleItemRepository = $productBundleItemRepository;
        $this->slugger = $slugger;
        $this->em = $em;
    }

    public function getProductsIsNotBundles(): ?array
    {
        return $this->productRepository->findBy(['status'=>'Active', 'isProductBundle'=>'No']);

    }

    public function getProducts(): ?array
    {
        return $this->productRepository->findBy(['isProductBundle'=>'Yes'],['id'=>'DESC']);
    }

    public function getProduct($id){
        #Find by id
        //return $this->productRepository->find($id);
        #Or find by slug
        $product = $this->productRepository->findBy(['id'=>$id,'isProductBundle'=>'Yes']);

        $bunleItems = $this->productBundleItemRepository->findByProductBundleIdJoinedToProduct($product[0]->getId());

        $returnData['product'] = $product;
        $returnData['bunleItems'] = $bunleItems;
        return $returnData;
    }

    public function addProduct($params){

        $product = new Product();
        foreach($params as $key=>$val){
            $property = 'set'.strtoupper($key);
            if(property_exists('AppEntityProduct',$key)){
                $product->$property($val);
            }
        }

        $product->setIsProductBundle("Yes");

        $slug = $this->slugger->slugify($product->getTitle());
        $product->setSlug($slug);
        $product->setCreatedAt(date("Y-m-d H:i:s"));
        $product->setUpdatedAt(date("Y-m-d H:i:s"));

        $this->em->persist($product);
        $this->em->flush();

        $productsArr = $params['productsArr'];

        if(count($productsArr)>0){
            foreach($productsArr as $productId){
               $productBundleItem = new ProductBundleItem();
               $productBundleItem->setProductBundleId($product->getId());
                $productBundleItem->setProductId($productId);
                $this->em->persist($productBundleItem);
                $this->em->flush();
            }
        }
        $returnData['product'] = $product;
        $returnData['productsArr'] = $productsArr;
        return $returnData;
    }

    public function updateProduct($params, $id){

        if(empty($id))
            return [];
        $product = $this->productRepository->find($id);
        if(!$product){
            return [];
        }
        foreach($params as $key=>$val){
            if($key=='id')
                continue;
            $property = 'set'.ucfirst($key);
            if(property_exists('AppEntityProduct',$key)){
                $product->$property($val);
            }
        }

        $product->setIsProductBundle("Yes");
        $slug = $this->slugger->slugify($product->getTitle());
        $product->setSlug($slug);
        $product->setUpdatedAt(date("Y-m-d H:i:s"));

        $this->em->persist($product);
        $this->em->flush();

        $productsArr = $params['productsArr'];

        if(count($productsArr)>0){
            foreach($productsArr as $productId){

                $isExist = $this->productBundleItemRepository->findBy(['productId'=>$productId]);
                if(!$isExist){
                    $productBundleItem = new ProductBundleItem();
                    $productBundleItem->setProductBundleId($product->getId());
                    $productBundleItem->setProductId($productId);
                    $this->em->persist($productBundleItem);
                    $this->em->flush();
                }
            }
        }

        $returnData['product'] = $product;
        $returnData['productsArr'] = $productsArr;
        return $returnData;
    }

    public function deleteProduct($id){
        $product = $this->productRepository->find($id);
        if($product){
            $productBundleItems = $this->productBundleItemRepository->findBy(['productBundleId'=>$product->getId()]);
            $this->em->remove($product);

            foreach($productBundleItems as $item){
                $this->em->remove($item);
            }

            $this->em->flush();
        }
    }
}

The whole code can be view here


Get this bounty!!!

#StackBounty: #laravel #api #plugins #moodle Moodle autologin plugin – how to direct user to a specific course?

Bounty: 50

I am building a laravel web application which involves the usage of Moodle Service (version 3.6). I have done autologin with a plugin.

The problem is that clicking the Take Course button on my external application will autologin to Moodle (via the plugin), but does not redirect the user to the course described in the button.

Is there a mechanism to do this?


Get this bounty!!!

#StackBounty: #api #rust #amazon-web-services User registration in Actix w/ DynamoDB

Bounty: 50

I am trying to puzzle out api based user registration for a service I am building, but I have a strong feeling that my code is not optimal.

It feels like passing “state” in the way I did prevents the server from being multithreaded, as I have no clue how actix could share data that isn’t Send or Sync across multiple threads.

I also interact with DynamoDb by using a .sync() call on the request, which means that i block on waiting for Dynamo to respond to me. This seems like it would be bad for performance of a web server but I don’t know how to avoid it without something like async/await.

Another issue is that I cannot guarantee that a user has a unique email without making a second table in Dynamo. I don’t want to expose a user’s email to the outside world, so for everything else I would need to use some sort of other unique identifier (here I went with a uuid), but for registration I would still need to check that requirement…somehow. But if I make a second table I introduce the possibility of an inconsistent state since to my knowledge I can’t make dynamo affect two tables atomically.

I also just returned out the created user id to the client, but is there something more useful I could have done? Should I return a token in this response? More info about the created user?

Any and all feedback would be greatly appreciated.

use actix_web::error::InternalError;
use actix_web::http::StatusCode;
use actix_web::{http, server, App, Json, Responder, State};
use bcrypt;
use core::borrow::Borrow;
use core::fmt;
use failure::Error;
use hocon::HoconLoader;
use log::{info, warn, Level};
use maplit::hashmap;
use rusoto_core::{Region, RusotoError};
use rusoto_dynamodb::{
    AttributeDefinition, AttributeValue, BatchWriteItemInput, CreateTableInput, DynamoDb,
    DynamoDbClient, GetItemInput, GetItemOutput, KeySchemaElement, ProvisionedThroughput,
    PutItemInput, PutRequest, WriteRequest,
};
use serde::{Deserialize, Serialize};
use serde_dynamodb;
use simple_logger;
use std::collections::HashMap;
use std::fmt::{Debug, Formatter};
use std::str::FromStr;
use uuid::Uuid;

type DynamoRecord = HashMap<String, AttributeValue>;

/// The info we need from a person in order to create a user for them.
#[derive(Serialize, Deserialize)]
pub struct UserRegistrationInfo {
    email: String,
    password: String,
}

impl Debug for UserRegistrationInfo {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(
            f,
            "UserRegistrationInfo {{ email = {:?}, password = <SENSITIVE> }}",
            self.email
        )
    }
}

/// The canonical user record that is actually stored in the database.
#[derive(Serialize, Deserialize, Debug)]
pub struct User {
    id: String,
    email: String,
    hashed_password: String,
}

impl User {
    /// Creates a User from the bare minimum info we received from the user. Note that
    /// this function is not pure as it involves at the very least generation of a unique
    /// id for the user.
    pub fn from_registration_info(registration_info: UserRegistrationInfo) -> User {
        User {
            id: Uuid::new_v4().to_string(),
            email: registration_info.email,
            hashed_password: bcrypt::hash(registration_info.password, bcrypt::DEFAULT_COST)
                .unwrap(),
        }
    }

    fn to_dynamo(&self) -> serde_dynamodb::error::Result<DynamoRecord> {
        Ok(serde_dynamodb::to_hashmap(self)?)
    }

    fn from_dynamo(m: DynamoRecord) -> serde_dynamodb::error::Result<User> {
        serde_dynamodb::from_hashmap(m)
    }
}

pub struct System {
    pub config: Config,
    pub dynamo_db: DynamoDbClient,
}

impl System {
    pub fn from_config(config: Config) -> System {
        let dynamo_db = DynamoDbClient::new(config.aws_region());
        System { config, dynamo_db }
    }
}

/// The data returned to the user in the event that they successfully register a user
#[derive(Serialize)]
struct SuccessfulRegistration {
    user_id: String,
}

fn register(
    registration_info: Json<UserRegistrationInfo>,
    state: State<System>,
) -> Result<impl Responder, failure::Error> {
    info!("Creating a new user");
    let new_user: User = User::from_registration_info(registration_info.into_inner());
    let put_result = state
        .dynamo_db
        .put_item(PutItemInput {
            table_name: String::from("chat_users"),
            item: new_user.to_dynamo().unwrap(),
            ..PutItemInput::default()
        })
        .sync()?;

    state
        .dynamo_db
        .batch_write_item(BatchWriteItemInput {
            request_items: hashmap! {
                state.config.users_table() => vec![
                    WriteRequest {
                        put_request: Some(PutRequest {
                            item: new_user.to_dynamo().unwrap()
                        }),
                        ..WriteRequest::default()
                    }
                ],
                state.config.login_table() => vec![
                    WriteRequest {
                        put_request: Some(PutRequest {
                            item: new_user.to_dynamo().unwrap()
                        }),
                        ..WriteRequest::default()
                    }
                ]
            },
            ..BatchWriteItemInput::default()
        })
        .sync()?;

    info!("Successfully created a new user");
    Ok(actix_web::HttpResponse::Ok().json(SuccessfulRegistration {
        user_id: new_user.id,
    }))
}

/// Creates the user table. Note: Dynamo doesn't have a "create if not exists" so this needs
/// to be externalized to a good ol' cloudformation script or similar.
fn create_tables(
    client: &DynamoDbClient,
) -> rusoto_core::RusotoResult<(), rusoto_dynamodb::CreateTableError> {
    client
        .create_table(CreateTableInput {
            attribute_definitions: vec![AttributeDefinition {
                attribute_name: "id".to_string(),
                attribute_type: "S".to_string(),
            }],
            provisioned_throughput: Some(ProvisionedThroughput {
                read_capacity_units: 5,
                write_capacity_units: 5,
            }),
            key_schema: vec![KeySchemaElement {
                attribute_name: "id".to_string(),
                key_type: "HASH".to_string(),
            }],
            table_name: "chat_users".to_string(),
            ..CreateTableInput::default()
        })
        .sync()?;
    Ok(())
}

#[derive(Debug, Clone)]
pub struct Config {
    aws_region: Region,
    users_table: String,
    login_table: String,
}

impl Config {
    pub fn aws_region(&self) -> Region {
        self.aws_region.clone()
    }

    pub fn users_table(&self) -> String {
        self.users_table.clone()
    }

    pub fn login_table(&self) -> String {
        self.login_table.clone()
    }

    fn load() -> Result<Config, failure::Error> {
        let hocon = HoconLoader::new()
            .load_file("./application.conf")?
            .hocon()?;

        let aws_region = match hocon["aws"]["region"]
            .as_string()
            .as_ref()
            .map(String::as_str)
        {
            Some("local") => {
                info!("Using "local" as our AWS region");
                Region::Custom {
                    name: "local".to_string(),
                    endpoint: "http://localhost:8000".to_string(),
                }
            }
            Some(region) => Region::from_str(region).unwrap_or_else(|_| {
                warn!("Unknown region: {:?}, defaulting to us-west-2", region);
                Region::UsWest2
            }),

            None => {
                warn!("No region provided, defaulting to us-west-2");
                Region::UsWest2
            }
        };

        let users_table = hocon["dynamo"]["users_table"].as_string().unwrap();
        let login_table = hocon["dynamo"]["login_table"].as_string().unwrap();

        Ok(Config {
            aws_region,
            users_table,
            login_table,
        })
    }
}

fn main() -> Result<(), Box<std::error::Error>> {
    simple_logger::init_with_level(Level::Info).unwrap();

    let config = Config::load()?;
    server::new(move || {
        App::with_state(System::from_config(config.clone())).route(
            "/register",
            http::Method::POST,
            register,
        )
    })
    .bind("127.0.0.1:8080")
    .unwrap()
    .run();

    Ok(())
}
```


Get this bounty!!!

#StackBounty: #magento2 #api #payment-methods #payment Magento2 API to access internal payment method

Bounty: 50

I am working on creating a way to make an order via the magento api and wondering if it is possible to access internal payment methods (payment methods that are only enabled for the admin panel) via the api?

So for example I have a plugin that creates a payment method that can only be seen/used via the magento admin panel. however when I use the magento API to list out payment methods I do not see that payment method listed and think its because its set to be viewable/usable only on the admin panel. So what would i change in the api call to gain access to it?


Get this bounty!!!

#StackBounty: #vb.net #rest #api What is wrong with this coinmex API?

Bounty: 200

Protected Overrides Function getJsonPrivate(method As String, otherParameters() As Tuple(Of String, String)) As String
    Dim base = "https://www.coinmex.com"
    Dim premethod = "/api/v1/spot/ccex/"
    Dim longmethod = premethod + method

    Dim timestampstring = getEstimatedTimeStamp().ToString

    Dim stringtosign = timestampstring + "GET" + longmethod + "{}" '1553784499976GET/api/v1/spot/ccex/account/assets{}

    Dim hasher = New System.Security.Cryptography.HMACSHA256(System.Text.Encoding.UTF8.GetBytes(_secret1))
    Dim sighashbyte = hasher.ComputeHash(System.Text.Encoding.UTF8.GetBytes(stringtosign))
    Dim signature = System.Convert.ToBase64String(sighashbyte) '"FIgrJFDOQctqnkOTyuv6+uTy6xw3OZiP4waC1u6P5LU="=
    Dim url = base + longmethod 'https://www.coinmex.com/api/v1/spot/ccex/account/assets

    '_apiKey1="cmx-1027e54e4723b09810576f8e7a5413**"
    '_passphrase1= 1Us6&f%*K@Qsqr**
    '
    Dim response = CookieAwareWebClient.downloadString1(url, "", {Tuple.Create("ACCESS-KEY", _apiKey1), Tuple.Create("ACCESS-SIGN", signature), Tuple.Create("ACCESS-TIMESTAMP", timestampstring), Tuple.Create("ACCESS-PASSPHRASE", _passphrase1)})

    Return response
End Function

Public Overrides Sub readbalances()
    typicalReadBalances("account/assets", "data", "currencyCode", "available", "frozen", "", {})
End Sub

I think I did it like what’s listed here
https://github.com/coinmex/coinmex-official-api-docs/blob/master/README_EN.md#1-access-account-information

# Request
GET /api/v1/spot/ccex/account/assets

# Response
[
    {
        "available":"0.1",
        "balance":"0.1",
        "currencyCode":"ETH",
        "frozen":"0",
        "id":1
    },
    {
        "available":"1",
        "balance":"1",
        "currencyCode":"USDT",
        "frozen":"0",
        "id":1
    }
]

And for Signature

This is the manual says

The ACCESS-SIGN header is the output generated by using HMAC SHA256 to
create the HMAC SHA256 using the BASE64 decoding secret key in the
prehash string to generate timestamp + method + requestPath + “?” +
queryString + body (where ‘+’ represents the string concatenation) and
BASE64 encoded output. The timestamp value is the same as the
ACCESS-TIMESTAMP header. This body is the request body string or
omitted if there is no request body (usually the GET request). This
method should be capitalized.

Remember that before using it as the key to HMAC, base64 decoding (the
result is 64 bytes) is first performed on the 64-bit alphanumeric
password string. In addition, the digest output is base64 encoded
before sending the header.

User submitted parameters must be signed except for sign. First, the
string to be signed is ordered according to the parameter name (first
compare the first letter of all parameter names, in alphabetic order,
if you encounter the same first letter, then you move to the second
letter, and so on).

For example, if we sign the following parameters

curl "https://www.coinmex.com/api/v1/spot/ccex/orders?limit=100"       

Timestamp = 1590000000.281
Method = "POST"
requestPath = "/api/v1/spot/ccex/orders"
queryString= "?limit=100"
body = {
            'code': 'ct_usdt',
            'side': 'buy',
            'type': 'limit',
            'size': '1',
            'price': '1',
            'funds': '',
        }

Generate the string to be signed

Message = '1590000000.281GET/api/v1/spot/ccex/orders?limit=100{"code": "ct_usdt", "side": "buy", "type": "limit", "size": "1", "price": "0.1", "funds": ""}'

Then, the character to be signed is added with the private key
parameters to generate the final character string to be signed.

For example:

hmac = hmac(secretkey, Message, SHA256)
Signature = base64.encode(hmac.digest())

I thought may be the _secret1 is a base64 string rather than utf8 so I changed to

Dim base = "https://www.coinmex.com"
Dim premethod = "/api/v1/spot/ccex/"
Dim longmethod = premethod + method

Dim timestampstring = getEstimatedTimeStamp().ToString

'Dim stringtosign = timestampstring + "GET" + longmethod + "{}" '1553784499976GET/api/v1/spot/ccex/account/assets{} also doesn't work
Dim stringtosign = timestampstring + "GET" + longmethod  '1553784499976GET/api/v1/spot/ccex/account/assets

Dim hasher = New System.Security.Cryptography.HMACSHA256(Convert.FromBase64String(_secret1)) 'secret looks like 43a90185f5b7ab25af045e9e64bac5dc745934f359f1806fcdd2a4af80ac2
Dim sighashbyte = hasher.ComputeHash(System.Text.Encoding.UTF8.GetBytes(stringtosign))
Dim signature = Convert.ToBase64String(sighashbyte) '"FIgrJFDOQctqnkOTyuv6+uTy6xw3OZiP4waC1u6P5LU="=
Dim url = base + longmethod 'https://www.coinmex.com/api/v1/spot/ccex/account/assets

'_apiKey1="cmx-1027e54e4723b09810576f8e7a5413**"
'_passphrase1= 1Us6&f%*K@Qsq***
'
Dim response = CookieAwareWebClient.downloadString1(url, "", {Tuple.Create("ACCESS-KEY", _apiKey1), Tuple.Create("ACCESS-SIGN", signature), Tuple.Create("ACCESS-TIMESTAMP", timestampstring), Tuple.Create("ACCESS-PASSPHRASE", _passphrase1)})

Return response

Not working either.

The secret key (I truncated a few letters) look like

43a90185f5b7ab25af045e9e64bac5dc745934f359f1806fcdd2a4af80ac2

Is this something that should be decoded as base 64 or utf8 or what?

The spec says it’s 64. However, it doesn’t look like a 64 encoded string. It looks like the letters are from 0-f

Best answers will:
1. Tell me what went wrong in the code. I made the change. Try. Run. Works. Awesome.

A good answer will
2. A sample simulation with a fake/real signatures/nonce/passphrase and real actual headers and signatures. So I can see where exactly I have a wrong result.


Get this bounty!!!

#StackBounty: #c# #vb.net #rest #api What is wrong with this coinmex API?

Bounty: 200

Protected Overrides Function getJsonPrivate(method As String, otherParameters() As Tuple(Of String, String)) As String
    Dim base = "https://www.coinmex.com"
    Dim premethod = "/api/v1/spot/ccex/"
    Dim longmethod = premethod + method

    Dim timestampstring = getEstimatedTimeStamp().ToString

    Dim stringtosign = timestampstring + "GET" + longmethod + "{}" '1553784499976GET/api/v1/spot/ccex/account/assets{}

    Dim hasher = New System.Security.Cryptography.HMACSHA256(System.Text.Encoding.UTF8.GetBytes(_secret1))
    Dim sighashbyte = hasher.ComputeHash(System.Text.Encoding.UTF8.GetBytes(stringtosign))
    Dim signature = System.Convert.ToBase64String(sighashbyte) '"FIgrJFDOQctqnkOTyuv6+uTy6xw3OZiP4waC1u6P5LU="=
    Dim url = base + longmethod 'https://www.coinmex.com/api/v1/spot/ccex/account/assets

    '_apiKey1="cmx-1027e54e4723b09810576f8e7a5413**"
    '_passphrase1= 1Us6&f%*K@Qsqr**
    '
    Dim response = CookieAwareWebClient.downloadString1(url, "", {Tuple.Create("ACCESS-KEY", _apiKey1), Tuple.Create("ACCESS-SIGN", signature), Tuple.Create("ACCESS-TIMESTAMP", timestampstring), Tuple.Create("ACCESS-PASSPHRASE", _passphrase1)})

    Return response
End Function

Public Overrides Sub readbalances()
    typicalReadBalances("account/assets", "data", "currencyCode", "available", "frozen", "", {})
End Sub

I think I did it like what’s listed here
https://github.com/coinmex/coinmex-official-api-docs/blob/master/README_EN.md#1-access-account-information

# Request
GET /api/v1/spot/ccex/account/assets

# Response
[
    {
        "available":"0.1",
        "balance":"0.1",
        "currencyCode":"ETH",
        "frozen":"0",
        "id":1
    },
    {
        "available":"1",
        "balance":"1",
        "currencyCode":"USDT",
        "frozen":"0",
        "id":1
    }
]

And for Signature

This is the manual says

The ACCESS-SIGN header is the output generated by using HMAC SHA256 to
create the HMAC SHA256 using the BASE64 decoding secret key in the
prehash string to generate timestamp + method + requestPath + “?” +
queryString + body (where ‘+’ represents the string concatenation) and
BASE64 encoded output. The timestamp value is the same as the
ACCESS-TIMESTAMP header. This body is the request body string or
omitted if there is no request body (usually the GET request). This
method should be capitalized.

Remember that before using it as the key to HMAC, base64 decoding (the
result is 64 bytes) is first performed on the 64-bit alphanumeric
password string. In addition, the digest output is base64 encoded
before sending the header.

User submitted parameters must be signed except for sign. First, the
string to be signed is ordered according to the parameter name (first
compare the first letter of all parameter names, in alphabetic order,
if you encounter the same first letter, then you move to the second
letter, and so on).

For example, if we sign the following parameters

curl "https://www.coinmex.com/api/v1/spot/ccex/orders?limit=100"       

Timestamp = 1590000000.281
Method = "POST"
requestPath = "/api/v1/spot/ccex/orders"
queryString= "?limit=100"
body = {
            'code': 'ct_usdt',
            'side': 'buy',
            'type': 'limit',
            'size': '1',
            'price': '1',
            'funds': '',
        }

Generate the string to be signed

Message = '1590000000.281GET/api/v1/spot/ccex/orders?limit=100{"code": "ct_usdt", "side": "buy", "type": "limit", "size": "1", "price": "0.1", "funds": ""}'

Then, the character to be signed is added with the private key
parameters to generate the final character string to be signed.

For example:

hmac = hmac(secretkey, Message, SHA256)
Signature = base64.encode(hmac.digest())

I thought may be the _secret1 is a base64 string rather than utf8 so I changed to

Dim base = "https://www.coinmex.com"
Dim premethod = "/api/v1/spot/ccex/"
Dim longmethod = premethod + method

Dim timestampstring = getEstimatedTimeStamp().ToString

'Dim stringtosign = timestampstring + "GET" + longmethod + "{}" '1553784499976GET/api/v1/spot/ccex/account/assets{} also doesn't work
Dim stringtosign = timestampstring + "GET" + longmethod  '1553784499976GET/api/v1/spot/ccex/account/assets

Dim hasher = New System.Security.Cryptography.HMACSHA256(Convert.FromBase64String(_secret1)) 'secret looks like 43a90185f5b7ab25af045e9e64bac5dc745934f359f1806fcdd2a4af80ac2
Dim sighashbyte = hasher.ComputeHash(System.Text.Encoding.UTF8.GetBytes(stringtosign))
Dim signature = Convert.ToBase64String(sighashbyte) '"FIgrJFDOQctqnkOTyuv6+uTy6xw3OZiP4waC1u6P5LU="=
Dim url = base + longmethod 'https://www.coinmex.com/api/v1/spot/ccex/account/assets

'_apiKey1="cmx-1027e54e4723b09810576f8e7a5413**"
'_passphrase1= 1Us6&f%*K@Qsq***
'
Dim response = CookieAwareWebClient.downloadString1(url, "", {Tuple.Create("ACCESS-KEY", _apiKey1), Tuple.Create("ACCESS-SIGN", signature), Tuple.Create("ACCESS-TIMESTAMP", timestampstring), Tuple.Create("ACCESS-PASSPHRASE", _passphrase1)})

Return response

Not working either.

The secret key (I truncated a few letters) look like

43a90185f5b7ab25af045e9e64bac5dc745934f359f1806fcdd2a4af80ac2

Is this something that should be decoded as base 64 or utf8 or what?

The spec says it’s 64. However, it doesn’t look like a 64 encoded string. It looks like the letters are from 0-f

Best answers will:
1. Tell me what went wrong in the code. I made the change. Try. Run. Works. Awesome.

A good answer will
2. A sample simulation with a fake/real signatures/nonce/passphrase and real actual headers and signatures. So I can see where exactly I have a wrong result.


Get this bounty!!!

#StackBounty: #performance #beginner #php #file-system #api Equity data processing: Fast and/or efficient file writing using PHP

Bounty: 50

Problem

This is my first scripting project and I’m sure it has so many issues.

The main class, EQ, scrapes equities data using EquityRecords, calculates sector coefficients using
SectorMovers, estimates equity prices, and finally writes ~8,000 HTML strings (~100Kb-120Kb) on .md files for viewing.

I couldn’t add EQ code in the post due to character limitation of the posts. Please see the entire code on this GitHub link.


Performance

The only goal is making EQ as fast/efficient as possible for a single server. Would you be so kind and review it and kindly help me to reach this goal?


EquityRecords

date_default_timezone_set("UTC");
ini_set('max_execution_time', 0);
ini_set('memory_limit', '-1');
set_time_limit(0);

// EquityRecords::allEquitiesSignleJSON(new EquityRecords());

class EquityRecords
{

    const NUMBER_OF_STOCKS_PER_REQUEST = 100;
    const NEW_LINE = "n";

    /**
     *
     * @var a string of iextrading symbols
     */

    const SYMBOLS_PATH = '/../../config/z-iextrading-symbs.md';

    /**
     *
     * @var a string of our symbols json directory
     */

    const SYMBOLS_DIR = "/../../blog-back/equities/real-time-60sec/z-raw-equilibrium-estimation";

    /**
     *
     * @var a string of target path and query
     */

    const TARGET_QUERY = "stock/market/batch?symbols=";

    /**
     *
     * @var a string of iextrading base URL
     */

    const BASE_URL = "https://api.iextrading.com/1.0/";

    /**
     *
     * @var a string of iextrading end point
     */

    const END_POINT = "&types=quote,chart&range=1m&last=10";

    /**
     *
     * @var an integer for maximum number of stocks per URL on each call
     */

    //***************** A ********************** //
    // public static function getSymbols() {
    //     return array_map(function($line){ return str_getcsv($line, "t"); }, file(__DIR__ . self::SYMBOLS_PATH));
    // }

    public static function getSymbols()
    {

        //***************** START: ALL SYMBOLS ARRAY ********************** //
        // var: is a filename path directory, where there is an md file with list of equities
        $list_of_equities_file = __DIR__ . self::SYMBOLS_PATH;

        // var: is content of md file with list of equities
        $content_of_equities = file_get_contents($list_of_equities_file);

        // var is an array(3) of equities such as: string(4) "ZYNE", string(10) "2019-01-04", string(27) "ZYNERBA PHARMACEUTICALS INC"

        // $symbols_array=preg_split('/rn|r|n/', $content_of_equities);
        $symbols_array = preg_split('/R/', $content_of_equities);
        //***************** END: ALL SYMBOLS ARRAY ********************** //

        // child and mother arrays are created to help calling equities in batches of 100, which seems to be the API limit.
        $child = array();
        $mother = array();
        // var: is 100 counter
        $limit_counter = self::NUMBER_OF_STOCKS_PER_REQUEST;
        foreach ($symbols_array as $ticker_arr) {
            $limit_counter = $limit_counter - 1;
            $symbols_array = preg_split('/t/', $ticker_arr);
            array_push($child, $symbols_array);

            if ($limit_counter <= 0) {
                $limit_counter = self::NUMBER_OF_STOCKS_PER_REQUEST;
                array_push($mother, $child);
                $child = array();
            }

        }
        return $mother;
    }

    public static function allEquitiesSignleJSON()
    {
        $equity_arrays = EquityRecords::getSymbols();
        $base_url = self::BASE_URL . self::TARGET_QUERY;

        $current_time = date("Y-m-d-H-i-s");
        $all_equities = array();
        // ticker: AAPL, GE, AMD
        foreach ($equity_arrays as $ticker_arr) {
            $ticker = array_column($ticker_arr, 0);
            $equity_url = $base_url . implode("%2C", $ticker) . self::END_POINT;
            $raw_eauity_json = file_get_contents($equity_url);
            $raw_equity_array = json_decode($raw_eauity_json, true);
            $all_equities = array_merge($all_equities, $raw_equity_array);
        }

        $all_equities_json = json_encode($all_equities);

        $symbols_dir = __DIR__ . self::SYMBOLS_DIR;

        if (!is_dir($symbols_dir)) {mkdir($symbols_dir, 0755, true);}

        $raw_equity_file = $symbols_dir . "/" . $current_time . ".json";
        $fp = fopen($raw_equity_file, "x+");
        fwrite($fp, $all_equities_json);
        fclose($fp);
        echo "YAAAY! Equity JSON file success at " . __METHOD__ . " ! 💚 " . self::NEW_LINE;
    }

    /**
     * @return a string for var_dump
     */
    public static function p()
    {
        $args = func_get_args();
        $die = (end($args) === 1) && array_pop($args);
        echo self::NEW_LINE;
        foreach ($args as $v) {
            $output = print_r($v, true);
            var_dump($output) . self::NEW_LINE;
        }
        echo self::NEW_LINE;
        if ($die) {
            die();
        }

    }

}

SectorMovers

date_default_timezone_set("UTC");
ini_set('max_execution_time', 0);
ini_set('memory_limit', '-1');
set_time_limit(0);

require_once __DIR__ . "/EquityRecords.php";

SectorMovers::getSectors();

class SectorMovers
{

    /**
     *
     * @var a string of iextrading base URL
     */

    const BASE_URL = "https://api.iextrading.com/1.0/";

    /**
     *
     * @var a string of target path and query
     */

    const TARGET_QUERY = "stock/market/batch?symbols=";

    /**
     *
     * @var a string for backend path for every sector
     */

    const EACH_SECTOR_DIR_PREFIX = "/../../blog-back/sectors/real-time-60sec/z-raw-sector-";

    /**
     *
     * @var a string for backend path for index sector
     */

    const INDEX_SECTOR_DIR_PREFIX = "/../../blog-back/sectors/real-time-60sec/y-index/";

    /**
     *
     * @var a string for live data path
     */

    const LIVE_DATA_DIR = "/../../../public_html/blog/files/";
    const DIR_FRONT_SECTOR_COEF_FILENAME = "s-1.txt"; // Filename that records sector coefficient JSON

    public static function getSectors()
    {
        $base_url = self::BASE_URL . self::TARGET_QUERY;
        $current_time = date("Y-m-d-H-i-s");

        $permission = 0755;

        $index_data = array("Overall" => array("sector_weight" => 1, "sector_coefficient" => 1, "sector_value" => 0));
        $sector_movers = SectorMovers::iexSectorParams();
        foreach ($sector_movers as $sector_mover) {
            // $sector_url = $base_url . implode(",", array_keys($sector_mover["selected_tickers"])) . "&types=quote&range=1m";
            $sector_url = $base_url . implode("%2C", array_keys($sector_mover["selected_tickers"])) . "&types=quote&range=1m";
            $rawSectorJson = file_get_contents($sector_url);
            $raw_sector_array = json_decode($rawSectorJson, true);

            // ******************* Back Data ***************** //
            // Write the raw file in the back directories

            // $rawSectorDir =  __DIR__ . self::EACH_SECTOR_DIR_PREFIX . $sector_mover["directory"];

            // // if back directory not exist
            // if (!is_dir($rawSectorDir)) {mkdir($rawSectorDir, $permission, true);}

            // // create and open/write/close sector data to back directories
            // $rawSectorFile = $rawSectorDir . "/" . $current_time . ".json";
            // $fp = fopen($rawSectorFile, "a+");
            // fwrite($fp, $rawSectorJson);
            // fclose($fp);

            // ******************* End Back Data ***************** //

            // Calculate the real-time index
            $index_value = 0;
            foreach ($raw_sector_array as $ticker => $ticker_stats) {
                if (isset($sector_mover["selected_tickers"][$ticker], $ticker_stats["quote"], $ticker_stats["quote"]["extendedChangePercent"], $ticker_stats["quote"]["changePercent"], $ticker_stats["quote"]["ytdChange"])) {

                    $change_amount = ($ticker_stats["quote"]["extendedChangePercent"] + $ticker_stats["quote"]["changePercent"] + $ticker_stats["quote"]["ytdChange"]) / 200;
                    $index_value += $sector_mover["sector_weight"] * $sector_mover["selected_tickers"][$ticker] * $change_amount;
                }
            }

            $index_data[$sector_mover["sector"]] = array("sector_weight" => $sector_mover["sector_weight"], "sector_coefficient" => $sector_mover["sector_coefficient"], "sector_value" => $index_value);
            $index_data["Overall"]["sector_value"] += $index_data[$sector_mover["sector"]]["sector_value"];
        }

        // Calculate the index factor for better visibility between -1 and +1
        $front_index_data = array();
        foreach ($index_data as $sector_name => $sector_index_data) {

            // $index_sign = $sector_index_data["sector_value"];
            // if ($index_sign < 0) {
            //     $index_sign = - $index_sign;
            // }

            $index_sign = abs($sector_index_data["sector_value"]);

            $index_factor = 1;
            for ($i = 0; $i <= 10; $i++) {
                $index_factor = pow(10, $i);
                if (($index_factor * $index_sign) > 1) {
                    $index_factor = pow(10, $i - 1);
                    break;
                }
            }

            // $index_factor = 10 ** strlen(preg_match('~.K0+~', $float, $zeros) ? $zeros[0] : 0);

            $front_index_data[$sector_name] = $sector_index_data["sector_weight"] * $sector_index_data["sector_coefficient"] * $sector_index_data["sector_value"] * $index_factor;
        }

        // Write the index file
        $index_sector_dir = __DIR__ . self::INDEX_SECTOR_DIR_PREFIX;

        if (!is_dir($index_sector_dir)) {mkdir($index_sector_dir, $permission, true);}

        $index_sector_file = $index_sector_dir . $current_time . ".json";

        $index_sector_json = json_encode($front_index_data, JSON_FORCE_OBJECT);
        $fp = fopen($index_sector_file, "a+");
        fwrite($fp, $index_sector_json);
        fclose($fp);

        $sector_dir = __DIR__ . self::LIVE_DATA_DIR;

        if (!is_dir($sector_dir)) {mkdir($sector_dir, $permission, true);} // if data directory did not exist

        // if s-1 file did not exist
        if (!file_exists($sector_dir . self::DIR_FRONT_SECTOR_COEF_FILENAME)) {
            $handle = fopen($sector_dir . self::DIR_FRONT_SECTOR_COEF_FILENAME, "wb");
            fwrite($handle, "d");
            fclose($handle);
        }

        $sector_coef_file = $sector_dir . self::DIR_FRONT_SECTOR_COEF_FILENAME;
        copy($index_sector_file, $sector_coef_file);
        echo "YAAAY! " . __METHOD__ . " updated sector coefficients successfully 💚!n";

        return $front_index_data;
    }

    public static function iexSectorParams()
    {
        $sector_movers = array(
            array(
                "sector" => "IT",
                "directory" => "information-technology",
                "sector_weight" => 0.18,
                "sector_coefficient" => 4,
                "selected_tickers" => array(
                    "AAPL" => 0.18,
                    "AMZN" => 0.16,
                    "GOOGL" => 0.14,
                    "IBM" => 0.2,
                    "MSFT" => 0.1,
                    "FB" => 0.1,
                    "NFLX" => 0.08,
                    "ADBE" => 0.06,
                    "CRM" => 0.04,
                    "NVDA" => 0.02,
                ),
            ),
            array(
                "sector" => "Telecommunication",
                "directory" => "telecommunication-services",
                "sector_weight" => 0.12,
                "sector_coefficient" => 4,
                "selected_tickers" => array(
                    "VZ" => 0.18,
                    "CSCO" => 0.16,
                    "CMCSA" => 0.14,
                    "T" => 0.12,
                    "CTL" => 0.1,
                    "CHTR" => 0.1,
                    "S" => 0.08,
                    "DISH" => 0.06,
                    "USM" => 0.04,
                    "VOD" => 0.02,
                ),
            ),
            array(
                "sector" => "Finance",
                "directory" => "financial-services",
                "sector_weight" => 0.1,
                "sector_coefficient" => 6,
                "selected_tickers" => array(
                    "JPM" => 0.18,
                    "GS" => 0.16,
                    "V" => 0.14,
                    "BAC" => 0.12,
                    "AXP" => 0.1,
                    "WFC" => 0.1,
                    "USB" => 0.08,
                    "PNC" => 0.06,
                    "AMG" => 0.04,
                    "AIG" => 0.02,
                ),
            ),
            array(
                "sector" => "Energy",
                "directory" => "energy",
                "sector_weight" => 0.1,
                "sector_coefficient" => 6,
                "selected_tickers" => array(
                    "CVX" => 0.18,
                    "XOM" => 0.16,
                    "APA" => 0.14,
                    "COP" => 0.12,
                    "BHGE" => 0.1,
                    "VLO" => 0.1,
                    "APC" => 0.08,
                    "ANDV" => 0.06,
                    "OXY" => 0.04,
                    "HAL" => 0.02,
                ),
            ),
            array(
                "sector" => "Industrials",
                "directory" => "industrials",
                "sector_weight" => 0.08,
                "sector_coefficient" => 8,
                "selected_tickers" => array(
                    "CAT" => 0.18,
                    "FLR" => 0.16,
                    "GE" => 0.14,
                    "JEC" => 0.12,
                    "JCI" => 0.1,
                    "MAS" => 0.1,
                    "FLS" => 0.08,
                    "AAL" => 0.06,
                    "AME" => 0.04,
                    "CHRW" => 0.02,
                ),
            ),
            array(
                "sector" => "Materials and Chemicals",
                "directory" => "materials-and-chemicals",
                "sector_weight" => 0.08,
                "sector_coefficient" => 8,
                "selected_tickers" => array(
                    "DWDP" => 0.18,
                    "APD" => 0.16,
                    "EMN" => 0.14,
                    "ECL" => 0.12,
                    "FMC" => 0.1,
                    "LYB" => 0.1,
                    "MOS" => 0.08,
                    "NEM" => 0.06,
                    "PPG" => 0.04,
                    "MLM" => 0.02,
                ),
            ),
            array(
                "sector" => "Utilities",
                "directory" => "utilities",
                "sector_weight" => 0.08,
                "sector_coefficient" => 8,
                "selected_tickers" => array(
                    "PPL" => 0.18,
                    "PCG" => 0.16,
                    "SO" => 0.14,
                    "WEC" => 0.12,
                    "PEG" => 0.1,
                    "XEL" => 0.1,
                    "D" => 0.08,
                    "NGG" => 0.06,
                    "NEE" => 0.04,
                    "PNW" => 0.02,
                ),
            ),
            array(
                "sector" => "Consumer Discretionary",
                "directory" => "consumer-discretionary",
                "sector_weight" => 0.08,
                "sector_coefficient" => 8,
                "selected_tickers" => array(
                    "DIS" => 0.18,
                    "HD" => 0.16,
                    "BBY" => 0.14,
                    "CBS" => 0.12,
                    "CMG" => 0.1,
                    "MCD" => 0.1,
                    "GPS" => 0.08,
                    "HOG" => 0.06,
                    "AZO" => 0.04,
                    "EXPE" => 0.02,
                ),
            ),
            array(
                "sector" => "Consumer Staples",
                "directory" => "consumer-staples",
                "sector_weight" => 0.06,
                "sector_coefficient" => 8,
                "selected_tickers" => array(
                    "PEP" => 0.18,
                    "PM" => 0.16,
                    "PG" => 0.14,
                    "MNST" => 0.12,
                    "TSN" => 0.1,
                    "CPB" => 0.1,
                    "HRL" => 0.08,
                    "SJM" => 0.06,
                    "CAG" => 0.04,
                    "KHC" => 0.02,
                ),
            ),
            array(
                "sector" => "Defense",
                "directory" => "defense-and-aerospace",
                "sector_weight" => 0.04,
                "sector_coefficient" => 10,
                "selected_tickers" => array(
                    "BA" => 0.18,
                    "LMT" => 0.16,
                    "UTX" => 0.14,
                    "NOC" => 0.12,
                    "HON" => 0.1,
                    "RTN" => 0.1,
                    "TXT" => 0.08,
                    "LLL" => 0.06,
                    "COL" => 0.04,
                    "GD" => 0.02,
                ),
            ),
            array(
                "sector" => "Health",
                "directory" => "health-care-and-pharmaceuticals",
                "sector_weight" => 0.04,
                "sector_coefficient" => 10,
                "selected_tickers" => array(
                    "UNH" => 0.18,
                    "JNJ" => 0.16,
                    "PFE" => 0.14,
                    "UHS" => 0.12,
                    "AET" => 0.1,
                    "RMD" => 0.1,
                    "TMO" => 0.08,
                    "MRK" => 0.06,
                    "ABT" => 0.04,
                    "LLY" => 0.02,
                ),
            ),

            array(
                "sector" => "Real Estate",
                "directory" => "real-estate",
                "sector_weight" => 0.04,
                "sector_coefficient" => 10,
                "selected_tickers" => array(
                    "CCI" => 0.18,
                    "AMT" => 0.16,
                    "AVB" => 0.14,
                    "HCP" => 0.12,
                    "RCL" => 0.1,
                    "HST" => 0.1,
                    "NCLH" => 0.08,
                    "HLT" => 0.06,
                    "ARE" => 0.04,
                    "AIV" => 0.02,
                ),
            ),
        );
        return $sector_movers;
    }

}

Acknowledgement

I’d like to thank these users for being so helpful, which I could implement some of their advices in the code.


Get this bounty!!!

#StackBounty: #performance #beginner #php #file-system #api API equity scraping: Fast and/or efficient file writing using PHP

Bounty: 50

This is my first scripting project, and the only goal is making the scripts as fast/efficient as possible (performance) for a single machine. Would you be so kind and review my working codes and kindly help me with the goal?

There is only one main class (EQ) that does this job, by scraping equities data using EquityRecordsclass and calculating sector coefficients using
SectorMovers class.

I tried to add EQ class in the post. However, I couldn’t because of character limitations of the post. You can view it in this GitHub link.

Acknowledgment

I’d also like to thank the following users for their kind helps:

  • Andreas

  • ArtisticPhoenix

  • Dharman

  • kemicofa

  • Mick Harner

  • Nina Scholz

  • Oh My Goodness

  • Sᴀᴍ Onᴇᴌᴀ


Get this bounty!!!

#StackBounty: #oauth #api #oauth2 #ldap Invalidate API tokens when LDAP user is invalid

Bounty: 50

I’m using oauth2 and LDAP for authorization and authentication of an API. Authentication flow is given below.

  1. User sends LDAP username and password (with password grand type) to
    the server.
  2. Server validates the password communicating with the LDAP server If valid, server returns an access token and a refresh token.

User keeps accessing APIs with access token until expired. When expired, the refresh token can be used to get a new access token and a new refresh token. The user can keep accessing the APIs forever updating the tokens.

Another requirement is making tokens invalid when user password is changed or when the user is disabled in the LDAP server. Is there anyway to do this?

So far I tried following approach:

Store the LDAP password hash in the server when initially user sends them.
When refreshing the token, fetch password hash of the user from the LDAP server and compare them to the one saved in the server.
But it looks like it’s not always possible to fetch the hash. It depends on the LDAP configuration,directory and Permissions


Get this bounty!!!