データへのアクセスを制限する¶
重要
このチュートリアルは、 :doc:の server_framework_101
チュートリアルの拡張です。 完了したことを確認し、このチュートリアルの演習のベースとして構築した`estate`モジュールを使用してください。
ここまでは、便利な機能の実装を中心に説明してきました。しかし、ほとんどのビジネスシナリオでは、すぐに セキュリティ が問題になります。
すべての従業員(
group_user
が意味するもの) が、物件情報、物件タイプ、または物件タグの作成、参照、更新、または削除を行うことができます。If
estate_account
is installed then only agents allowed to interact with invoicing can confirm sales as that's necessary to create an invoice.
ところが:
第三者が物件に直接アクセスできるようにはしたくありません。
当社の従業員全員が不動産エージェントではないため(例:管理担当者、不動産管理者など) 、エージェントではない人に利用可能な物件を見せたくありません。
不動産業者は、 利用可能な 物件の種類やタグを決定する必要はありません。
実際のエステイトエージェントは、*排他的*プロパティを持つことができます。1つのエージェントが他のエージェントの排他を管理できるようにしたくありません。
すべての不動産業者は、自分が管理する物件の販売内容を確認できるべきですが、システム内の請求書を検証したり、支払い済みとしてマークしたりすることはできないようにします。
注釈
小規模な企業であれば、これらのいくつか、あるいはほとんどの機能を利用しても問題ないかもしれません。
ユーザーが無から作成するよりも不必要なセキュリティルールを無効にする方が簡単だからです。 注意を払ってアクセスを制限するのが良いでしょう必要であればリラックスできるのです
グループ¶
関連項目
このトピックに関連するドキュメントは、 セキュリティ リファレンス にあります。
/contributoring/development/coding_guidelines はマスターデータ項目のフォーマットと場所をドキュメント化します。
目標
このセクションの最後には、
従業員を 不動産エージェント または 不動産マネージャー にすることができます。
admin
ユーザーは不動産マネージャーです。請求または管理にアクセスできない、新しい 不動産エージェント 従業員がいるとします。
変更が必要になるたびに従業員に個別のセキュリティルールを適用するのは現実的ではないので、 グループ でセキュリティルールとユーザを結びつけます。グループは、従業員に割り当てることのできるロールに対応しています。
ほとんどのOdooアプリケーション 1 では、良いベースラインとして、 ユーザー と マネージャー (または管理者) の役割を持たせます。マネージャーはアプリケーションの設定を変更し、その使用全体を監督することができ、ユーザーはアプリケーション 2 を使用することができます。
このベースラインは、私たちにとって十分なものです。
不動産管理者は、システムの設定(利用可能なタイプやタグの管理) や、パイプラインのすべての物件を監督することができます。
不動産エージェントは、自分が担当している物件や、特に担当していない物件を管理することができます。
Odoo のデータ駆動型の性質に合わせて、グループは res.groups
モデルのレコードにすぎません。 これらは通常、モジュールのデータファイルのいずれかで定義されている :doc:`master data <define_module_data>`の一部です。
単純な例は こちら で確認できます。
Exercise
security.xml
ファイルを適切なフォルダに作成し、__manifest__.py
ファイルに付け加えます。まだ設定されていない場合は、
Real Estate/Brokerage
の値を持つ__manifest__.py
に``'category`` フィールドを追加してください。Id
estate_group_user
、名前 "Agent" および カテゴリbase.module_category_real_estate_brokrakage
でグループを作成するレコードを追加します。続けて、Id
estate_group_manager
、名前 "Manager" 、カテゴリbase.module_category_real_estate_brokerage
でグループを作成するレコードを追加します。estate_group_manager
グループはestate_group_user
を内包する必要があります。
注釈
Where does that category comes from ? It's a module category.
Here we used the category id base.module_category_real_estate_brokerage
which was automatically generated by Odoo based on the category
set in the __manifest__.py
of the module.
You can also find here the list of
default module categories
provided by Odoo.
ちなみに
データファイルを変更したので、 -u estate
を使ってOdoo を再起動し、モジュールを更新することを忘れないでください。
admin
ユーザー ("Mitchell Admin") を開くと、新しいセクションが表示されます。

管理者ユーザーを Real Estate manager に設定します。
Exercise
Webインターフェイスを介して、 "不動産エージェント" アクセス権限のみを持つ新しいユーザーを作成します。そのユーザーは請求書発行または管理アクセス権限を持ってはいけません。
新しいユーザーでログインするには、プライベートタブかプライベートウィンドウを使用します (パスワードを設定することを忘れないでください) 。不動産エージェントとして、不動産アプリケーション、およびディスカッション(チャット) アプリケーションのみを表示できることでしょう。

