Posts for: #2023/11

rbac なロールでの動的な権限チェック

23時に寝て何度か起きて7時に起きた。夜に作業するつもりが、メイドインアビス を見ながら寝落ちした。

ldap で認証したユーザーの権限管理

rbac なロール管理 の仕組みを api サーバーに実装した。初期実装したときは静的にリソース (url) に対して acl から権限が許可されているかどうかのみをチェックするだけでよかった。ldap で認証したユーザーは自分の情報は更新できるが、他人の情報は更新できないといったリクエスト単位に権限が許可されているかどうかをミドルウェアで判別したい。いわば、リクエスト時に動的にリソースの情報をチェックしないといけない。

いくつか試行錯誤して、あーでもないこーどもないとやった結果、次のように落ち着いた。

  • リソースは動的な権限チェックのために AuthorizeFunc を取得するための AuthorizeKey をもつ
  • AuthorizeFunc は Context から取得する
  • AuthorizeFunc が true を返す場合は権限を付与する
func (r *Role) CanAccess(ctx context.Context, resourceName, target string) bool {
	for _, ac := range r.ACL {
		if ac.Resource.Match(resourceName) {
			for _, perm := range ac.Permissions {
				if perm.IsGranted(target) {
					return true
				}
			}
			if authorize, ok := ctx.Value(ac.Resource.Key).(AuthorizeFunc); ok {
				if authorize(ctx, resourceName, target) {
					return true
				}
			}
		}
	}
	return false
}

ロールに渡す Context にはあらかじめ、AuthorizeKey と AuthorizeFunc を登録しておく。

ctx = context.WithValue(ctx, role.LDAPResource, role.IsLDAPResourceOwner)

リソースを生成するときに AuthorizeKey をセットしておく。

ldapUserResource = rbac.NewResource(
	"ldap-user-specific-operation",
	"(/api/ldap/entry|/api/ldap/entry/.*)",
	LDAPResource,
)

ちょっと設定は煩雑になるが、ひとまずこれで要件を満たせた。

葛藤も逡巡もしない

2時に寝て4時に起きて6時に起きて7時半に起きた。意味なくあまりよく眠れなかった。自分の pr のレビュー待ちやリファクタリングと他人のデザインレビュー/コードレビューなど、いろいろ雑多なことをやって隙間の1日になった。

メイドインアビス 烈日の黄金郷

ちょっと時期は遅れていると思うけど、メイドインアビス の新しい作品が配信されているのに気付いた。晩ごはんを食べてから見始めたらおもしろくて、夜に別作業をするつもりが寝落ちするまで見続けてしまった。

劇場版「メイドインアビス」-深き魂の黎明- も何度もみた。好きな作品の1つだ。敵としてボンボルドというキャラクターが出てくるが、ボンボルドの在り方は一概に悪とか非道とか、サイコパスと断じられるものでもなく、なにか強い印象に残っていた。

今回の「烈日の黄金郷」においても敵でないが、ワズキャンというリーダーキャラクターが出てくる。メイドインアビスは、その世界観として死が身近な状況における強いリーダーシップを描いているようにみえる。それが世界観のせいなのか、作者の独特の感性なのか、その両方なのかはわからないが、とても特異なリーダーシップにみえてしまう。現代の生活や価値観から言えばサイコパスのようにみえるが、作品の世界観から言えば、強いリーダーシップと解釈できる。そのリーダーの選択、決断、思考、信念、潔さのどれもが淡々としたストーリーの展開をミステリアスなものにしている。

なぜか私はこの作品のちょっと特異なリーダーに共感するところがあっておもしろくみることができる。共感するところの1つに、メイドインアビスに出てくるリーダーは葛藤や逡巡をしない。括弧とした信念があるから仲間を犠牲にしても自責しない。それがある種の潔さや偽善を感じない爽快さにつながっていて私の価値観にあっているように思える。そう、失敗しても潔いのが私は好きなのだ。誰かの責任にもしないし、その結果で自暴自棄になったりもしない。なにが起きてもそれは自分の人生で受け入れていくしかない。メイドインアビスに出てくるリーダー像はまさにそれを体現しているように思う。

考えないという傷のある現場

2時に寝て7時半に起きた。昨日からよく寝た。また心機一転。

ldap エントリーの crud api

先週から ldap クライアントや そのプール を実装して結合テストも一通り書いていた。今日はそれらを使った crud な web api を一通り実装した。クライアント実装もテストもしっかり出来ているので後は時間の問題で1つずつ確認しながらコードを書いていくだけだった。こういう作業になると、まとまった時間があればすぐに終わる。他のメンバーのコードレビューをみたり、設計の話しをしたり、他に意識を取られてあまり自分の作業に集中できなかった。

言葉が通じないもどかしさ

