2010年1月20日水曜日

グループの入れ子を洗い出す

ドミノディレクトリのグループ文書では、メンバーの値としてユーザーのほか、グループを設定できます。

このように入れ子(ネストとも呼ばれます)になったグループを Domino は(アクセス認証の場合) 6 つのレベルまでたどってくれます。
※メール配信の場合は20のレベルまで
※8のAdministratorヘルプには「メール配信は5つのレベル」といった記載がいくつか残っています。R4.xの頃の名残りと思われ...orz

でもグループのメンバーにさらにグループが設定されていると、実際のアクセス権限がどうなっているのかがわかりづらいですよね。

そこで入れ子のグループを階層表示するアプリケーションを作ってみました。

選択したアプリケーションのACLからグループのエントリだけ取り出し、そのメンバーに設定されたグループを掘り出していきます。
そして掘り出したグループをビューで階層表示します。

下記は "グループの入れ子を調べる" エージェントの Lotus Script です。

(Options)
Option Base 1
(Declarations)
Dim ss As NotesSession
Dim vw As notesview
Type aclentrytype
Level As Integer
Name As String
End Type
Dim entrytype() As aclentrytype
Sub Initialize
Set ss = New NotesSession
Dim db As NotesDatabase

'アプリケーションのACLからグループのエントリだけ抽出する
Dim ws As New NotesUIWorkspace
Dim notesacl As NotesACL
Dim aclentry As NotesACLEntry
Dim numEntry As Integer

varDB = ws.Prompt( 13, "選択", "サーバー、アプリケーションを選択します" )
If Isempty( varDB ) Then Exit Sub
Set db = ss.GetDatabase( varDB( 0 ), varDB( 1 ) )
If db Is Nothing Then Exit Sub

If Not db.IsOpen Then flag = db.Open( "", "")
Set notesacl = db.ACL
Set aclentry = notesacl.GetFirstEntry
While Not (aclentry Is Nothing)
If aclentry.IsGroup Then
numEntry = numEntry + 1
Redim Preserve entrytype( numEntry )
entrytype( numEntry ).Level = aclentry.Level
entrytype( numEntry ).Name = aclentry.Name
End If
Set aclentry = notesacl.GetNextEntry( aclentry )
Wend

'レベルとグループ名を書き出す
Dim ndb As NotesDatabase
Dim parentdoc As NotesDocument
Dim i As Integer

Set ndb = ss.GetDatabase( db.Server, "names.nsf")
Set vw = ndb.GetView( "Groups" )
Set parentdoc = maketreedoc( db.Title, 99, Nothing )

For i = 1 To Ubound( entrytype )
Call grpmember( entrytype( i ).Name, i, 1, parentdoc )
Next
End Sub
Sub grpmember(grpname As String, idx As Integer, nest As Integer, pdoc As NotesDocument)
If nest > 6 Then Exit Sub

Dim nam As New NotesName( grpname )
Dim entry As NotesViewEntry
Set entry = vw.GetEntryByKey( nam.Abbreviated, True )
If entry Is Nothing Then Exit Sub

Dim treedoc As NotesDocument
Set treedoc = maketreedoc( grpname, entrytype( idx ).Level, pdoc )

Dim doc As NotesDocument
Set doc = entry.Document
Forall o In doc.GetItemValue( "Members" )
Call grpmember( Cstr( o ), idx, nest + 1, treedoc )
End Forall
End Sub
Function maketreedoc(title As String, idx As Integer, parent As NotesDocument) As NotesDocument
Set maketreedoc = New NotesDocument(ss.CurrentDatabase)
With maketreedoc
If Not (parent Is Nothing) Then Call .MakeResponse(parent)
.Form = "GroupTree"
.Group = title
.Level = idx
Call .Save(True, True)  
End With
End Function

上記エージェントを実行すると、アプリケーション内に文書を書き出します。

これらの文書は親子関係になっていて、以下のような3列のビューを作成すると階層構造で表示できます。

1列目の値として次の式を記述します。
@Replace(@Text(LEVEL); "0":"1":"2":"3":"4":"5":"6":"99"; "なし":"投稿者":"読者":"作成者":"編集者":"設計者":"管理者":"")

2列目は列のプロパティで「返答文書のみ表示」と「展開できる行に三角アイコンを表示する」にチェックを付けます。列の値は Group とします。

3列目は列のプロパティで「展開できる行に三角アイコンを表示する」にチェックを付けます。列の値は Group とします。
ビューのプロパティで「返答文書を階層表示する」にチェックを付けます。

以上でできあがりです。

ディレクトリアシスタントを使って別のアドレス帳にあるグループで認証させている環境では物足りないかもしれませんね。
なんとか対応できるようにいろいろ調べてみたいと思います。

それから、ビュー上で文書をダブルクリックしてもフォームが無いのでエラーが表示されますが、気にしないでください。

0 件のコメント:

コメントを投稿