社内システム向けにSAML用認証プロキシをFargateで立ててVPNを撲滅する話

経緯

Work from Home への対応を進める中で、部署によっては社内システムへのアクセスで VPN が必須になっている。でも、VPN 経由だと回線は細くなるので接続しっぱなしで作業するのはつらいことが多い。もちろんエンジニアであれば特定の IP だけ VPN 経由に、とかそういう設定もできるけど、みんなが手軽にできるわけでもない。それに、最近は Zero Trust Network みたいな考え方も出てきているし、社内システムを G Suite の Google アカウントで SSO できるように対応できればセキュリティも強化されるし VPN 不要になってみんなハッピー!と思った。

とはいえ、社内システムは他システムからの依存もあり、あんまり適当に認証まわりをいじりたくない。そこで、社内システム自体はそのままにして、SAML 対応の認証プロキシを別ドメインで立てるという構想に至った。

ハンドドリップでエグみが強く出てしまうときの対処方法

発端

ここのところ KOFFEE MAMEYA にどハマリしている。Raspberry Candy / ONA Coffee の異次元のうまさに感動して、同僚からもらった Ethiopia Zelelu Ararso / MAME も意気揚々と淹れたところ、全然美味しく作れない。

いろいろ考えて試行錯誤していたら 150g の豆は数日間で溶けて、結局満足できる1杯は得られなかった。

この記事では最初の状況、自分の試行錯誤、淹れ方の相談、別の豆でリベンジ、優勝までを長々と書く。

dieselで条件に基づいたクエリを構築する

diesel 小ネタ。

参考: https://github.com/diesel-rs/diesel/issues/455

やりたいこと

数字の ID でも文字列の slug でも1つの関数で検索できるようにしたい。

pub enum IdOrSlug {
    Id(i32),
    Slug(String),
}

// ...

pub fn find(..., id: IdOrSlug) -> Result<Article> {
    let query = articles::table.left_join(categories::table);
    let query = match id {
        IdOrSlug::Id(id) => query.filter(articles::id.eq(id)),
        IdOrSlug::Slug(slug) => query.filter(articles::slug.eq(slug.as_str())),
    };

    // ...

ダメっぽい

.filter() をかますと引数の型が戻り値の型に埋め込まれるようで、 incompatible だと怒られる。

match arms have incompatible types

expected struct `schema::articles::columns::id`, found struct `schema::articles::columns::slug`

note: expected type `diesel::query_builder::SelectStatement<_, _, _, diesel::query_builder::where_clause::WhereClause<diesel::expression::operators::Eq<schema::articles::columns::id, diesel::expression::bound::Bound<diesel::sql_types::Integer, i32>>>>`
       found struct `diesel::query_builder::SelectStatement<_, _, _, diesel::query_builder::where_clause::WhereClause<diesel::expression::operators::Eq<schema::articles::columns::slug, diesel::expression::bound::Bound<diesel::sql_types::Text, &str>>>>`