先週「参考にして」と指示したものが「全コピー」で驚いてしまった。私がいくつか指摘したらすぐに削除し始めてさらに落胆した。自分の頭で考えて作業していないようにみえる。

開発というお仕事は自分で考えて、コードの1つ1つに明確な意図や根拠をもって書くものだ。もちろん、情報不足や設計に自信がもてなくて一時的に曖昧な実装にするときもあるけれど、それは懸念事項として把握しておくことで将来対応すればよい。基本的に追加するコードにはすべて意味がある。

他人が分からなくても自分が理解できているのなら、自分の考えを説明し、それが論理的であったり筋が通っていれば、私は自分の考えと違っていても構わない。説明できないコードを追加して、ツッコミを受けてなにも説明できない状況をみているのは本当に悲しい。

山田ズーニーさんの著書に書いてあった「考えないという傷」を思い出した。

秋休み3

2時に寝て何度か起きて8時に起きた。休むつもりはなかったのだけれども、お昼までゆっくりしていたら、今日はもういっかと思ってそのままお休みすることにした。疲れていたのかもしれない。1日のんびりしていた。

筋肉痛の翌日

昨日は山登りで筋肉痛になって夕方からずっと寝ていて7時に起きて8時半に起きた。それでも寝たら筋肉痛はある程度は直った。寝ると回復するもんや。

ストレッチ

昨日から全身筋肉痛になっている。それでも夕方からずっと安静にしていたせいか、昨日の一番ひどかった頃よりずっと回復していた。さらにストレッチでそういった話しをしたら、トレーナーさんも筋肉痛を気遣った形でストレッチをしてくれた。筋肉痛の状態だと筋肉は伸びないらしい。あまり筋を押さず、ほぐすようなストレッチにしてくれたという。筋肉痛にも関わらず、いつもよりも関節や筋肉の負荷が小さかったように思える。今日の開脚幅は開始前153cmで、ストレッチ後155cmだった。

カフーツさん訪問

たまたま見かけたので ブログJelly Vol.135 に参加してきた。瑞祥 黒松剣菱 というお酒をもっていった。こういうイベントで灘のお酒を飲む機会にしようと思ったものの、今回は周りの人たちにあわせてワインとビールを飲むだけで終わってしまった。次回のイベントのときに飲みましょうとお酒を置いてきた。私自身、家で日本酒を飲まない。カジュアルに日本酒を飲もうという空気や雰囲気がない。入り口を変えるため、日本酒にあう食事やつまみも用意していくのがよいと気付いた。次回は日本酒向けの食べものをもっていこうと思う。

昨日の山登りの下山中もマネジメントや気付きについて2時間ほど一緒に行った人たちと話していた。ここでもお酒が入ったらその延長の話しをだらだらやってしまった。気付きがないという事象に対して、どうやれば気付きを得られるようになるか、その背景や変化、人の特性・性格・成長などについて、私はいま関心をもっている。人に依るというのも多分にあると思う。教えてできることなのかどうかすら、私はわかっていない。私の立場としては、仕組みとプラクティスで気付きを与えて、教育によって成長することを願いたい。

いとうさんに note のオンラインコンテンツの領収書にインボイスの登録番号を設定してほしいとお願いした。さらにコワーキングスペースのサービス料がいま1,000円になっている。よくみると、90円の消費税を含んで税込み価格になっている。こういうとき、1,000円をサービス料、100円を消費税、税込みで1,100円にすればいいとアドバイスした。次回からそうするといとうさんも話されていた。免税事業者が課税事業者になっても事業者の損益には影響を与えない状態を支持したい。

インボイスの少額特例

freee の「修正待ちリスト一覧」にインボイスの少額特例に該当する明細があるという通知が出ている。次の条件に当てはまる事業者は少額特例の対象になるという。

「前々年度の課税売上高が1億円以下」または「前年度の開始から6ヶ月間の課税売上高が5,000万円以下」のどちらかに当てはまる事業者で、税込1万円未満の仕入や経費は、インボイス(適格請求書)があるかどうかにかかわらず仕入税額を控除できます。

うちは消費税の申告に 簡易課税制度 を選択しているため、事実上、インボイスの有無で消費税の仕入れ控除に影響はない。実際の消費税の納税には影響を与えないが、税制の理解を深めるために取引明細や税区分の処理などをちゃんと記帳しようとは考えている。将来的に簡易課税制度が廃止されたり、その条件を満たさないようになる可能性もある。消費税のようなシンプルな税金にも関わらず、事業者は本質的に損益に影響を与えないものにも関わらず、取引先との関係、政治や社会的な事情によって税制が混乱している。

消費税の逆進性についての問題も見聞きはする。次の記事では生活必需品に低い税率を適用することで緩和するという対策を述べている。さまざまな条件で時限的な特例を多重に発令するよりも、すでに軽減税率があるのだから食品は5%にするとか、そういったシンプルな税制で対策を取れないのだろうかと考えてしまう。

