34

他の人がこれをどのように設計するかについてのいくつかのインプットを探しています。クラス(djangoグループ)ベースのビューを提供します。

たとえば、ユーザーのグループは、ユーザーがアクセスできるビュー/テンプレートを決定します。ユーザーのリンクバーが何で構成されるかを決定するために、関数を表示するためのパスをテーブルに格納することを考えています。フィルタ仕様を保存して、これらのテンプレートを埋める行を決定することもできます。

良い例は病院の看護ユニットです。1つのユニットの看護師は、病院全体の患者を診察する必要はありません。彼らは彼らの患者に会う必要があるだけです。同じユニットの医師は、それらの患者も診察する必要がありますが、はるかに優れた機能にアクセスできる必要があります。

これは、サードパーティのアプリケーションを介して行われましたか?そして、この問題にどのようにアプローチしますか?

ありがとう、ピート

4

9 に答える 9

46

Django にはすでにグループと権限システムがあり、目的には十分かもしれません。

http://docs.djangoproject.com/en/dev/topics/auth/

通常、コードでは、ユーザーに権限があるかどうかを確認します。ユーザーには、自分の権限と、所属するグループの権限があります。これは、管理コンソールから非常に簡単に管理できます。

2 つの部分を確認する必要があります。

  1. ページをリクエストしているユーザーにその権限があることを確認してください。
  2. ユーザーが許可を持っている場合にのみ、ユーザーへのリンクを表示します。

1.の場合、次のようにデコレータで権限を確認できます。

from django.contrib.auth.decorators import permission_required

@permission_required('polls.can_vote')
def some_view(request):

2. の場合、現在ログインしているユーザーの権限は、テンプレート変数 {{ perms }} に格納されます。このコードは、上記と同じ権限をチェックします。

{% if perms.polls.can_vote %}
    <a href="/vote">vote</a>
{% endif %}

リンクのリストを生成するには、 user.get_all_permissions() を反復処理して、dict からリンク (またはリンクを生成する関数) をフェッチします。

def more_elaborate_list_of_links_for_a_perm(user):
    return ["/link1", ...]

_LINKS = {
    'polls.can_vote' : lambda u: ["/user/specific/link/" + u.id],
    'polls.can_close': lambda u: ['/static/link/1', 'static/link/2'],
    'polls.can_open' : more_elaborate_list_of_links_for_a_perm
}

def gen_links(user):
    # get_all_permissions also gets permissions for users groups
    perms = user.get_all_permissions()
    return sum((_LINKS[p](user) for p in perms if p in _LINKS), [])

おそらく他にも多くのアプローチがあります。

于 2009-10-10T01:00:28.420 に答える
5

同様の問題がありました。Django のグループはこれにはあまり適していませんが、押し込むことはできます。

私たちが行った方法は次のとおりです。

アクセス制御されたすべてのオブジェクトには、groups テーブルとの ManyToMany 関係があります。各グループは、特定の種類の権限 (「患者の基本情報を表示できる」、「患者の連絡先情報を編集できる」など) を定義するために使用されました。ユーザーは、アクセス許可を持つ必要があるグループに追加されます (この病院の患者のみを表示する例では、「valley-view-hospital」グループを作成できます)。

次に、レコードのリストをユーザーに表示するときに、2 つのグループの組み合わせに基づいてフィルター処理します。ユーザーは、特定のオブジェクトを表示するために、関連するすべてのグループ権限を持っている必要があります。

システムで必要な場合は、個別の ManyToMany の負のアクセス許可、または個別の読み取り/書き込みアクセス許可を保持できます。また、一連のメタ グループ (医師、看護師) を定義して、ルックアップ フィルターがアクセス許可の実際のサブセットを取得するようにすることもできます。

リンクバーの問題に関する限り、同じシステムを使用してプログラムでそれらを生成できます-ユーザーが表示または編集できるオブジェクトのクラスに基づいてフィルターし、get_absolute_url()タイプ関数を使用して (おそらくそれを呼び出しますget_index_url())、リンクを返しますオブジェクトの各クラスのインデックス。

これらはすべて非常に複雑であるため、最終的にはある程度のキャッシングを行いたいと思うことになるでしょうが、最適化を行う前にキャッシングを機能させてください。それは可能であり、言葉よりもコードの方が見苦しくありません。

于 2009-10-29T06:01:03.223 に答える
4

Django のロール ベースのパーミッションに関する新しい非常に興味深いプロジェクトがあります: http://bitbucket.org/nabucosound/django-rbac

于 2009-11-02T16:39:19.173 に答える
3

少し前に同様の問題がありました。あなたの状況では単純すぎるかもしれませんが、私たちのソリューションはうまくいきました。誰もが示唆しているように、私たちは django パーミッション システムを使用して、モデルとのユーザー インタラクションを制御しました。ただし、ユーザーをグループ化するだけでなく、GenericForeignKey を使用してオブジェクトをグループ化しました。