アクセス権限¶
関連項目
このトピックに関連する文書は、 アクセス権限 にあります。
目標
このセクションの最後には、
少なくとも不動産エージェントではない従業員には、不動産アプリケーションが表示されません。
不動産エージェントは、物件の種類やタグを更新することはできません。
アクセス権は 第4章:セキュリティー-簡単な紹介 で最初に導入されました。
アクセス権は、グループを 介して ユーザーにモデルへのアクセス権を与える方法です。グループへのアクセス権を関連付けることで、そのグループを持つすべてのユーザーがアクセスできるようになります
例えば、不動産エージェントが利用可能な物件タイプを変更できないようにします。 そのアクセス権限を "user" グループにリンクしないようにしました
アクセス権はアクセス許可を与えるだけで、削除することはできません。アクセスがチェックされると、システムは、(グループを介して) そのユーザーに関連する すべての アクセス権限を確認し、どのアクセスを許可しているかどうかを判断します。
グループ |
追加(create) |
参照(read) |
更新(update) |
削除(delete) |
A |
X |
X |
||
B |
X |
|||
C |
X |
グループAとCを持つユーザーは、オブジェクトを削除するだけでなく、BとCを持つユーザーはそれを読み取り、更新することができます。 それを作成または削除しません。
注釈
アクセス権のグループは省略できます。これはACLが*すべてのユーザー*に適用されることを意味します。 これは有用だが危険なフォールバックだ インストールされたアプリケーションによっては 非ユーザでもモデルにアクセスできるようになる
あるユーザーにアクセス権が適用されない場合、そのユーザーにはアクセスが許可されません(デフォルトでは拒否)。
メニュー項目がアクセス権を持たず、ユーザが見ることができるサブメニューを持たないモデルを指す場合。 メニューは表示されません。
Exercise
アクセス権ファイルを次のようにしてみましょう。
不動産管理グループにすべてのオブジェクトへのフルアクセスを許可します。
エージェント(不動産ユーザー) には、タイプとタグへの参照アクセスのみを許可します。
プロパティを削除する権利を誰にも与えません。
エージェントユーザは、タイプやタグを変更したり、物件情報を削除したりすることはできませんが、それ以外の作成や更新はできることを確認してください。
警告
ir.model.access
レコードには、異なる xid を与えることを忘れないでください。そうしないと、互いに上書きされてしまいます。
"demo" ユーザーは不動産エージェントまたはマネージャーにされていないので、彼らは不動産アプリケーションを見ることすらできないはずです。 プライベートタブまたはプライベートウィンドウを使用してこれを確認します( "demo" ユーザーのパスワードは "demo" です) 。
ルールを記録¶
関連項目
このトピックに関連するドキュメントは、 ルールを記録 にあります。
目標
このセクションの最後では、エージェントは同僚の特定の物件情報を見ることができませんが、マネージャはすべてを見ることができるようになっています。
アクセス権は、モデル全体へのアクセスを許可することができますが、多くの場合、より具体的にする必要があります。エージェントが一般的な物件情報を操作することができる一方で、同僚の一人が管理する物件情報を更新したり、見たりすることを望んでいない場合があります。
記録する 規則 はその正確さを提供します: 個々の記録へのアクセスを許可または拒否することができます:
<record id="rule_id" model="ir.rule">
<field name="name">A description of the rule's role</field>
<field name="model_id" ref="model_to_manage"/>
<field name="perm_read" eval="False"/>
<field name="groups" eval="[Command.link(ref('base.group_user'))]"/>
<field name="domain_force">[
'|', ('user_id', '=', user.id),
('user_id', '=', False)
]</field>
</record>
ドメインを検索 は、アクセスを管理するためのものです。レコードがパスされた場合、アクセスが許可され、そうでなければ、アクセスが拒否されます。
ちなみに
ルールはやや複雑で、一括して作成されない傾向があるため、通常はアクセス権に使用されるCSVではなく、XMLで作成されます。
上記のルールについて:
"作成(create)"、"更新(update)" (write) 、 "削除(delete)" (unlink) といった操作にのみ適用されます。ここでは、すべての従業員が他のユーザーの記録を見ることができますが、作成者/担当者のみがレコードを更新できます。
非グローバル ですので、マネージャーなどの追加ルールを提供できます。
現在のユーザー (
user.id
) がレコードに設定されている場合 (例:作成した、または、割り当てられている) や、レコードに関連するユーザーが全くいない場合に、操作を許可します。
注釈
ルールが定義されていないか、モデルと操作に適用されていない場合、その操作は許可されます(デフォルトは許可) 。これは、アクセス権が正しく設定されていない(許可しすぎている) 場合、奇妙な影響をもたらす可能性があります。
Exercise
エージェントは見ることしかできないように制限するルールや、営業担当者が設定されていないか自分が営業担当者になっている物件情報のみ変更できるように制限するルールを定義してみましょう。
不動産エージェントのユーザーをもう一人作るか、営業担当者がマネージャーや他のユーザーである物件をいくつか作ります。
不動産マネージャーがすべての物件を見ることができることを確認してください。できない場合、なぜできないのか思い出してください。
estate_group_manager
グループはestate_group_user
を内包する必要があります。
セキュリティオーバーライド¶
セキュリティのバイパス¶
目標
このセクションの最後では、不動産エージェントが請求書作成のためのアクセス権を必要とせずに、物件の販売を確認できるようになっています。
不動産エージェントとして物件を "sold(売却済み)" にしようとすると、アクセスエラーが発生するはずです。