ハイキング山登り

ハイキング山登り

4時に寝て8時に起きた。久しぶりに深夜過ぎまでコードを書いて、あと文章を書いて、気付いたら3時をまわっていた。

新神戸駅からのハイキング

新神戸駅に10時集合、遅刻もあって少し出発は遅れたが、10時半には駅を出発した。駅を出たらすぐに登山道に入れる。これはすごい立地だと思う。通常、登山道までは市街地から1-2時間かけて移動することが多いと思う。新神戸駅という市街地からすぐに山登りできるというのは神戸観光の1つとして十分によいと思えた。11月としては高めの最高気温23℃とやや暑いぐらいだったが、山登りにはちょうどいい気候だった。寒い時期や暑い時期を避けるという意味で11月はよい時期の選択にみえる。まだ暖かいせいか、紅葉は始まったばかりで、もう少し遅い時期だと紅葉も楽しめてよいかもしれない。

布引の滝 (雄滝)

ハイキングマップの B 布引ゾーンは、山道もコンクリートで舗装されていて歩きやすい。布引の滝は雌と雄の2つがあり、雄滝は整備されているのもあって観光向けになっている。

布引五本松堰堤

ダムの1つ。周囲をぐるっと回りながらハイキングを続ける。この辺りも舗装された道路が続くので初心者向けコースの延長にある。紅葉はほとんどなかった。

再度山 (ふたたびやま) 山頂

大龍寺から30分ぐらいかな?ここは初心者向けではなく、やや険しい山道を登っていく必要がある。道路は整備されなくて、かろうじて1人が歩けるような狭い山道を、所々、よじ登るような感覚でやや体力がいる。体力のない人や子どもはちょっと難しいと思う。私がいっぱいいっぱいだったので (山登りに慣れていない) 高齢な人には無理だと思う。山頂には 470m という置きものがあって神戸の町並みを展望できる。ここまでは舗装された道路のハイキングなので山登りが好きな人はこのぐらいの負荷をかけた方が楽しめるかもしれない。

山頂から下って再度山公園へ到着した。上るのが山道だったから下るのも山道で、下手すると崖から滑ってしまうので降りるのも注意が必要になる。

再度山公園

ここは車でも来れるそうで、のどかな公園になっていた。紅葉もちらほらみえて、あと2-3週間したらよい時期かもしれない。また車でも行ってみようかと思う。ここで休憩しているときに13時をまわっていたと思う。登りは所々でうちらは休憩をとってゆっくり進んでいたので一般よりは遅いペースだったと思う。

下山

ここからは一気に下山してきた。なだらかな下りがずっと続くコースだったので体力的にはそうしんどくなく一気に降りてきた。だいたい2時間ぐらいで県庁駅まで来れた。そこで15時ぐらいになっていた。これはこれで山道を眺めながら歩くのも気持ちがよいし、登る方が好きな人はもっと登ってロープウェイで降りてくるというのもよいかもしれない。私は太ももの負荷が限界なぐらい体力的にしんどかったのでこのぐらいの行程が限界だというのもわかってよかった。歩ける距離としては3時間程度を目安に、なだらかなハイキングコースを探すとよさそうに思う。

論理の通じない人たち

23時に寝て何度か起きて8時に起きた。ホテルの部屋が暗いと朝になった気がしなくて2度寝したら寝坊した。

組織の対応と sns の議論

先日の sns 騒ぎ の続き。公式からの声明も出たので軽くまとめておく。

簡潔な文章に事実の記述、責任の所在、関係者への配慮が含まれていて十分な内容にみえる。法律なども関係するため、弁護士チェックが必要なことを考慮すると、こんな短期間で組織の見解を出せたことは運営側の体制を鑑みることができる。それが適正かどうかは人によって判断は異なるかもしれないが、私はコミュニティ運営というボランティア主体の組織であれば十分なものだと思えた。その後のネット上の議論も、ちゃんと追えてはいないが、様々な見解で議論は進んでいるようにみえる。

今回みていて感じたことの1つに、コミュニケーションが成り立たない人が世の中にはたくさんいるということ。議論の前提や論理の出発点が異なる人たちは、一定の論理を含む全体や大局を理解できず、細部や詳細のところだけを拠り所に自身の論理を組み立てる。意見の差異があることはなんら問題はないが、論理が通じないのは議論の余地すらないようにみえた。そういう人たちを会話するときは前提条件を同じにしたり、思想の背景を共有したり、もっと時間をかけて丁寧にすり合わせていく作業が必要になる。そして sns のような、流れが速い不特定多数の議論はそういった丁寧な作業にまったく向いていない。だから sns で議論することは時間の無駄である。