階層を開発できるように、それ自体にリンクするモデルを構築しました。

class Group( models.Model ):
    name = models.CharField( ... )
    parent = models.ForeignKey( 'self', blank=True, null=True)
    content_type = models.ForeignKey( ContentType )
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey( 'content_type', 'object_id' )
    ...

それを機能させるために、django User モデルのユーザー プロファイルとして機能するモデルも作成しました。含まれていたのは、上記の Group モデルにリンクされた ManyToManyField だけでした。これにより、必要に応じてユーザーに 0 個以上のグループへのアクセスを許可することができました。(ドキュメント)

class UserProfile( models.Model ):
    user = models.ForeignKey( User, unique=True )
    groups = models.ManyToManyField( Group )
    ...

これにより、両方の長所が得られ、すべてを django のパーミッション システムに押し込もうとする必要がなくなりました。私はこの基本的なセットアップを使用して、スポーツ コンテンツへのユーザーのアクセスを制御しています (リーグ全体にアクセスできるユーザー、1 つまたは 2 つの会議のみにアクセスできるユーザー、個々のチームにしかアクセスできないユーザーもいます)。おそらく、ニーズに合わせて十分に一般化されている可能性があります。

于 2009-10-30T04:23:28.163 に答える
1

この質問は2009 年 10 月に行われましたが、 2012 年 7 月になっても問題は解決していません。

優れた役割ベースのアプリを検索したところdjango-permission、最良の結果が見つかりました。

私が必要としていた 3 つの重要な機能は、Roles、 ビューDecorators、およびTemplatetagです。どうやらdjango-permissionsそれらのすべてを持っています。使用方法についてはドキュメントをお読みください。

唯一の欠点は、開発中であることです。

于 2012-07-04T08:22:00.417 に答える
1

ピノ ノワール ワインの専門家向けのサイトで、さまざまな基準に基づいてオブジェクトごとのアクセスを作成しました。インバウンドリンクに注目のワイナリーのドメイン名と一致するリファラー フィールドがある場合、ユーザーはそのワイナリーに関連するすべての記事、テイスティング ノートなどに展開される「ワイナリー トークン」を取得します。テイスティング イベントでの景品には「名前付きトークン」を使用し、サイトの特定の部分にアクセスできるようにしました。これを使用して、検索エンジン スパイダーに特定の種類の権限を付与し、これらの検索エンジンからのリンクがスパイダーと同じ権限を持つようにします (つまり、クローキング ゲームはありません)。

短いバージョンは、クラス (トークンを保持する TokenBuckets と呼びます) を作成し、各オブジェクト (詳細ページ、リスト ページなど) がユーザーの TokenBucket に特定のレベルのアクセスが許可されているかどうかを問い合わせることができます。

基本的に、これは奇妙な種類の ACL システムです。メカニズムを作成するのはそれほど難しくありませんでした。すべての魔法は、どのような状況でどのトークンがバケツに入るかを決定することにあります。

于 2009-10-30T04:37:54.373 に答える
1

実際のオブジェクトごとの ACL が必要ない場合は、Django パーミッション システムを使用できます。利用可能なすべての権限のリストを取得するには:

from django.contrib.auth.models import Permission
perms = Permission.objects.all()

他の認証および認可ソース用の APIがあるため、この権限テーブルに固執する必要はありません。

この認証モデル (RBAC) の観点から、ニーズに合わせてこの Django システムをハックするか、ACL のようなソリューションを考え出すことができます。

于 2009-10-10T02:04:00.867 に答える
1

django ユーザーロールを使用できます

https://github.com/dabapps/django-user-roles

于 2012-09-07T13:59:13.870 に答える
0

同様の問題に対して、ロールベースシステムを使用しました。基本的に、ユーザーはさまざまな役割を引き受ける権限を持っています。

ビュー関数が装飾されました:

def needs_capability(capability,redirect_to="/cms/"):
   def view_func_wrapper(view_func):
       def wrapped_view_func(request,*args,**kwargs):
           if not request.role._can(capability):
              return HttpResponseRedirect(redirect_to)
           return view_func(request,*args,**kwargs)
       return wrapped_view_func
   return view_func_wrapper

魔法の残りの部分はrequest.role、コンテキスト プロセッサ内で設定された属性内にあります。認証されたユーザーはロールを取得し、洗われていない大衆はダミーロールを取得しました。

テンプレート内では、情報へのアクセスがさらに制限されていました。

 {% if not request.role.can.view_all_products %}
          Lots of products, yeah!
 {% endif %}

私の意見では最もクリーンなソリューションではありませんが、期待どおりに機能しました。

于 2009-11-02T12:43:57.223 に答える