これは、 estate_account
がプロセスの中で請求書を作成しようとするために起こりますが、請求書の作成には、すべての請求書管理の権限が必要なのです。
エージェントが完全な請求権限を持たずに販売を確認できるようにしたいと考えています。つまり、現在のユーザーがそのような権限を持って いないくても 、請求書を作成するためには、Odooの通常のセキュリティチェックを バイパス する必要があります。
Odooの既存のセキュリティチェックを迂回するには、あえて迂回する方法と副作用として迂回する方法の2つの方法があります。
sudo()
メソッドは "sudoモード" で新しいレコードセットを作成します これはすべてのアクセス権と記録ルールを無視します(ただし、ハードコードされたグループとユーザーのチェックは依然として適用されます)。RAWSQLクエリを実行すると、アクセス権を回避し、ORM自体をバイパスする副作用としてルールを記録します。
Exercise
請求書作成時にアクセス権やルールを回避するように、 estate_account
を更新してみましょう。
危険
このような機能は一般的に避けるべきであり、現在のユーザーと操作が通常のアクセス権の検証を回避できることを確認した上で、細心の注意を払ってのみ使用する必要があります。
また、このようなモードで実行される操作は、ユーザーの入力にできるだけ頼らず、できる限り検証を行うべきです。
プログラムによるセキュリティチェック¶
目標
このセクションの最後には、請求書の作成が estate
への変更に関わらず、セキュリティ上の問題に対して堅牢なものになっています。
Odoo では、アクセス権と記録ルールは、ORM 経由でデータアクセスを行う場合にのみチェックされます。 ORMメソッド経由でレコードを作成、読み取り、検索、書き込み、またはリンク解除します。他のメソッドは必ずしもあらゆる種類のアクセス権をチェックしません。
前のセクションでは、action_sold
で請求書を作成するときにレコード規則をバイパスしました。 このバイパスは、チェックされている権利を持たない任意のユーザーがアクセスすることができます。
請求書の作成前に、
estate_account
のaction_sold
にプリントを追加します (請求書の作成は物件情報にアクセスするため、ACLチェックが行われます) 。print(" reached ".center(100, '='))
Odooのログに reached
が表示され、続いてアクセスエラーが表示されるはずです。
危険
すでにPythonのコードに入っているからといって、アクセス権やルールがチェックされた、あるいはチェックされるとは限りません。
現状では 、アクセスは、 self
のデータへのアクセスによって暗黙のうちにチェックされ、 super()
(これも同様に self
を 更新します) を呼び出すことで、アクセスエラーが発生し、トランザクションをキャンセルして、請求書を "uncreating(作成解除)" にしています。
しかし 、これが将来的に変更されたり、メソッドに副次的作用が追加されたり (例:政府機関に売却を報告する) 、 estate
にバグが混入したりすると、エージェント以外の人がアクセスしてはいけない操作をトリガーすることが可能になります。
したがって、CRUDではない操作を行う場合や、ORMやセキュリティを正当にバイパスする場合、あるいはその他の副次的作用を引き起こす場合には、明示的なセキュリティチェックを行うことが非常に重要です。
明示的なセキュリティチェックは次の方法で行うことができます。
現在のユーザーが誰であるかをチェックし (
self.env.user
) 、特定のモデルやレコードと照合する。現在のユーザーが、操作を許可または拒否するためにハードコードされた特定のグループを持っているかどうかをチェックする (
self.env.user.has_group
) 。レコードセットに
check_access(operations)
を呼び出すと、現在のユーザーがセットの すべて レコードに対して操作を実行できることが確認されます。 特殊なケースとして、レコードセットが空の場合。 それは現在のユーザーがアクセス権を持っていることを確認します一般的にモデルの操作を実行する。
Exercise
請求書を作成する前に、check_access
を使用して、現在のユーザーが請求書のプロパティを更新できるようにします。
バイパス・スクリプトを再実行し、印刷の前にエラーが発生することを確認してみましょう。
マルチカンパニーでのセキュリティ¶
関連項目
:ref:は、一般的にマルチ企業施設の概要についての「参照/howtos/company」、特に :ref:は「マルチ企業セキュリティルール <howto/company/security>」です。
一般的なルールに関する文書は、 ルールを記録 にあります。
目標
このセクションの最後では、エージェントが自分の所属するエージェンシー(または複数のエージェンシー) の物件にのみアクセスできるようになります。
何らかの理由で、当社は不動産事業を複数の企業として管理する必要がある場合があります。 自立した組織やフランチャイズの仕組みがあるかもしれません 法的または財政的にお互いに分離した複数のブランド(他の不動産事業を買収した可能性があります)があります。
Odoo は、同じシステム内の複数の企業を管理するために使用することができます。 ただし、実際の取り扱いは個々のモジュールに応じて行われます。Odoo 自体は、会社に依存するフィールドと マルチ企業規則 の問題を管理するためのツールを提供します。 我々自身が関心を持っていることです
私たちは、異なる代理店を互いに "サイロ化" し、物件は特定の代理店に属し、ユーザー(代理店またはマネージャー) は自分の代理店にリンクされた物件のみを見ることができるようにしたいと考えています。
先に述べたように、これは自明ではない記録に基づいているため、ユーザにとってはルールを厳しくするよりも緩める方が簡単であり、比較的強いセキュリティモデルをデフォルトにすることは理にかなっています。
複数の会社のルールは単純に company_ids
または company_id
フィールドに基づいて記録されます。
company_ids
は、現在のユーザーがアクセスできるすべての会社です。company_id
は、現在のアクティブな会社(ユーザーが現在働いている会社) です。
マルチカンパニールールでは 通常 、前者を使用します。つまり、レコードがユーザーのアクセス権を持つ会社の 1つ に関連しているかどうかをチェックします。
<record model="ir.rule" id="hr_appraisal_plan_comp_rule">
<field name="name">Appraisal Plan multi-company</field>
<field name="model_id" ref="model_hr_appraisal_plan"/>
<field name="domain_force">[
'|', ('company_id', '=', False),
('company_id', 'in', company_ids)
]</field>
</record>
危険
マルチ企業規則は通常 :ref:`global <reference/security/rules/global>`です。そうでなければ、追加規則がマルチ企業規則のバイパスを可能にするリスクが高いです。
Exercise
estate.property
にcompany_id
フィールドを追加します。これは必須であり(代理店のない物件は望ましくありません) 、現在のユーザの現在の会社をデフォルトとします。新しい会社を作成し、その会社を新しい不動産エージェントとします。
マネージャーは両方の会社のメンバーであるものとします。
従来エージェントは、従来会社のメンバーでなければなりません。
それぞれの会社にいくつかの物件を作成します(マネージャーとして会社のセレクタを使用するか、エージェントを使用します) 。デフォルトの営業担当者の設定を解除して、 この ルールがトリガーされることを回避します。
すべてのエージェントがすべての会社を見ることができますが、これは望ましくないので、この動作を制限するレコードルールを追加してみましょう。
警告
モジュールのモデルやデータを変更した場合は、必ず --update
してください。
可視性 != セキュリティ¶
目標
このセクションの最後に、不動産エージェントは、不動産アプリケーションの設定メニューを表示しないでください。 しかし、プロパティの種類やタグを設定することができます。
特定のOdooモデルをグループ(または会社やユーザー) に直接関連付けることができます。この関連付けが セキュリティ 機能なのか 可視化 機能なのかを利用する前に把握することが重要です。
可視性 機能は、ユーザーがモデルにアクセスしたり、それ以外の場合でも記録することができます。 インターフェイスの別の部分を介して、または RPC、コンテキストによってはWebインターフェースに表示されない場合があります。
セキュリティ 機能とは、ユーザーがレコード、フィールド、操作にアクセスできないことを意味します。
いくつかの例を示します。
(Pythonコード内の) モデルフィールド におけるグループはセキュリティ機能であり、グループ外のユーザーはフィールドを取得することができず、またその存在を知ることもできません。
例:サーバーアクションでは、 システムユーザーのみがPythonコードを見たり更新したりすることができます。
(XMLファイル内の) ビュー要素 におけるグループは可視化機能です。グループ外のユーザーはフォーム内の要素やその内容を見ることはできませんが、それ以外では(そのフィールドを含んだ) オブジェクトを操作することができます。
メニューやアクションにおけるグループは可視化機能です。メニューやアクションはインターフェイスに表示されませんが、基礎となるオブジェクトと直接対話することは妨げられません。
Exercise
不動産エージェントは、プロパティの種類やタグを追加することはできませんが、作成時にプロパティフォームビューからオプションを確認することができます。
format@@0メニューは、インターフェイスにノイズを追加するだけで、マネージャーにのみ表示できます。
物件タイプや物件タグのメニューにアクセスできなくなったにもかかわらず、エージェントはタグやタイプを選択してプロパティに設定することができるので、オブジェクトそのものにアクセスすることができます。