Other

aws chaliceでpynamodb(dynamodb)を利用する際のIAM policy

Posted by dowell on

chaliceはboto3で使っているメソッドから必要なIAMを自動的に付与(更新しないもできる)する機能を持ってるので、boto3でdynamodbを使ったりすれば、自動で付与されるけど、pynamodbを使った場合はそこまでは面倒見てくれないので、boto3でdynamoを利用せず、pynamodbのモデルしか用意してないと、こんな感じでdynamodbへのポリシーは無視される。


$ chalice gen-policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cognito-idp:AdminCreateUser",
"cognito-idp:AdminInitiateAuth",
"cognito-idp:AdminRespondToAuthChallenge"
],
"Resource": [
"*"
],
"Sid": "275e6aad3b0a4356ac3b9ab90fbe2422"
}
]
}

なので、手動で管理する必要があるけど、Identity and Access Management (IAM)から編集するのはchalice使う意味なくなるので、.chalice/policy.jsonを利用する。

手動で変更してもいいけど、ミスってもいやなので、適当に下記のapp.pyにboto3でdynamoを操作する記述を追加


dynamodb.get_item(TableName="nanndemoiiyo")
dynamodb.put_item(TableName="nanndemoiiyo")
table = dynamodb.create_table(

この状態でポリシーを見るとDynamodbのポリシーが入るので、jsonとして保存


$ chalice gen-policy > .chalice/policy.json
$ cat .chalice/policy.json

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cognito-idp:AdminCreateUser",
"cognito-idp:AdminInitiateAuth",
"cognito-idp:AdminRespondToAuthChallenge"
],
"Resource": [
"*"
],
"Sid": "c5c6757d1033420fa4ba529b67bd333d"
},
{
"Effect": "Allow",
"Action": [
"dynamodb:CreateTable",
"dynamodb:GetItem",
"dynamodb:PutItem"
],
"Resource": [
"*"
],
"Sid": "5a2f50fb91a34608b571409e5291041b"
}
]
}

環境によってサフィックスが必要
今回は「.chalice/policy.json」から「.chalice/policy-dev.json」に変更してデプロイ時は「–no-autogen-policy」をつければOK

Other

cloudformationでCognitoのUserPool作成でエラー

Posted by dowell on


aws cloudformation deploy --template-file userPool.yml --stack-name CognitoUserPool-test --capabilities CAPABILITY_IAM --profile dev-southeast

Waiting for changeset to be created..
Waiting for stack create/update to complete

Failed to create/update the stack. Run the following command
to fetch the list of events leading up to the failure
aws cloudformation describe-stack-events --stack-name CognitoUserPool-test


