/*
Copyright 1999-2011 (c) My-Channels
Copyright (c) 2012-2014 Software AG, Darmstadt, Germany and/or Software AG USA Inc., Reston, VA, USA, and/or its subsidiaries and/or its affiliates and/or their licensors.
Use, reproduction, transfer, publication or disclosure is prohibited except as specifically provided for in your License Agreement with Software AG.
*/
using System;
using System.Collections.Generic;
namespace com.pcbsys.nirvana.nAdminAPI.apps
{
using com.pcbsys.nirvana.nAdminAPI;
using com.pcbsys.nirvana.client;
///
/// * This application can be used to change permissions for a subject on a channel
///
public class modchanacl
{
///
/// * Private variables used in this application
///
public const string everyone = "everyone";
public const string everywhere = "everywhere";
private string realm = null;
private string name = null;
private string host = null;
private bool pattern = false;
private bool factory = false;
private bool canListAcl = false;
private bool canModifyAcl = false;
private bool fullPrivileges = false;
private bool canGetLastEid = false;
private bool canRead = false;
private bool canWrite = false;
private bool canPurge = false;
private bool canNamed = false;
private nSessionAttributes attr = null;
private string channelName = null;
private nRealmNode node = null;
private nACL acl = null;
private string[] changeArgs = null;
///
/// * Construct an instance of this class using the command line arguments passed
/// * when it is executed.
///
public modchanacl(string[] args)
{
try
{
changeArgs = args;
// set the parameters required for this operation
getOptions(changeArgs);
Console.WriteLine("Connecting to " + realm);
// construct the session attributes from the realm
attr = new nSessionAttributes(realm);
// get the root realm node from the realm admin
node = new nRealmNode(attr);
if (!node.isAuthorised())
{
Console.WriteLine("User not authorised on this node " + realm);
return;
}
// wait for the entire node namespace to be constructed if
// the operation is recursive
Console.Write("waiting for namepsace construction..... ");
node.waitForEntireNameSpace();
Console.WriteLine("finished");
// call the method to search from the root realm node
searchNode(node);
// close the realm node which will close all connections to child nodes
node.close();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
///
/// * set the permissions on the channel
///
public virtual void setChannel(nLeafNode p_leaf)
{
try
{
// get the acl for the channel node
acl = p_leaf.getACLs();
Console.WriteLine("Creating new entry for " + name + "@" + host);
// create a new acl entry with the name and host
nChannelACLEntry lookup = (nChannelACLEntry)acl.find(name + "@" + host);
// set the current permissions from the acl entry
setCurrent(lookup);
Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
Console.WriteLine("Current ACL Settings for " + p_leaf.Name + " on realm " + node.Name);
Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
dump(lookup);
// now set those which have changed
setChanges();
// change the entry in the acl
p_leaf.modACLEntry(changeACLEntry(lookup));
// set the node acl to the new acl list
Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
Console.WriteLine("New ACL Settings for " + p_leaf.Name + " on realm " + node.Name);
Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
dump(lookup);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
///
/// * search the enumeration of child nodes for other realms and channels
///
private void searchNodes(System.Collections.IEnumerator enum1)
{
while (enum1.MoveNext())
{
object obj = enum1.Current;
if (obj is nLeafNode)
{
nLeafNode leaf = (nLeafNode)obj;
string fullyQualifiedName = leaf.getAbsolutePath();
Console.WriteLine("Found channel " + fullyQualifiedName);
if (pattern)
{
if ((leaf.isChannel()) && (fullyQualifiedName.IndexOf(channelName) != -1))
{
// we have found a channel that matches the name specified, so set the permissions
setChannel(leaf);
return;
}
}
else if (factory)
{
if ((leaf.isChannel()) && (fullyQualifiedName.StartsWith(channelName)))
{
// we have found a channel that matches the name specified, so set the permissions
setChannel(leaf);
return;
}
}
else if ((leaf.isChannel()) && (fullyQualifiedName.Equals(channelName)))
{
// we have found a channel that matches the name specified, so set the permissions
setChannel(leaf);
return;
}
}
else if (obj is nRealmNode)
{
// we have found another realm node, so search this node for channels
searchNode((nRealmNode)obj);
}
else if (obj is nContainer)
{
nContainer cont = (nContainer)obj;
searchNodes(cont.getNodes());
}
}
}
///
/// * Search the children of the realm passed as a paremeter
///
private void searchNode(nRealmNode p_node)
{
try
{
Console.WriteLine("Found node " + p_node.Name);
searchNodes(p_node.getNodes());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
///
/// * Change an acl entry and set the permissions based on the permissions flags
///
public virtual nChannelACLEntry changeACLEntry(nChannelACLEntry aclEntry)
{
return this.setPermissions(aclEntry);
}
///
/// * If you construct an instance of this class from another class, you can set the name
/// * and host for the subject.
///
public virtual void setSubject(string p_name, string p_host)
{
name = p_name;
host = p_host;
}
///
/// * This will set the permissions flags to what the current acl settings are
/// *
/// * This is so that only those permissions that you wish to change are changed
///
public virtual void setCurrent(nChannelACLEntry entry)
{
canListAcl = entry.canList();
canModifyAcl = entry.canModify();
fullPrivileges = entry.hasFullPrivileges();
canGetLastEid = entry.canGetLastEID();
canRead = entry.canRead();
canWrite = entry.canWrite();
canPurge = entry.canPurge();
canNamed = entry.canUseNamedSubscription();
}
///
/// * Set the permissions on the channel acl entry
///
public virtual nChannelACLEntry setPermissions(nChannelACLEntry aclEntry)
{
aclEntry.setList(canListAcl);
aclEntry.setModify(canModifyAcl);
aclEntry.setFullPrivileges(fullPrivileges);
aclEntry.setGetLastEID(canGetLastEid);
aclEntry.setRead(canRead);
aclEntry.setWrite(canWrite);
aclEntry.setPurge(canPurge);
aclEntry.setUseNamedSubscription(canNamed);
return aclEntry;
}
///
/// * Output to system.out the permissions the current permissions on the acl entry
///
public virtual void dump(nChannelACLEntry entry)
{
Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
Console.WriteLine("List ACL : " + entry.canList());
Console.WriteLine("Set ACL : " + entry.canModify());
Console.WriteLine("Full Privileges : " + entry.hasFullPrivileges());
Console.WriteLine("Get Last EID : " + entry.canGetLastEID());
Console.WriteLine("Read channel : " + entry.canRead());
Console.WriteLine("Write to channel : " + entry.canWrite());
Console.WriteLine("Purge channel : " + entry.canPurge());
Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
}
///
/// * Output to system.out the permissions that will be set
///
public virtual void dump()
{
Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
Console.WriteLine("ACL will be set to.... ");
Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
Console.WriteLine("List ACL : " + canListAcl);
Console.WriteLine("Set ACL : " + canModifyAcl);
Console.WriteLine("Full Privileges : " + fullPrivileges);
Console.WriteLine("Get Last EID : " + canGetLastEid);
Console.WriteLine("Read channel : " + canRead);
Console.WriteLine("Write to channel : " + canWrite);
Console.WriteLine("Purge channel : " + canPurge);
Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
}
///
/// * Set the program variables and flags based on command line args
///
public virtual void getOptions(string[] args)
{
if (args == null || args.Length == 0)
{
Usage();
System.Environment.Exit(1);
}
realm = args[0];
if (realm == null)
{
Usage();
System.Environment.Exit(1);
}
name = args[1];
if (name == null)
{
Usage();
System.Environment.Exit(1);
}
else if (name.Equals(everyone))
{
name = "*";
}
host = args[2];
if (host == null)
{
Usage();
System.Environment.Exit(1);
}
else if (host.Equals(everywhere))
{
host = "*";
}
channelName = args[3];
if (channelName == null)
{
Usage();
System.Environment.Exit(1);
}
if (channelName.IndexOf("%") != -1)
{
if (channelName.StartsWith("%") && channelName.EndsWith("%"))
{
channelName = channelName.Substring(1);
channelName = channelName.Substring(0, channelName.Length - 1);
pattern = true;
}
if (channelName.EndsWith("%"))
{
channelName = channelName.Substring(0, channelName.Length - 1);
factory = true;
}
}
}
///
/// * This method will set the permissions flags, if the command line arguments have been
/// * passed for specific permissions.
/// *
/// * The command line arguments are + or - for either add or remove permission, followed
/// * by the actual permission flag
///
public virtual void setChanges()
{
for (int i = 0; i < changeArgs.Length; i++)
{
bool hasPermission;
if (changeArgs[i].StartsWith("+"))
{
hasPermission = true;
}
else if (changeArgs[i].StartsWith("-"))
{
hasPermission = false;
}
else
{
continue;
}
string permission = changeArgs[i].Substring(1);
Console.WriteLine("operation " + hasPermission + " for permission " + permission);
if (permission.Equals("list_acl"))
{
canListAcl = hasPermission;
}
else if (permission.Equals("modify_acl"))
{
canModifyAcl = hasPermission;
}
else if (permission.Equals("full"))
{
fullPrivileges = hasPermission;
}
else if (permission.Equals("read"))
{
canRead = hasPermission;
}
else if (permission.Equals("write"))
{
canWrite = hasPermission;
}
else if (permission.Equals("purge"))
{
canPurge = hasPermission;
}
else if (permission.Equals("named"))
{
canNamed = hasPermission;
}
else if (permission.Equals("all_perms"))
{
canListAcl = hasPermission;
canModifyAcl = hasPermission;
canGetLastEid = hasPermission;
canRead = hasPermission;
canWrite = hasPermission;
canPurge = hasPermission;
canNamed = hasPermission;
}
}
}
///
/// * Run this as a command line program passing the command line args.
/// *
/// * Or construct one of these classes from another class ensuring you have added :
/// *
/// * RNAME
/// * NAME
/// * HOST
/// * CHANNEL
/// *
/// * as system properties, and pass in a list of permissions in the constructor
/// *
///
static void Main(string[] args)
{
modchanacl setAcl = new modchanacl(args);
System.Environment.Exit(0);
}
///
/// * Prints the usage message for this class
///
private static void Usage()
{
Console.WriteLine("Usage ...\n");
Console.WriteLine("nchangechanacl [+/-list_acl] [+/-modify_acl] [+/-full] [+/-last_eid] [+/-read] [+/-write] [+/-purge] [+/-named] [+/-all_perms]\n");
Console.WriteLine(" \n");
Console.WriteLine(" - the rname of the server to connect to");
Console.WriteLine(" - User name parameter for the channel to change the ACL entry for");
Console.WriteLine(" - Host name parameter for the channel to change the ACL entry for");
Console.WriteLine(" - Channel name parameter for the channel to change the ACL entry for");
Console.WriteLine("\n[Optional Arguments] \n");
Console.WriteLine("[+/-] - Prepending + or - specifies whether to add or remove a permission");
Console.WriteLine("[list_acl] - Specifies that the list acl permission should be added/removed");
Console.WriteLine("[modify_acl] - Specifies that the modify acl permission should be added/removed");
Console.WriteLine("[full] - Specifies that the full permission should be added/removed");
Console.WriteLine("[last_eid] - Specifies that the get last EID permission should be added/removed");
Console.WriteLine("[read] - Specifies that the read permission should be added/removed");
Console.WriteLine("[write] - Specifies that the write permission should be added/removed");
Console.WriteLine("[purge] - Specifies that the purge permission should be added/removed");
Console.WriteLine("[named] - Specifies that the used named subscriber permission should be added/removed");
Console.WriteLine("[all_perms] - Specifies that all permissions should be added/removed");
}
}
}