コネクションを共有しないプール

go の非同期処理であまり使われることはないが、semaphore が準公式ライブラリとして提供されている。私はセマフォを気に入っていてたまに使う。

ldap プロトコルではコネクションの確立とログインに相当する bind の操作が分かれている。コネクションを確立したまま、ログアウトに相当する処理ができればプールを設けることでコネクションの再利用ができる。

しかし、このドキュメントの説明によると、unbind という操作は用意されているものの、ログアウトに相当する機能ではなく、クローズする前に通知するといった用途だと書いてある。unbind のリクエストをした後にはクローズするしかないといったものになる。それを踏まえて、プールはセマフォで同時接続数のみを制御するのでよいのではないかと思う。そんなワーカープールを実装してみた。

type ClientPool struct {
	config *config.LDAP
	sem    *semaphore.Weighted
}

func (p *ClientPool) Get(
	ctx context.Context,
) (*LDAPClient, error) {
	if !p.sem.TryAcquire(1) {
		return nil, fmt.Errorf("failed to acquire, wait and get later")
	}
	client := NewLDAPClient(p.config)
	if err := client.Connect(ctx); err != nil {
		p.sem.Release(1)
		return nil, fmt.Errorf("failed to connect: %w", err)
	}
	return client, nil
}

func (p *ClientPool) GetAuthenticated(
	ctx context.Context,
) (*LDAPClient, error) {
	client, err := p.Get(ctx)
	if err != nil {
		return nil, fmt.Errorf("failed to get: %w", err)
	}
	dn := p.config.BindDN
	passwd := p.config.BindPasswd.String()
	if err := client.Bind(ctx, dn, passwd); err != nil {
		p.sem.Release(1)
		return nil, fmt.Errorf("failed to bind: %w", err)
	}
	return client, nil
}

func (p *ClientPool) Close(client *LDAPClient) error {
	err := client.Close()
	p.sem.Release(1)
	return err
}

func NewClientPool(cfg *config.LDAP) *ClientPool {
	return &ClientPool{
		config: cfg,
		sem:    semaphore.NewWeighted(cfg.ClientPoolSize),
	}
}

穴場のビアバー

穴場のビアバー

0時に寝て何度か起きて6時半に起きた。移動日の疲れもあってか、いつもよりよく眠れた気がする。

朝食バイキング

先々月から大崎探索 をしていて ニューオータニイン東京 に泊まってみた。川沿いの道を歩きながら朝食バイキングもおいしい。食品の品数があると満足度が高い。

プロジェクトの進捗報告

出張したときの月例報告の11回目。前回の進捗報告はこちら

まだ開発の序盤なので 事前に準備した資料 の内容を一通り終えて雑談の時間も多かったように思う。3回目の開発フェーズになるのもあり、メンバーの練度も上がって、開発の手際はかなりよくなっているように私からはみえている。それらも含めて、メンバーが自律的に issue を作ったり、タスクを自分に割り当てたりしながら開発が進むようになっていると報告した。プロジェクトオーナーからも、最近のマイルストーン定例をみていて、メンバーが気付きが増えている、自律的によくないところを改善しようという意思がみえるといった話題も出ていた。課題管理のプラクティスを実践してきて、着実によい開発者の習慣を身につけて、よい開発チームに育ってきているように、私からもみえている。あとは課題管理についてのコンテンツを私が書かないといけないのを、バーンナウトの影響もあってか、先月はさぼってしまっていたので、今月こそなんか書きますと、自分を追い込む意図でもその場で話題にした。

mongo とトランザクションとレプリカセット

mongo には トランザクション の機能が提供されている。しかし、トランザクションを使うためには レプリケーション を有効にしないといけない。レプリケーションは通常は複数台のマシンでクラスタリングを構築するものになる。うちらはシングルノードの mongo を扱っているのでレプリケーションを必要としていない。それでも、ドキュメントを読んでいると、スタンドアローンでも本番環境ではレプリカセットを使う方がよいといった説明もみつかる。

ちょうど開発の要件としてトランザクションを必要とする状況も出てきた。mongo のレプリケーションやトランザクションの仕組みを理解するよい機会かもしれない。11月中には調査したいというところ。

エビスバー

大崎探検の2日目。YEBISU BAR 大崎店 へ行ってみた。大崎駅横の駅ビルの2階にある。アクセスもよい。水曜日なのに20-21時半ぐらいまでいて、お客さんは3組ぐらしかいなかった。よい意味で空いてて静かにゆっくり飲めてよかった。穴場のバーをみつけた。ビール2杯とつまみ2品でちょうど3000円程度。ちょっと割高かもしれないけど、場所とお店の雰囲気とゆっくりできたことを考慮するとちょうどよい価格帯にも思える。またゆっくり軽く飲みたいときに行こうと思う。