{
"StackId": "arn:aws:cloudformation:ap-southeast-2:00000894962:stack/CognitoUserPool-test/f6e05000-0000-11e9-ba1c-0664273e8e22",
"EventId": "CognitoUserPool-CREATE_FAILED-2019-08-15T07:26:25.833Z",
"StackName": "CognitoUserPool-test",
"LogicalResourceId": "CognitoUserPool",
"PhysicalResourceId": "",
"ResourceType": "AWS::Cognito::UserPool",
"Timestamp": "2019-08-15T07:26:25.833Z",
"ResourceStatus": "CREATE_FAILED",
"ResourceStatusReason": "Property validation failure: [Encountered unsupported properties in {/Schema/0}: [Required\"]]",
"ResourceProperties":


Schema:
- Name: "name"
AttributeDataType: String
Mutable: true
Required": true

誤字。。

Other

AWS – Cognitoでemailを変更した場合、認証してなくても古いメアドはログインできない

Posted by dowell on

タイトル通りで

Cogitoでまずユーザを登録する。


var attributeList = [];
attributeList.push(new AWSCognito.CognitoIdentityServiceProvider.CognitoUserAttribute({
Name: 'name',
Value: $('#name').val()
}));
attributeList.push(new AWSCognito.CognitoIdentityServiceProvider.CognitoUserAttribute({
Name: 'email',
Value: $('#email').val()
}));
userPool.signUp($('#email').val(), $('#password').val(), attributeList, null, function(err, result) {
if (err) {
console.log(err);
return;
}
cognitoUser = result.user;
console.log('Username:' + cognitoUser.getUsername());
});

登録後、認証コードが送られてくるので

Other

GoogleのGoogleDrive乗っ取られた?エロ画像を置かれた

Posted by dowell on

GoogleDriveは使ってないんですが
たまたまGmailのメールから添付Drive経由で開いて、削除しようと一覧を開いたらエロ画像が置かれていて、x****@gmail.comと共有になっていて、半年以上前からになっていて、Googleに削除されなかったのが救い。。

何かアプリをインストールした時なのか、わからないけどドライブへの許可をしてたみたいで、API経由でアップロードなのかシェアされていたみたい。

使わないつもりのサービスでもたまにチェックしないと、不意にアカウント停止の対象になるかもしれない。

iPhone

GADInvalidInitializationException-GoogleMobileAdsアップデートしたら動かなくなった

Posted by dowell on

GADInvalidInitializationExceptionが発生

GoogleMobileAdsをアップデートしたら、iOSアプリがクラッシュするようになってしまった。


2019-03-29 17:20:39.153251+0900 test.app[9165:102709] *** Terminating app due to uncaught exception 'GADInvalidInitializationException', reason: 'The Google Mobile Ads SDK was initialized incorrectly. Google AdMob publishers should follow instructions here: https://googlemobileadssdk.page.link/admob-ios-update-plist to include the AppMeasurement framework, set the -ObjC linker flag, and set GADApplicationIdentifier with a valid App ID. Google Ad Manager publishers should follow instructions here: https://googlemobileadssdk.page.link/ad-manager-ios-update-plist'
*** First throw call stack:

GADInvalidInitializationExceptionの原因

いままでAppDelegateでGADMobileAds.configure( APPID )してましたがこれがとうとうダメになったようです。

‘configure(withApplicationID:)’ is deprecated: Use [GADMobileAds.sharedInstance startWithCompletionHandler:]


 GADMobileAds.configure(withApplicationID: 

今後はInfo.plistにGADApplicationIdentifierを追加するらしいです。


GADApplicationIdentifier
ca-app-pub-123~????????

Androidはちょっと前からmanifest.xmlに追加が必要になっていたので同じ感じ。
Googleが解析しやすいようにするのかな?

iPhone

carthageでpkluz/PKHUDがBuild Failed – バージョン指定を間違えてビルドエラー

Posted by dowell on

$ cat Cartfile
github "pkluz/PKHUD" ~> 4.0

$ carthage update --platform iOS PKHUD
*** Building scheme "PKHUD" in PKHUD.xcodeproj
Build Failed
	Task failed with exit code 65:
	/usr/bin/xcrun xcodebuild -project /Users/dp/dev/Xcode/test.app/Carthage/Checkouts/PKHUD/PKHUD.xcodeproj -scheme PKHUD -configuration Release -derivedDataPath /Users/dp/Library/Caches/org.carthage.CarthageKit/DerivedData/10.2_10E125/PKHUD/4.2.3 -sdk iphoneos ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= CARTHAGE=YES archive -archivePath /var/folders/bv/0637g83s7bz_l040pkghmt380000gn/T/PKHUD SKIP_INSTALL=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=NO CLANG_ENABLE_CODE_COVERAGE=NO STRIP_INSTALLED_PRODUCT=NO (launched in /Users/dp/dev/Xcode/test.app/Carthage/Checkouts/PKHUD)

This usually indicates that project itself failed to compile. Please check the xcodebuild log for more details: /var/folders/bv/0637g83s7bz_l040pkghmt380000gn/T/carthage-xcodebuild.15y1aS.log

Build Failed , Task failed with exit code 65

ログを確認します。


cat /var/folders/bv/0637g83s7bz_l040pkghmt380000gn/T/carthage-xcodebuild.15y1aS.log

note: Planning build
note: Constructing build description
Build system information
error: SWIFT_VERSION '3.0' is unsupported, supported versions are: 4.0, 4.2, 5.0. (in target 'PKHUD')

Build system information
error: SWIFT_VERSION '3.0' is unsupported, supported versions are: 4.0, 4.2, 5.0. (in target 'PKHUD')

** ARCHIVE FAILED **

バージョン指定間違ってた。。


$ cat Cartfile
- github "pkluz/PKHUD" ~> 4.0
+ github "pkluz/PKHUD" ~> 5.0

https://github.com/pkluz/PKHUD

iPhone

Xcode10.2 (10E125)にしたらcarthageでIncompatible Swift version

Posted by dowell on

carthageはバイナリが準備されていればダウンロードしてビルド短縮しますが
importしたバイナリがXcodeのアップデートで4から5になってしまったので
buildした環境と変わってしまったのでエラーが出てしまいました。


Skipped installing FontAwesome.swift.framework binary due to the error:
	"Incompatible Swift version - framework was built with 4.2.1 (swiftlang-1000.11.42 clang-1000.11.45.1) and the local version is 5.0 (swiftlang-1001.0.69.5 clang-1001.0.46.3)."

version0.20からはSwiftのバージョンが異なる場合ビルドしてくれるそうなので
Carthageをバージョンアップしました。


brew upgrade carthage

version0.20からはSwiftのバージョンが違ったので「Falling back to building from the source」を勝手に実行してくれました。


** Downloading FontAwesome.swift.framework binary at "Dynamic Type"
***  Skipped installing FontAwesome.swift.framework binary due to the error:
	"Incompatible Swift version - framework was built with 4.2.1 (swiftlang-1000.11.42 clang-1000.11.45.1) and the local version is 5.0 (swiftlang-1001.0.69.5 clang-1001.0.46.3)."

    Falling back to building from the source
PHP

SlimフレームワークでLaravelで有名なEloquentのEvent(self::creating,updating,savingイベント)が動かなかったのを解決できた

Posted by dowell on

EloquentはLaravelでなくても便利なのでORMとしてCodeigniterやSlimで利用してますが
Eloquentのモデルが設定したイベントが呼ばれないので調べてみました。

エラーにはならず、普通にORMとして機能するんですけど、イベントが如何せんよばれない。。


class User extends Model {
public static function boot(){
	parent::boot();
	self::creating(function ($q) {
log出力とかしたい。
	});
	self::updating(function ($q) {
log出力とかしたいのに、イベントが呼ばれない。。
	});
}

$user = User::find(1);
$user->last_login_at = time();
$user->save();

最初slim eloquent event not working,slim eloquent event not callなどで
ググったけど、SlimでEloquentとなるとModelの基本しか見つからないので
vendorの中をちゃんと読むことにしました。

Illuminate\Database\Eloquent\Model.phpを見ると
トレイトにHasEventsってぽいやつがいる。
そして中でイベントが設定されていれば、Dispatcher読んでる。



Model.php

namespace Illuminate\Database\Eloquent;

abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializable, QueueableEntity, UrlRoutable
{
    use Concerns\HasAttributes,
        Concerns\HasEvents,
        Concerns\HasGlobalScopes,
        Concerns\HasRelationships,
        Concerns\HasTimestamps,
        Concerns\HidesAttributes,
        Concerns\GuardsAttributes,
        ForwardsCalls;


HasEvents.php
namespace Illuminate\Database\Eloquent\Concerns;

use Illuminate\Contracts\Events\Dispatcher;

trait HasEvents
{
    /**
     * The event map for the model.
     *
     * Allows for object-based events for native Eloquent events.
     *
     * @var array
     */
    protected $dispatchesEvents = [];
省略
    /**
     * Get the observable event names.
     *
     * @return array
     */
    public function getObservableEvents()
    {
        return array_merge(
            [
                'retrieved', 'creating', 'created', 'updating', 'updated',
                'saving', 'saved', 'restoring', 'restored',
                'deleting', 'deleted', 'forceDeleted',
            ],
            $this->observables
        );
    }
省略
    protected function registerObserver($class)
    {
        $className = $this->resolveObserverClassName($class);

        // When registering a model observer, we will spin through the possible events
        // and determine if this observer has that method. If it does, we will hook
        // it into the model's event system, making it convenient to watch these.
        foreach ($this->getObservableEvents() as $event) {
            if (method_exists($class, $event)) {
                static::registerModelEvent($event, $className.'@'.$event);
            }
        }
    }

イベントディスパッチャーはIlluminate\Contracts\Events\Dispatcherか。
と思いディレクトリを探すと無い。
そこで気づきました。。イベント設定してもDispatcher無いじゃん。
EventってEloquentが持ってるのかよければ依存で持ってきてると思ったけど。。。違うよね。。

今回はSlimを利用していて、下記のようにDBを読んでいます。


// DIC configuration
$container = $app->getContainer();

$container['db'] = function( $c ) {
	$capsule = new \Illuminate\Database\Capsule\Manager;
	$capsule->addConnection( $c['settings']['db'] );
	$capsule->getConnection()->enableQueryLog();
	$capsule->setAsGlobal();
	$capsule->bootEloquent();
	return $capsule;
};

composer.jsonはこんな感じ


"require": {
	"slim/slim": "^3.12",
	"monolog/monolog": "^1.24",
	"danielstjules/stringy": "^3.1",
	"respect/validation": "^1.1",
	"illuminate/database": "^5.5"
},

さっそくイベントライブラリを追加します。


composer require illuminate/container
composer require illuminate/events

そして、コンテナに入れてるDBにも設定を追加します。
最初間違って、setAsGlobalの後にsetEventDispatcherして動かなくて悩みました。。


use Illuminate\Events\Dispatcher as Dispatcher;
use Illuminate\Container\Container as Container;

// DIC configuration
$container = $app->getContainer();

$container['db'] = function( $c ) {
	$capsule = new \Illuminate\Database\Capsule\Manager;
	$capsule->addConnection( $c['settings']['db'] );
	$capsule->setEventDispatcher( new Dispatcher( new Container ) );
	$capsule->getConnection()->enableQueryLog();
	$capsule->setAsGlobal();
	$capsule->bootEloquent();
	return $capsule;
};

これでSlimフレームワークでもEloquentのModelイベントが動くようになりました。

PHP

Slim Frameworkでsettingsに追加した設定値が$c->get(‘settings’)でnull

Posted by dowell on

SlimでTwitterAPIやSessionの設定をsettingsに追加しましたが

コンテナに追加する際に、設定値がNullになっていしまう。


$container['twitterOAuth'] = function ($c) {
    $settings = $c->get('settings')['twitter'];
    var_dump( $c->get('settings') );
    exit;

Null

エラーも特に出てないので、Slimがどうやってsettingsを読んでいるか見てみた。

slim/slim/Slim/Collection.php


他はgetterなどなんで、フィルターはない。
public function __construct(array $items = [])
    {
        $this->replace($items);
    }

slim/slim/Slim/Container.php


settingsが空ならEmptyでCollection作るけど
valuesにはあるけど、userSettingsにはない。
public function __construct(array $values = [])
{
       parent::__construct($values);
var_dump( $values ); ある

       $userSettings = isset($values['settings']) ? $values['settings'] : [];

var_dump( $userSettings );  ない

    $this->registerDefaultServices($userSettings);
}
private function registerDefaultServices($userSettings)
{
    $defaultSettings = $this->defaultSettings;

    /**
     * This service MUST return an array or an
     * instance of \ArrayAccess.
     *
     * @return array|\ArrayAccess
     */
    $this['settings'] = function () use ($userSettings, $defaultSettings) {
        return new Collection(array_merge($defaultSettings, $userSettings));
    };

    $defaultProvider = new DefaultServicesProvider();
    $defaultProvider->register($this);
}

なんてことはなく、settings.phpのsettingsの閉じが意図してなかっただけ。。
return ‘settings’ , ‘session’ , ‘twitter’;
になってただけだった。。

settings.php


// Monolog settings
    'logger' => [
        'name' => 'App',
        'path' => __DIR__ . '/logs/app.log',
        'level' => \Monolog\Logger::DEBUG,
        ],
    ], // 多いい。。。。