# HG changeset patch # User Stephen Talley # Date 1335502346 14400 # Node ID a8e124b894b8fea0f6d806c43cecab54676f1f76 # Parent 0a2af47213539fdde2ec71a1009a43dc8a4b028f 7095663 A GUI needed for User Management 7158462 modify RAD usermgr module to support user/role cmds functionality diff -r 0a2af4721353 -r a8e124b894b8 usr/src/apis/usermgr.xml --- a/usr/src/apis/usermgr.xml Thu Apr 26 00:14:30 2012 -0400 +++ b/usr/src/apis/usermgr.xml Fri Apr 27 00:52:26 2012 -0400 @@ -23,26 +23,204 @@ --> + name="com.oracle.solaris.rad.usermgr"> - - + + describes a Solaris group + + + Fully describes a Solaris group, contains + group name, group id, group members. + + + Specifies the group name. + + + Specifies the Gid of the group. + + Specifies the members of the group. - - - - - - + + describes a Solaris user + + + Fully describes a Solaris user, contains + account, home directory and security attributes + associated with a user. See man passwd(4), + shadow(4), userattr(4) for more info on fields. + + + username for the account. + + + UID for the account. + + + GID for the account. + + + gecos info for the account. + + + homedirectory location for the account. + + + default shell for the account. + + + Number of inactivity days allowed for the account. + + + + Minimum number of days between password changes + for the account. + + + + Maximum cemunber of days the password is valid for + the account. + + + + Number of days before password expires the user + is warned. + + + + The date after which login will not be allowed for + the account. The date format is %y-%m-%d %H:%M:%S. + + + + Specifies whether the account is locked + after failed logins execeeds the allowable + limit. + + + + Specifies per-user always audit pre-selection + flags. + + + + Specifies per-user never-audit + pre-selection flags. + + + + specifies whether account is role or user. + + + specifies the default project for the account. + + + Specifies the max label at which the user can + operate. + + + + Specifies the min labelthat the user can login . + + + Specifies whether the account user role or user + password for role authentication. + + + + Specifies when the desktop session for the user gets + locked. + + + + Specifies the idle time before the idlecmd is + executed. + + + + Specifies the status of the account. + + + Specifies the roles that have been assigned to the + account. + + + + + Specifies the profiles that have been assigned to the + account. + + + + + Specifies the authorizations that have been assigned + to the account. + + + + + Specifies the default set of privileges assigned to + user at login. + + + + + Specifies the maximum set of privileges the user or + process started by the user can obtain. + + + + + Specifies the supplemental groups that have been + assigned to the account. + + + + + + + + Keeps track of all the fields that have been + changed in the user object. + + + Keeps track of all the fields that have been + changed in the user object. For every field + that has been changed in the User object the + respective changeField will be set to true. + + + + + + + + + + + + + + + + + + + + + + + + + User Manager api error types @@ -52,6 +230,12 @@ + + Name service scope types + + + + @@ -62,63 +246,488 @@ - + + Set of operations that can be performed on + users and roles. + + + + Lists users. + + + Lists the users present in the selected + scope based on the filter options. + - + + + + + READERROR - when unable to read user after + + + + + + Lists groups. + + + Lists the groups present in the selected + scope. + - + + + + + READERROR - when unable to read the groups database. + + + + + + Lists shells. + + + Lists the set of available shells + that can be set as default shell for users. + - + + + + + READERROR - when unable to read the default shells. + + + + - + + Lists user defaults. + + + Lists the default values for groups, basedir, + project, shell, skel, inactive, expire, + auths, profiles, roles, limitPriv, + defaultPriv, lockAfterRetries used for + creation of users and roles. + + + + + + READERROR - when unable to read default user properties. + + + + + + + + + Lists scopes. + + + Lists the set of name service repositories + that can be administered. + + + + + + + READERROR - when unable to read the name services that can be managed. + + + + + + + + + + Lists assigned roles. + + + Lists the roles assigned to a user. + + + + + + + READERROR - when unable to read user roles + + + + + + + + + Lists assigned profiles. + + + Lists the profiles assigned to a user. + + + + + + + READERROR - when unable to read user profiles. + + + + + + + + + Lists assigned authorizations. + + + Lists the authorizations assigned to a user. + + + + + + + READERROR - when unable to read user authorizations. + + + + + + + Lists default privileges. + + + Lists the default privileges assigned to a user. + + + + + + + READERROR - when unable to read user's default privileges. + + + + + + + + + Lists limit privileges. + + + Lists the limit privileges assigned to a user. + + + + + + + READERROR - when unable to read user's limit privileges. + + + + + + + + + Lists supplemental groups. + + + Lists the supplemental groups that the user + is a member of. + + + + + + + READERROR - when unable to read user's supplemental groups. + + + + + + + + + Lists Assigned Audit Classes. + + + Lists the audit classes that are assigned to + the user. + + + + + + + READERROR - when unable to read user's assigned audit classes. + + + + + + + + + Lists users PAM configuration files. + + + Lists the per-user PAM configuration files. + + + + + + + READERROR - when unable to read user specific PAM configuration files. + + + + + + + + + gets User information for a given username. + + + Gets the user information for a given username from + the name service repository based on the filter + options. + + + + + + + READERROR - when unable to read user + + + + + + Specifies the username for which the + account information is to be retrieved. + + + + + + Add user or role. + + + Adds a user or role to the selected name + service repository based on the filter + options. Applies the properties set in + the user object as the account, password, + security attributes. + Sets INVALIDDATA error when arguments are not valid. + Sets PASSERROR error when password update fails. + Sets READERROR error when unable to read user after + successful addition of new user. + Sets USEREXISTS error user already exists with same + username. + - - - + + + + + INVALIDDATA - when arguments are not valid. + + + INVALIDDATA - when arguments are not valid. + + + READERROR - when unable to read user after adding new user. + + + + + + user object which contains attributes of new + user account to be created. + + + + password to be set for the new user account. + + + + Modify user or role. + + + Modifies users or roles present in the selected + scope based on the filter options. + Applies the changed fields in the user object + to the user or role attributes. + Sets INVALIDDATA error when arguments are not valid. + Sets PASSERROR error when password update fails. + Sets READERROR error when unable to read user after + successful modification of user. + - - - + + + + + INVALIDDATA - when arguments are not valid. + + + INVALIDDATA - when arguments are not valid. + + + READERROR - when unable to read user after adding new user. + + + + + + user object which contains user attributes + to be modified. + + + + password to be set for the new user account. + + + + Indicates which fields have been modified + in the user object by the client. + + - - + + Delete user. + + + Deletes user or role based on username + present in the selected scope based on the + filter options. + Sets READERROR error on failure. + + + + + + READERROR - when unable to read user + + + + + + username of account that needs to be deleted. + + + + + + sets the name-service repository scope. + + + Sets the name-service repository scope. + All subsequent operations will use the specified scope. + + + Specifies the name-service scope to + be used for managing users. + + - - - - + + + Sets the filter options. + + + Sets the filter options which are used for + all the subsequent operations. The options + are user or role and search string. + + + Specifies if users or roles + will be managed. + + + + Specifies the string to match + against user or role names to be managed. + + - - - - + + Checks if System is Labeled. + + + Checks if the Trusted Extensions feature is + enabled on the system. + Returns true if successful and sets + Sets READERROR error on failure. + + + + + + + READERROR - when checking if Trusted Extensions is enabled fails. + + + + + Gets the user type. + + + Checks if the user is role or normal user. + Returns UserType set to role or normal user. + Sets READERROR error on failure. + - - + + + + + READERROR - when checking if Trusted Extensions is enabled fails. + + + + + + Specifies user name to check for user or role. + + diff -r 0a2af4721353 -r a8e124b894b8 usr/src/cmd/rad/mod/usermgr/Makefile --- a/usr/src/cmd/rad/mod/usermgr/Makefile Thu Apr 26 00:14:30 2012 -0400 +++ b/usr/src/cmd/rad/mod/usermgr/Makefile Fri Apr 27 00:52:26 2012 -0400 @@ -20,12 +20,12 @@ # # -# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. # include ../Makefile.env -LDLIBS += -lpam +LDLIBS += -lpam $(PROTO_LIB)/liboamuser.a -lsldap -ltsnet -ltsol -lproject -lnsl MOD_APIS=usermgr MOD_OBJS=mod_usermgr.o diff -r 0a2af4721353 -r a8e124b894b8 usr/src/cmd/rad/mod/usermgr/mod_usermgr.c --- a/usr/src/cmd/rad/mod/usermgr/mod_usermgr.c Thu Apr 26 00:14:30 2012 -0400 +++ b/usr/src/cmd/rad/mod/usermgr/mod_usermgr.c Fri Apr 27 00:52:26 2012 -0400 @@ -40,13 +40,18 @@ #include #include #include +#include #include #include "api_usermgr.h" +#include "nssec.h" #define USERADD "/usr/sbin/useradd" #define USERMOD "/usr/sbin/usermod" #define USERDEL "/usr/sbin/userdel" +#define ROLEADD "/usr/sbin/roleadd" +#define ROLEMOD "/usr/sbin/rolemod" +#define ROLEDEL "/usr/sbin/roledel" #define PWD_FILE "/etc/passwd" #define GRP_FILE "/etc/group" @@ -72,38 +77,109 @@ /* uid for nobody4 */ #define UID_NOBODY4 65534 +#define DEF_ATTEMPTS 3 +#define MAX_INT_LEN 11 +#define GROUPS "groups" +#define DFLT_PROJ_FLD "defaultProj" +#define LIMIT_PRIV_FLD "limitPriv" +#define DFLT_PRIV_FLD "defaultPriv" +#define MIN_LABEL_FLD "minLabel" +#define IDLE_CMD_FLD "idleCmd" +#define IDLE_TIME_FLD "idleTime" +#define LOCK_AFTER_RETRIES_FLD "lockAfterRetries" +#define ALWAYS_AUDIT_FLAGS_FLD "alwaysAuditFlags" +#define NEVER_AUDIT_FLAGS_FLD "neverAuditFlags" +#define ROLE_AUTH_FLD "roleAuth" + +#define check_rep(x) (x == NULL || (x->type != SEC_REP_FILES && \ + x-> type != SEC_REP_LDAP) || x->rops == NULL) \ + ? -1 : 0 +typedef struct ua_mod +{ + char *ua_key; + char *ua_fldname; +} ua_mod_t; + +static ua_mod_t ua_mods[] = { + USERATTR_AUTHS_KW, NULL, + USERATTR_PROFILES_KW, NULL, + USERATTR_ROLES_KW, NULL, + USERATTR_TYPE_KW, NULL, + USERATTR_DEFAULTPROJ_KW, DFLT_PROJ_FLD, + USERATTR_LIMPRIV_KW, LIMIT_PRIV_FLD, + USERATTR_DFLTPRIV_KW, DFLT_PRIV_FLD, + USERATTR_CLEARANCE, NULL, + USERATTR_MINLABEL, MIN_LABEL_FLD, + USERATTR_LOCK_AFTER_RETRIES_KW, LOCK_AFTER_RETRIES_FLD, + USERATTR_IDLECMD_KW, IDLE_CMD_FLD, + USERATTR_IDLETIME_KW, IDLE_TIME_FLD, + USERATTR_AUDIT_FLAGS_KW, ALWAYS_AUDIT_FLAGS_FLD, + USERATTR_ROLE_AUTH_KW, ROLE_AUTH_FLD, + GROUPS, +}; + +#define ua_num_keys (sizeof (ua_mods) / sizeof (ua_mod_t)) + +static char *scope = NSS_REP_FILES; +static char *type = USERATTR_TYPE_NORMAL_KW; +static sec_repository_t *scope_rep = NULL; static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; -/*ARGSUSED*/ static int verify_conv(int num_msg, struct pam_message **msg, struct pam_response **response, void *ptr) { char *passwd = ptr; + struct pam_message *m; + struct pam_response *r; + char *temp; + int k, i; + + if (num_msg <= 0) + return (PAM_CONV_ERR); /* * We assume the first (and only) request is to verify * the provided auth token. This is necessary until * PAM_SILENT is fixed by 6758592. */ - struct pam_response *r = malloc(sizeof (struct pam_response)); - if (r == NULL) + *response = (struct pam_response *)calloc(num_msg, + sizeof (struct pam_response)); + if (*response == NULL) return (PAM_BUF_ERR); - *response = r; - r->resp = strdup(passwd); - if (r->resp == NULL) { + k = num_msg; + m = *msg; + r = *response; + + temp = strdup(passwd); + if (temp == NULL) { + rad_log(RL_DEBUG, "strdup of passwd failed."); free(r); return (PAM_BUF_ERR); } - - r->resp_retcode = 0; + while (k--) { + r->resp = strdup(passwd); + if (r->resp == NULL) { + /* free responses */ + r = *response; + for (i = 0; i < num_msg; i++, r++) { + if (r->resp) + free(r->resp); + } + free(*response); + *response = NULL; + return (PAM_BUF_ERR); + } + m++; r++; + } return (PAM_SUCCESS); } static int update_user_passwd(const char *user, const char *passwd) { + pam_repository_t auth_rep = {scope, NULL, 0}; pam_handle_t *pamh; struct pam_conv pam_conv = { verify_conv, (void *)passwd }; int res; @@ -111,49 +187,176 @@ res = pam_start("other", user, &pam_conv, &pamh); if (res != PAM_SUCCESS) { pamh = NULL; - rad_log(RL_WARN, "Failed to initialize PAM: %s\n", + rad_log(RL_ERROR, "Failed to initialize PAM: %s", pam_strerror(pamh, res)); return (res == PAM_PERM_DENIED ? PAM_EPERM : PAM_ERROR); } + if ((res = pam_set_item(pamh, PAM_REPOSITORY, + (void *)&auth_rep)) != PAM_SUCCESS) { + rad_log(RL_ERROR, "Failed to set repository: %s", + pam_strerror(pamh, res)); + (void) pam_end(pamh, res); + return (res == PAM_PERM_DENIED ? PAM_EPERM : PAM_ERROR); + } + res = pam_chauthtok(pamh, PAM_SILENT|PAM_NO_AUTHTOK_CHECK); if (res != PAM_SUCCESS) { - rad_log(RL_WARN, "Failed to change auth token: %s\n", + rad_log(RL_ERROR, "Failed to change auth token: %s", pam_strerror(pamh, res)); - pam_end(pamh, res); + (void) pam_end(pamh, res); return (res == PAM_PERM_DENIED ? PAM_EPERM : PAM_ERROR); } + (void) pam_end(pamh, res); + return (res); +} - pam_end(pamh, PAM_SUCCESS); +static char *list_to_string(data_t *list) +{ + int size, index; + int item_len = 0; + char *retstr = NULL; + size = array_size(list); + if (size == 0) + return (retstr); + for (index = 0; index < size; index++) { + const char *fld_str = data_to_string(array_get(list, index)); + if (fld_str != NULL && fld_str[0] != '\0') { + item_len += strlen(fld_str) + 1; + } + } + if (item_len <= 0) + return (retstr); + retstr = malloc(item_len + 1); + if (retstr == NULL) { + rad_log(RL_ERROR, "Error allocating list items."); + return (retstr); + } + *retstr = '\0'; + for (index = 0; index < size; index++) { + const char *fld_str = data_to_string(array_get(list, index)); + if (fld_str != NULL && fld_str[0] != '\0') { + if (index == 0) + *retstr = '\0'; + (void) strncat(retstr, fld_str, item_len); + if (index < (size - 1)) + (void) strncat(retstr, ",", item_len); + } + } + return (retstr); +} - return (0); +static void add_kv_field(const char *argv[], int *argc, data_t **input, +boolean_t new_user, char *kw, char *chgfield) +{ + data_t *field; + data_t *fieldChanged; + data_t *user = input[0]; + field = struct_get(user, kw); + fieldChanged = (new_user ? NULL : struct_get(input[2], chgfield)); + if ((fieldChanged != NULL && data_to_boolean(fieldChanged) == B_TRUE) || + field != NULL) { + int len; + char *qt_str; + if (strcmp(kw, GROUPS) == 0) { + qt_str = list_to_string(field); + if (qt_str != NULL && + qt_str[0] != '\0') { + argv[(*argc)++] = strdup("-G"); + argv[(*argc)++] = qt_str; + } else if (!new_user) { + argv[(*argc)++] = strdup("-G"); + argv[(*argc)++] = strdup(""); + } + } else { + if (field != NULL) { + if (strcmp(kw, USERATTR_AUTHS_KW) == 0 || + strcmp(kw, USERATTR_ROLES_KW) == 0 || + strcmp(kw, USERATTR_PROFILES_KW) == 0) { + char *fld_str = list_to_string(field); + if (fld_str != NULL && + strlen(fld_str) > 0) { + argv[(*argc)++] = strdup("-K"); + len = strlen(fld_str) + + strlen(kw) + 2; + qt_str = malloc(len); + if (qt_str == NULL) { + rad_log(RL_ERROR, + "Error allocating" + " memory."); + return; + } + (void) snprintf(qt_str, len, + "%s=%s", kw, fld_str); + argv[(*argc)++] = qt_str; + } else if (!new_user) { + len = strlen(kw) + 4; + argv[(*argc)++] = strdup("-K"); + qt_str = malloc(len); + (void) snprintf(qt_str, len, + "%s=%s", kw, ""); + argv[(*argc)++] = qt_str; + } + } + } else if (!new_user) { + len = strlen(kw) + 4; + argv[(*argc)++] = strdup("-K"); + qt_str = malloc(len); + (void) snprintf(qt_str, len, "%s=%s", kw, ""); + argv[(*argc)++] = qt_str; + } + } + } } static int build_args_array(const char *argv[], int *argc, boolean_t new_user, char *uids, - char *gids, data_t **input) +char *gids, data_t **input) { data_t *user = input[0]; data_t *field; + data_t *fieldChanged; int count = 0; - argv[count++] = new_user ? USERADD : USERMOD; + if (strcmp(type, USERATTR_TYPE_ROLE) == 0) { + argv[count++] = strdup(new_user ? ROLEADD : ROLEMOD); + } else { + argv[count++] = strdup(new_user ? USERADD : USERMOD); + } + argv[count++] = strdup("-S"); + argv[count++] = strdup(scope); + fieldChanged = (new_user ? NULL : struct_get(input[2], + "homedirChanged")); + field = struct_get(user, "homeDirectory"); if (new_user) { - field = struct_get(user, "homeDirectory"); - if (field) { - argv[count++] = "-d"; - argv[count++] = data_to_string(field); + if (field != NULL) { + argv[count++] = strdup("-d"); + argv[count++] = strdup(data_to_string(field)); } else { - argv[count++] = "-b"; - argv[count++] = BASE_DIR; + argv[count++] = strdup("-b"); + argv[count++] = strdup(BASE_DIR); } - argv[count++] = "-m"; + argv[count++] = strdup("-m"); + } else { + if ((fieldChanged != NULL && + data_to_boolean(fieldChanged) == B_TRUE && + field != NULL) || field != NULL) { + argv[count++] = strdup("-d"); + argv[count++] = strdup(data_to_string(field)); + } } + fieldChanged = (new_user ? NULL : struct_get(input[2], "descChanged")); field = struct_get(user, "description"); - if (field) { - argv[count++] = "-c"; - argv[count++] = data_to_string(field); + if ((fieldChanged != NULL && data_to_boolean(fieldChanged) == B_TRUE && + field != NULL) || field != NULL) { + argv[count++] = strdup("-c"); + argv[count++] = strdup(data_to_string(field)); + if (strchr(argv[count-1], ':') + != NULL) { + rad_log(RL_ERROR, "Error in description field."); + return (-1); + } } /* set uid only if we are adding a user */ @@ -164,10 +367,10 @@ if ((uid > 99) && (uid <= MAXUID)) { (void) snprintf(uids, GUID_MAX, "%d", uid); - argv[count++] = "-u"; - argv[count++] = uids; + argv[count++] = strdup("-u"); + argv[count++] = strdup(uids); } else if (uid != 0) { - rad_log(RL_WARN, "invalid uid found %d", uid); + rad_log(RL_ERROR, "Invalid uid found %d", uid); return (1); } } @@ -175,21 +378,36 @@ /* append gid */ field = struct_get(user, "groupID"); - if (field) { + fieldChanged = (new_user ? NULL : struct_get(input[2], "gidChanged")); + if ((fieldChanged != NULL && data_to_boolean(fieldChanged) == B_TRUE && + field != NULL) || field != NULL) { gid_t gid = data_to_uinteger(field); if (gid > 0) { (void) snprintf(gids, GUID_MAX, "%d", gid); - argv[count++] = "-g"; - argv[count++] = gids; + argv[count++] = strdup("-g"); + argv[count++] = strdup(gids); } } field = struct_get(user, "defaultShell"); - if (field) { - argv[count++] = "-s"; - argv[count++] = data_to_string(field); + fieldChanged = (new_user ? NULL : struct_get(input[2], + "defShellChanged")); + if ((fieldChanged != NULL && data_to_boolean(fieldChanged) == B_TRUE && + field != NULL) || field != NULL) { + argv[count++] = strdup("-s"); + argv[count++] = strdup(data_to_string(field)); } + add_kv_field(argv, &count, input, new_user, + USERATTR_PROFILES_KW, "profilesChanged"); + if (strcmp(type, USERATTR_TYPE_ROLE)) { + add_kv_field(argv, &count, input, new_user, + USERATTR_ROLES_KW, "rolesChanged"); + } + add_kv_field(argv, &count, input, new_user, + USERATTR_AUTHS_KW, "authsChanged"); + add_kv_field(argv, &count, input, new_user, + GROUPS, "groupsChanged"); argv[count] = NULL; *argc = count; @@ -201,9 +419,22 @@ static data_t * make_user(const struct passwd *pwe) { + if (pwe == NULL) { + rad_log(RL_ERROR, "Invalid passwd struct"); + return (NULL); + } data_t *user = data_new_struct(&t__User); + if (user == NULL) { + rad_log(RL_ERROR, "User object is null."); + return (NULL); + } data_t *username = data_new_string(pwe->pw_name, lt_copy); + if (username == NULL) { + rad_log(RL_ERROR, "Username is null."); + return (NULL); + } + data_t *user_id = data_new_uinteger(pwe->pw_uid); data_t *group_id = data_new_uinteger(pwe->pw_gid); data_t *desc = data_new_string( @@ -211,34 +442,245 @@ data_t *home_dir = data_new_string(pwe->pw_dir, lt_copy); data_t *shell = data_new_string(pwe->pw_shell, lt_copy); + data_t *inactive = data_new_integer(-1); + data_t *min = data_new_integer(-1); + data_t *max = data_new_integer(-1); + data_t *warn = data_new_integer(-1); + data_t *accountStatus = data_new_string("UNKNOWN", lt_const); - if ((user == NULL) || (username == NULL) || (user_id == NULL) || - (group_id == NULL) || (desc == NULL) || (home_dir == NULL) || - (shell == NULL)) { - data_free(user); - data_free(username); - data_free(user_id); - data_free(group_id); - data_free(desc); - data_free(home_dir); - data_free(shell); - return (NULL); + struct_set(user, "username", username); + struct_set(user, "userID", user_id); + struct_set(user, "groupID", group_id); + struct_set(user, "description", desc); + struct_set(user, "homeDirectory", home_dir); + struct_set(user, "defaultShell", shell); + struct_set(user, "inactive", inactive); + struct_set(user, "min", min); + struct_set(user, "max", max); + struct_set(user, "warn", warn); + struct_set(user, "accountStatus", accountStatus); + + return (data_purify_deep(user)); +} + +static data_t * +make_attrs_array(const nss_attr_t *attrs_lst) +{ + data_t *attr_arr = NULL; + data_t *attr; + int i; + + if (attrs_lst != NULL && attrs_lst->attr_cnt > 0) { + attr_arr = data_new_array(&t_array_string, + attrs_lst->attr_cnt); + if (attr_arr == NULL) { + rad_log(RL_ERROR, + "Error allocating attr array"); + return (NULL); + } + for (i = 0; i < attrs_lst->attr_cnt; i++) { + attr = data_new_string(attrs_lst->attrvals[i], + lt_copy); + if (attr == NULL) { + rad_log(RL_ERROR, + "Error allocating attr"); + data_free(attr_arr); + return (NULL); + } + (void) array_add(attr_arr, attr); + } } else { - struct_set(user, "username", username); - struct_set(user, "userID", user_id); - struct_set(user, "groupID", group_id); - struct_set(user, "description", desc); - struct_set(user, "homeDirectory", home_dir); - struct_set(user, "defaultShell", shell); + attr_arr = data_new_array(&t_array_string, 1); + if (attr_arr == NULL) { + rad_log(RL_ERROR, + "Error allocating attr array"); + return (NULL); + } + attr = data_new_string("", lt_copy); + if (attr == NULL) { + rad_log(RL_ERROR, + "Error allocating attr"); + data_free(attr_arr); + return (NULL); + } + (void) array_add(attr_arr, attr); } + + return (attr_arr); +} + + +static data_t * +load_userattr(userattr_t *ua, data_t *user) +{ + char *attrs_lst; + data_t *attr, *attrs_arr; + int i, rc = 0; + + for (i = 0; i < ua_num_keys; i++) { + if (strcmp(ua_mods[i].ua_key, GROUPS) == 0) { + rc = _nss_get_userattrs(ua->name, ua_mods[i].ua_key, + scope_rep, &attrs_lst); + } else { + char *kv_attr; + attrs_lst = NULL; + if ((kv_attr = kva_match(ua->attr, + (char *)ua_mods[i].ua_key)) != NULL) { + attrs_lst = strdup(kv_attr); + rc = 0; + } + } + if (rc == 0) { + if (attrs_lst != NULL) { + char *fldname; + if (strcmp(ua_mods[i].ua_key, + USERATTR_AUTHS_KW) == 0 || + strcmp(ua_mods[i].ua_key, + USERATTR_PROFILES_KW) == 0 || + strcmp(ua_mods[i].ua_key, + USERATTR_ROLES_KW) == 0 || + strcmp(ua_mods[i].ua_key, + USERATTR_LIMPRIV_KW) == 0 || + strcmp(ua_mods[i].ua_key, + USERATTR_DFLTPRIV_KW) == 0 || + strcmp(ua_mods[i].ua_key, GROUPS) == 0) { + char *vals; + char *token, *lasts; + + vals = attrs_lst; + attrs_arr = data_new_array( + &t_array_string, 1); + if (attrs_arr == NULL) { + rad_log(RL_ERROR, + "Error allocating " + "attr array"); + return (NULL); + } + for (token = strtok_r(vals, ",", + &lasts); token != NULL; + token = strtok_r(NULL, ",", + &lasts)) { + attr = data_new_string(token, + lt_copy); + if (attr == NULL) { + rad_log(RL_ERROR, + "Error allocating" + " attr"); + data_free(attrs_arr); + return (NULL); + } else { + (void) array_add( + attrs_arr, attr); + } + } + fldname = (ua_mods[i].ua_fldname + == NULL) ? ua_mods[i].ua_key : + ua_mods[i].ua_fldname; + struct_set(user, fldname, + attrs_arr); + free(attrs_lst); + } else { + attrs_arr = data_new_string( + attrs_lst, lt_copy); + /* + * Need to fix audit flags + */ + if (strcmp(ua_mods[i].ua_key, + USERATTR_AUDIT_FLAGS_KW) + == 0) { + struct_set(user, + ALWAYS_AUDIT_FLAGS_FLD, + attrs_arr); + } else { + fldname = (ua_mods[i].ua_fldname + == NULL) ? ua_mods[i].ua_key + : ua_mods[i].ua_fldname; + struct_set(user, + fldname, + attrs_arr); + } + free(attrs_lst); + } + } + } + } + return (user); } +/* converts expire field in string format to date */ +static char * +convtodate(int expire) +{ + time_t tminsec; + struct tm ts; + char buf[80]; + + if (expire == -1) + return (NULL); + tminsec = expire * DAY; + ts = *localtime(&tminsec); + (void) strftime(buf, sizeof (buf), "%y-%m-%d %H:%M:%S", &ts); + return (strdup(buf)); +} + +static data_t * +load_shadow(const struct spwd *sp, data_t *user) +{ + char *exp_val, *status; + if (sp == NULL || user == NULL) { + rad_log(RL_ERROR, "Invalid arg in update_shadowinfo."); + return (NULL); + } + if (sp->sp_expire == -1) + exp_val = ""; + else + exp_val = convtodate(sp->sp_expire); + if (exp_val == NULL) { + rad_log(RL_ERROR, "Error gettting shadow expire."); + return (NULL); + } + + data_t *expire = data_new_string(exp_val, lt_copy); + data_t *inactive = data_new_integer(sp->sp_inact); + data_t *min = data_new_integer(sp->sp_min); + data_t *max = data_new_integer(sp->sp_max); + data_t *warn = data_new_integer(sp->sp_warn); + data_t *accountStatus; + + if (sp->sp_pwdp == NULL || *sp->sp_pwdp == '\0') { + status = "NOPASSWORD"; + } else if (strncmp(sp->sp_pwdp, LOCKSTRING, + sizeof (LOCKSTRING)-1) == 0) { + status = "LOCKED"; + } else if (strncmp(sp->sp_pwdp, NOLOGINSTRING, + sizeof (NOLOGINSTRING)-1) == 0) { + status = "NOLOGIN"; + } else if (strncmp(sp->sp_pwdp, UNINITPW, sizeof (UNINITPW)-1) == 0) { + status = "NOTACTIVATED"; + } else if ((strlen(sp->sp_pwdp) == 13 && sp->sp_pwdp[0] != '$') || + sp->sp_pwdp[0] == '$') { + status = "PASSWORD"; + } else { + status = "UNKNOWN"; + } + accountStatus = data_new_string(status, lt_const); + + struct_set(user, "expire", expire); + struct_set(user, "inactive", inactive); + struct_set(user, "min", min); + struct_set(user, "max", max); + struct_set(user, "warn", warn); + struct_set(user, "accountStatus", accountStatus); + return (data_purify_deep(user)); +} + + static data_t * make_error(data_t *e) { data_t *error = data_new_struct(&t__UserMgrError); struct_set(error, "errorCode", e); - return (data_purify(error)); + return (data_purify_deep(error)); } static boolean_t @@ -279,17 +721,33 @@ { int res = UT_NORMAL; - userattr_t *attr = getusernam(username); - if (attr) { - char *type = kva_match(attr->attr, USERATTR_TYPE_KW); + userattr_t *puattr = NULL; + nss_XbyY_buf_t *buf = NULL; + + if (get_repository_handle(scope, &scope_rep) != SEC_REP_SUCCESS) { + rad_log(RL_ERROR, + "Error getting handle to repository"); + return (-1); + } - if ((type) && + if (check_rep(scope_rep) != 0 || username == NULL) + return (-1); + + + init_nss_buffer(SEC_REP_DB_USERATTR, &buf); + if ((scope_rep->rops->get_usernam((char *)username, + &puattr, buf)) == SEC_REP_SUCCESS) { + char *type = kva_match(puattr->attr, USERATTR_TYPE_KW); + + if ((type != NULL) && ((strcmp(type, USERATTR_TYPE_ADMIN_KW) == 0) || - (strcmp(type, USERATTR_TYPE_NONADMIN_KW) == 0))) { + (strcmp(type, USERATTR_TYPE_ROLE) == 0))) { res = UT_ROLE; } + free(puattr); } - enduserattr(); + free_nss_buffer(&buf); + free_repository_handle(scope_rep); return (res); } @@ -298,7 +756,7 @@ is_local_user(boolean_t *luser, const char *username) { FILE *fp = fopen(PWD_FILE, "r"); if (fp == NULL) { - rad_log(RL_DEBUG, "unable to open %s", PWD_FILE); + rad_log(RL_ERROR, "unable to open %s", PWD_FILE); return (1); } @@ -318,46 +776,28 @@ static int is_last_admin(boolean_t *admin, const char *username) { - userattr_t *attr = getusernam(username); - if ((attr == NULL) || - !kva_vsearch(attr->attr, USERATTR_ROLES_KW, ROOT)) { + userattr_t *puattr = NULL; + nss_XbyY_buf_t *buf = NULL; + boolean_t last_admin = B_TRUE; + boolean_t local_user; + int r; + + if (check_rep(scope_rep) != 0 || username == NULL) + return (-1); + init_nss_buffer(SEC_REP_DB_USERATTR, &buf); + (void) scope_rep->rops->get_usernam((char *)username, &puattr, buf); + if ((puattr == NULL) || + kva_vsearch(puattr->attr, USERATTR_ROLES_KW, ROOT) == NULL) { *admin = B_FALSE; - - free_userattr(attr); - enduserattr(); - + free_userattr(puattr); + free_nss_buffer(&buf); return (0); } - - FILE *fp = fopen(USERATTR_FILENAME, "r"); - if (fp == NULL) { - rad_log(RL_DEBUG, "unable to open %s", USERATTR_FILENAME); + r = is_local_user(&local_user, puattr->name); + if (r != 0) return (1); - } - - boolean_t last_admin = B_TRUE; - while (((attr = fgetuserattr(fp)) != NULL) && (last_admin)) { - if (strcmp(username, attr->name) != 0) { - if (kva_vsearch(attr->attr, USERATTR_ROLES_KW, ROOT)) { - /* verify that attr->name is a local user */ - boolean_t local_user; - int r = is_local_user(&local_user, attr->name); - if (r != 0) { - free_userattr(attr); - enduserattr(); - (void) fclose(fp); - return (1); - } - if (local_user) - last_admin = B_FALSE; - } - } - } - - free_userattr(attr); - enduserattr(); - (void) fclose(fp); - + if (local_user) + last_admin = B_FALSE; *admin = last_admin; return (0); } @@ -366,13 +806,74 @@ get_user(const char *username) { data_t *user; - struct passwd *entry = getpwnam(username); - if (entry) { - user = make_user(entry); - endpwent(); + struct spwd *spwd = NULL; + userattr_t *uattr = NULL; + struct passwd *entry = NULL; + nss_XbyY_buf_t *buf = NULL; + int rc; + + init_nss_buffer(SEC_REP_DB_PASSWD, &buf); + rc = scope_rep->rops->get_pwnam((char *)username, + &entry, buf); + if (entry != NULL) { + if ((user = make_user(entry)) == NULL) { + rad_log(RL_ERROR, + "Unable to create user obj."); + free(entry); + free_nss_buffer(&buf); + return (NULL); + } + free(entry); + } else { + rad_log(RL_DEBUG, + "%s not found. rc = %d", + username, rc); + free_nss_buffer(&buf); + return (NULL); } - - return (user); + free_nss_buffer(&buf); + init_nss_buffer(SEC_REP_DB_USERATTR, &buf); + rc = scope_rep->rops->get_usernam((char *)username, &uattr, buf); + if (uattr != NULL) { + rad_log(RL_DEBUG, "Loading userattr" + " info for user %s", username); + char *uatype = kva_match(uattr->attr, USERATTR_TYPE_KW); + if ((type != NULL && uatype != NULL && + strcmp(uatype, type)) || + (type != NULL && uatype == NULL && + strcmp(type, USERATTR_TYPE_ROLE) == 0)) { + free(uattr); + free_nss_buffer(&buf); + return (NULL); + } + if ((user = load_userattr(uattr, user)) == NULL) { + rad_log(RL_ERROR, "Error loading userattr" + " info for user %s", username); + free(uattr); + free_nss_buffer(&buf); + return (NULL); + } + free(uattr); + } else if (uattr == NULL && + strcmp(type, USERATTR_TYPE_ROLE) == 0) { + free_nss_buffer(&buf); + return (NULL); + } + free_nss_buffer(&buf); + init_nss_buffer(SEC_REP_DB_SHADOW, &buf); + rc = scope_rep->rops->get_spnam((char *)username, &spwd, buf); + if (spwd != NULL) { + if ((user = load_shadow(spwd, user)) == NULL) { + rad_log(RL_ERROR, "Error filling shadow info" + "for user %s", username); + free(spwd); + free_nss_buffer(&buf); + return (NULL); + } + free(spwd); + } + free_nss_buffer(&buf); + return (data_purify_deep(user)); } /*ARGSUSED*/ @@ -381,40 +882,55 @@ data_t **rtnval, data_t **error) { conerr_t rtn_code = ce_ok; + data_t *users; + nss_XbyY_buf_t *buf = NULL; + struct passwd *entry; + int count = 0; - data_t *users = data_new_array(&t_array__User, 100); - FILE *fp = fopen(PWD_FILE, "r"); - if (fp) { - struct passwd *entry; - while ((entry = fgetpwent(fp)) != NULL) { - /* - * prune system users including noaccess, - * nobody, nobody4 - */ - if ((entry->pw_uid > 99) && - (entry->pw_uid != UID_NOACCESS) && - (entry->pw_uid != UID_NOBODY) && - (entry->pw_uid != UID_NOBODY4)) { + rad_log(RL_DEBUG, "In readUsers. scope:%s, type=%s", scope, type); + if (get_repository_handle(scope, &scope_rep) != SEC_REP_SUCCESS) { + rad_log(RL_ERROR, "Error getting handle to repository"); + return (-1); + } + if (check_rep(scope_rep) != 0) { + free_repository_handle(scope_rep); + *rtnval = NULL; + *error = make_error(&e__UserMgrErrorType_READERROR); + return (ce_object); + } + users = data_new_array(&t_array__User, 100); + init_nss_buffer(SEC_REP_DB_PASSWD, &buf); + scope_rep->rops->set_pwent(); + while ((entry = scope_rep->rops->get_pwent(buf)) != NULL) { + /* + * prune system users including noaccess, + * nobody, nobody4 + */ + if (((entry->pw_uid > 99) && + (entry->pw_uid != UID_NOACCESS) && + (entry->pw_uid != UID_NOBODY) && + (entry->pw_uid != UID_NOBODY4)) || + (entry->pw_uid == 0)) { + data_t *user = get_user(entry->pw_name); + if (user != NULL) { + (void) array_add(users, user); + count++; + } else { + rad_log(RL_DEBUG, "No users found"); + } - data_t *user = make_user(entry); - if (user != NULL) - (void) array_add(users, user); - } } - - endpwent(); - (void) fclose(fp); } - - if (data_verify(users, users->d_type, B_FALSE)) { + scope_rep->rops->end_pwent(); + free_nss_buffer(&buf); + if (data_verify(users, users->d_type, B_TRUE) == B_TRUE) { *rtnval = users; } else { data_free(users); - *rtnval = NULL; *error = make_error(&e__UserMgrErrorType_READERROR); rtn_code = ce_object; } - + free_repository_handle(scope_rep); return (rtn_code); } @@ -425,11 +941,19 @@ { conerr_t rtn_code = ce_ok; + rad_log(RL_DEBUG, "In readGroups. scope:%s", scope); + if (get_repository_handle(scope, &scope_rep) != SEC_REP_SUCCESS) { + rad_log(RL_ERROR, "Error getting handle to repository"); + return (-1); + } data_t *groups = data_new_array(&t_array__Group, 50); FILE *fp = fopen(GRP_FILE, "r"); if (fp) { struct group *entry; - while ((entry = fgetgrent(fp)) != NULL) { + nss_XbyY_buf_t *buf = NULL; + init_nss_buffer(SEC_REP_DB_GROUP, &buf); + scope_rep->rops->set_group(); + while ((entry = scope_rep->rops->get_group(buf)) != NULL) { data_t *group = data_new_struct(&t__Group); struct_set(group, "groupName", @@ -448,9 +972,8 @@ struct_set(group, "groupMembers", members); (void) array_add(groups, group); } - - endgrent(); - (void) fclose(fp); + scope_rep->rops->end_group(); + free_nss_buffer(&buf); } if (data_verify(groups, groups->d_type, B_TRUE)) { @@ -462,6 +985,7 @@ rtn_code = ce_object; } + free_repository_handle(scope_rep); return (rtn_code); } @@ -514,28 +1038,36 @@ if (args[1] != NULL) password = data_to_secret(args[1]); + rad_log(RL_DEBUG, "In addUser.scope : %s", scope); + if (get_repository_handle(scope, &scope_rep) != SEC_REP_SUCCESS) { + rad_log(RL_ERROR, + "Error getting handle to repository"); + *error = make_error( + &e__UserMgrErrorType_READERROR); + return (ce_object); + } const char *argv[ARG_COUNT]; char uids[GUID_MAX]; char gids[GUID_MAX]; int argc; if (build_args_array(argv, &argc, B_TRUE, uids, gids, args) != 0) { - rad_log(RL_DEBUG, "invalid arguments found."); + rad_log(RL_DEBUG, "Invalid arguments found."); *error = make_error(&e__UserMgrErrorType_INVALIDDATA); return (ce_object); } - argv[argc++] = username; + argv[argc++] = strdup(username); argv[argc] = NULL; assert(argc < ARG_COUNT); int estatus; int fstatus = rad_forkexec_wait(NULL, argv, &estatus); + if ((fstatus == 0) && (estatus == 0)) { + rad_log(RL_DEBUG, + "%s created successfully", username); - if ((fstatus == 0) && (estatus == 0)) { - rad_log(RL_DEBUG, "%s created successfully.", username); - - if (password) { + if (password != NULL && password[0] != '\0') { int res = update_user_passwd(username, password); if (res != 0) { switch (res) { @@ -543,28 +1075,48 @@ rtn_code = ce_priv; break; default: + rad_log(RL_ERROR, + "Error from pam"); *error = make_error( &e__UserMgrErrorType_PASSERROR); rtn_code = ce_object; } + *rtnval = NULL; + return (rtn_code); } } data_t *new_user; + free_repository_handle(scope_rep); + (void) sleep(2); + if (get_repository_handle(scope, &scope_rep) + != SEC_REP_SUCCESS) { + rad_log(RL_ERROR, + "Error getting handle to" + " repository"); + *error = make_error( + &e__UserMgrErrorType_READERROR); + return (ce_object); + } if ((new_user = get_user(username)) != NULL) { - *rtnval = new_user; + if ((*rtnval = data_purify_deep(new_user)) == NULL) { + *error = make_error( + &e__UserMgrErrorType_READERROR); + return (ce_object); + } return (ce_ok); } else { - rad_log(RL_DEBUG, "unable to read newly created user"); + rad_log(RL_ERROR, + "Unable to read newly created user"); *error = make_error(&e__UserMgrErrorType_PASSERROR); return (ce_object); } } else if (fstatus != 0) { - rad_log(RL_DEBUG, "unable to fork child process"); + rad_log(RL_ERROR, "Unable to fork child process"); *error = make_error(&e__UserMgrErrorType_READERROR); rtn_code = ce_object; } else { - rad_log(RL_WARN, "error creating user %s", username); + rad_log(RL_ERROR, "Error creating user %s", username); switch (estatus) { case EX_NO_PERM: @@ -584,6 +1136,7 @@ rtn_code = ce_object; } } + free_repository_handle(scope_rep); return (rtn_code); } @@ -606,14 +1159,20 @@ char gids[GUID_MAX]; int argc; + rad_log(RL_DEBUG, "In modifyUser. scope:%s", scope); + if (get_repository_handle(scope, &scope_rep) != SEC_REP_SUCCESS) { + rad_log(RL_ERROR, + "Error getting handle to repository"); + return (-1); + } if (build_args_array(argv, &argc, B_FALSE, uids, gids, args) != 0) { - rad_log(RL_WARN, "invalid arguments"); + rad_log(RL_ERROR, + "Invalid arguments"); *error = make_error(&e__UserMgrErrorType_INVALIDDATA); return (ce_object); } - if (argc > 2) { - argv[argc++] = username; + argv[argc++] = strdup(username); argv[argc] = NULL; assert(argc < ARG_COUNT); @@ -622,20 +1181,32 @@ if ((fstatus == 0) && (estatus == 0)) { data_t *modified_user; + free_repository_handle(scope_rep); + (void) sleep(2); + if (get_repository_handle(scope, &scope_rep) + != SEC_REP_SUCCESS) { + rad_log(RL_ERROR, + "Error getting handle" + " to repository"); + return (-1); + } if ((modified_user = get_user(username)) != NULL) { *rtnval = modified_user; } else { - rad_log(RL_DEBUG, "Cannot read modified user"); + rad_log(RL_ERROR, + "Cannot read modified user"); *error = make_error(&e__UserMgrErrorType_READERROR); return (ce_object); } } else if (fstatus != 0) { - rad_log(RL_DEBUG, "unable to fork child process"); + rad_log(RL_ERROR, + "Unable to fork child process"); *error = make_error(&e__UserMgrErrorType_READERROR); rtn_code = ce_object; } else { - rad_log(RL_DEBUG, "error modifying user %s", username); + rad_log(RL_ERROR, + "Error modifying user %s", username); switch (estatus) { case EX_NO_PERM: case EX_NO_AUTH: @@ -652,7 +1223,8 @@ if ((rtn_code == ce_ok) && password) { int res = update_user_passwd(username, password); if (res != 0) { - rad_log(RL_DEBUG, "unable to set user password"); + rad_log(RL_ERROR, + "Unable to set user password"); switch (res) { case PAM_EPERM: rtn_code = ce_priv; @@ -671,6 +1243,7 @@ if (rtn_code != ce_ok) data_free(*rtnval); + free_repository_handle(scope_rep); return (rtn_code); } @@ -682,9 +1255,20 @@ assert(args[0] != NULL); const char *username = data_to_string(args[0]); - const char *argv[] = {USERDEL, "-r", username, NULL}; + const char *argv[] = {USERDEL, "-S", scope, "-r", username, NULL}; + + if (strcmp(type, USERATTR_TYPE_ROLE) == 0) { + argv[0] = ROLEDEL; + } boolean_t last_admin; + rad_log(RL_DEBUG, "In deleteUser. scope:%s", scope); + if (get_repository_handle(scope, &scope_rep) != SEC_REP_SUCCESS) { + rad_log(RL_ERROR, + "Error getting handle to repository"); + *error = make_error(&e__UserMgrErrorType_READERROR); + return (ce_object); + } if (is_last_admin(&last_admin, username) != 0) { *error = make_error(&e__UserMgrErrorType_READERROR); return (ce_object); @@ -692,7 +1276,8 @@ if ((get_user_type(ROOT) == UT_ROLE) && last_admin) { *error = make_error(&e__UserMgrErrorType_LASTADMIN); - rad_log(RL_DEBUG, "cannot delete last local administrator."); + rad_log(RL_ERROR, + "Cannot delete last local administrator"); return (ce_object); } @@ -700,16 +1285,18 @@ int fstatus = rad_forkexec_wait(NULL, argv, &estatus); if ((fstatus == 0) && (estatus == 0)) { - rad_log(RL_DEBUG, "%s deleted successfully", username); + rad_log(RL_DEBUG, + "%s deleted successfully", username); return (ce_ok); } /* unable to delete home directory, try again without the -r option */ if (estatus == EX_HOMEDIR) { - rad_log(RL_WARN, "Unable to determine the status of home %s", + rad_log(RL_WARN, + "Unable to determine the status of home %s", "directory, trying again."); - const char *argv[] = {USERDEL, username, NULL}; + const char *argv[] = {USERDEL, "-S", scope, username, NULL}; fstatus = rad_forkexec_wait(NULL, argv, &estatus); if ((fstatus == 0) && (estatus == 0)) { @@ -721,7 +1308,7 @@ conerr_t rtn_code = ce_ok; if (fstatus != 0) { - rad_log(RL_DEBUG, "unable to fork child process"); + rad_log(RL_DEBUG, "Unable to fork child process"); *error = make_error(&e__UserMgrErrorType_READERROR); rtn_code = ce_object; } else { @@ -739,11 +1326,23 @@ if (rtn_code == ce_priv) data_free(*error); + free_repository_handle(scope_rep); return (rtn_code); } /*ARGSUSED*/ conerr_t +api_UserMgr_invoke_getUser(rad_instance_t *inst, adr_method_t *meth, + data_t **rtnval, data_t **args, int count, data_t **error) +{ + /* will implement along with other fixes. */ + *rtnval = NULL; + *error = make_error(&e__UserMgrErrorType_READERROR); + return (ce_object); +} + +/*ARGSUSED*/ +conerr_t api_UserMgr_invoke_isAdministrator(rad_instance_t *inst, adr_method_t *meth, data_t **rtnval, data_t **args, int count, data_t **error) { @@ -758,7 +1357,7 @@ enduserattr(); data_t *res = data_new_boolean(admin); - if (*rtnval = data_purify(res)) { + if ((*rtnval = data_purify_deep(res)) != NULL) { return (ce_ok); } else { *error = make_error(&e__UserMgrErrorType_READERROR); @@ -827,7 +1426,6 @@ rtn_code = ce_object; } } - return (rtn_code); } @@ -839,7 +1437,7 @@ const char *username = data_to_string(args[0]); data_t *type = data_new_enum(&t__UserType, get_user_type(username)); - if (*rtnval = data_purify(type)) { + if ((*rtnval = data_purify_deep(type)) != NULL) { return (ce_ok); } else { *error = make_error(&e__UserMgrErrorType_READERROR); @@ -954,38 +1552,259 @@ data_t *group_id = data_new_uinteger(group); data_t *default_shell = data_new_string(shell, lt_copy); data_t *home_dir = data_new_string(basedir, lt_copy); + data_t *inactive = data_new_integer(-1); + data_t *min = data_new_integer(-1); + data_t *max = data_new_integer(-1); + data_t *warn = data_new_integer(-1); + data_t *accountStatus = data_new_string("UNKNOWN", lt_const); - if ((user == NULL) || (username == NULL) || (group_id == NULL) || - (default_shell == NULL) || (home_dir == NULL)) { - data_free(user); - data_free(username); - data_free(group_id); - data_free(default_shell); - data_free(home_dir); + struct_set(user, "username", username); + struct_set(user, "userID", data_new_uinteger(0)); + struct_set(user, "groupID", group_id); + struct_set(user, "defaultShell", default_shell); + struct_set(user, "homeDirectory", home_dir); + struct_set(user, "inactive", inactive); + struct_set(user, "min", min); + struct_set(user, "max", max); + struct_set(user, "warn", warn); + struct_set(user, "accountStatus", accountStatus); + if ((*rtnval = data_purify_deep(user)) == NULL) { *error = make_error(&e__UserMgrErrorType_READERROR); return (ce_object); - } else { - struct_set(user, "username", username); - struct_set(user, "userID", data_new_uinteger(0)); - struct_set(user, "groupID", group_id); - struct_set(user, "defaultShell", default_shell); - struct_set(user, "homeDirectory", home_dir); - - if (!(*rtnval = data_purify(user))) { - *error = make_error(&e__UserMgrErrorType_READERROR); - return (ce_object); - } } return (ce_ok); } + +static void +populate_list(nss_attr_t *list, const char *attr_name, conerr_t *rtn_code, +data_t **rtnval, data_t **error) +{ + data_t *attrs_arr = NULL; + *rtn_code = ce_ok; + + if (list != NULL) { + attrs_arr = make_attrs_array(list); + if (attrs_arr == NULL) { + rad_log(RL_ERROR, "Error making %s list.", attr_name); + *error = make_error(&e__UserMgrErrorType_READERROR); + *rtn_code = ce_object; + } + if ((*rtnval = data_purify_deep(attrs_arr)) == NULL) { + rad_log(RL_ERROR, "Error in return type."); + *error = make_error(&e__UserMgrErrorType_READERROR); + *rtn_code = ce_object; + } + } else { + rad_log(RL_ERROR, + "Error getting assigned %s.", attr_name); + *error = make_error(&e__UserMgrErrorType_READERROR); + *rtn_code = ce_object; + } +} + +/*ARGSUSED*/ +conerr_t +api_UserMgr_read_profiles(rad_instance_t *inst, adr_attribute_t *attr, + data_t **rtnval, data_t **error) +{ + conerr_t rtn_code = ce_ok; + nss_attr_t *profs_lst = NULL; + + rad_log(RL_DEBUG, "In read_profiles"); + _nss_get_assign_profiles(NULL, &profs_lst); + populate_list(profs_lst, USERATTR_PROFILES_KW, &rtn_code, + rtnval, error); + return (rtn_code); +} + +/*ARGSUSED*/ +conerr_t +api_UserMgr_read_roles(rad_instance_t *inst, adr_attribute_t *attr, + data_t **rtnval, data_t **error) +{ + conerr_t rtn_code = ce_ok; + nss_attr_t *roles_lst = NULL; + + rad_log(RL_DEBUG, "In read_roles."); + _nss_get_assign_roles(NULL, &roles_lst); + populate_list(roles_lst, USERATTR_ROLES_KW, &rtn_code, + rtnval, error); + return (rtn_code); +} + +/*ARGSUSED*/ +conerr_t +api_UserMgr_read_auths(rad_instance_t *inst, adr_attribute_t *attr, + data_t **rtnval, data_t **error) +{ + conerr_t rtn_code = ce_ok; + nss_attr_t *auths_lst = NULL; + + rad_log(RL_DEBUG, "In read_auths"); + _nss_get_assign_auths(NULL, &auths_lst); + populate_list(auths_lst, USERATTR_AUTHS_KW, + &rtn_code, rtnval, error); + return (rtn_code); +} + +/*ARGSUSED*/ +conerr_t +api_UserMgr_read_defaultPrivs(rad_instance_t *inst, adr_attribute_t *attr, + data_t **rtnval, data_t **error) +{ + conerr_t rtn_code = ce_ok; + nss_attr_t *privs_lst = NULL; + + rad_log(RL_DEBUG, "In read_deafutlPrivs"); + _nss_get_assign_privs(NULL, USERATTR_DFLTPRIV_KW, &privs_lst); + populate_list(privs_lst, USERATTR_DFLTPRIV_KW, + &rtn_code, rtnval, error); + return (rtn_code); +} + +/*ARGSUSED*/ +conerr_t +api_UserMgr_read_limitPrivs(rad_instance_t *inst, adr_attribute_t *attr, + data_t **rtnval, data_t **error) +{ + conerr_t rtn_code = ce_ok; + nss_attr_t *privs_lst = NULL; + + rad_log(RL_DEBUG, "In read_limitPrivs"); + _nss_get_assign_privs(NULL, USERATTR_LIMPRIV_KW, &privs_lst); + populate_list(privs_lst, USERATTR_LIMPRIV_KW, + &rtn_code, rtnval, error); + return (rtn_code); +} + +/*ARGSUSED*/ +conerr_t +api_UserMgr_read_supplGroups(rad_instance_t *inst, adr_attribute_t *attr, + data_t **rtnval, data_t **error) +{ + conerr_t rtn_code = ce_ok; + nss_attr_t *grps_lst = NULL; + + rad_log(RL_DEBUG, "In SupplGroups."); + _nss_get_assign_grps(NULL, &grps_lst); + populate_list(grps_lst, GROUPS, &rtn_code, rtnval, error); + return (rtn_code); +} + +/*ARGSUSED*/ +conerr_t +api_UserMgr_read_scopes(rad_instance_t *inst, adr_attribute_t *attr, + data_t **rtnval, data_t **error) +{ + conerr_t rtn_code = ce_ok; + char *scopes_str; + char *lasts; + char *token; + data_t *scope; + + rad_log(RL_DEBUG, "In readScopes."); + scopes_str = _nss_get_scopes(); + data_t *scopes_arr = data_new_array(&t_array_string, 2); + token = strtok_r(scopes_str, ",", &lasts); + do { + if (token != NULL) { + scope = data_new_string((const char *)token, + lt_copy); + (void) array_add(scopes_arr, scope); + } + } while ((token = strtok_r(NULL, ",", &lasts)) != NULL); + if (data_verify(scopes_arr, scopes_arr->d_type, B_TRUE)) { + *rtnval = scopes_arr; + } else { + data_free(scopes_arr); + *rtnval = NULL; + *error = make_error(&e__UserMgrErrorType_READERROR); + rtn_code = ce_object; + } + return (rtn_code); +} + + +/*ARGSUSED*/ +conerr_t +api_UserMgr_read_auditClasses(rad_instance_t *inst, adr_attribute_t *attr, + data_t **rtnval, data_t **error) +{ + /* will implement along with other fixes. */ + *rtnval = NULL; + *error = make_error(&e__UserMgrErrorType_READERROR); + return (ce_object); +} + + +/*ARGSUSED*/ +conerr_t +api_UserMgr_read_pamUserConfFiles(rad_instance_t *inst, adr_attribute_t *attr, + data_t **rtnval, data_t **error) +{ + /* will implement along with other fixes. */ + *rtnval = NULL; + *error = make_error(&e__UserMgrErrorType_READERROR); + return (ce_object); +} + +/*ARGSUSED*/ +conerr_t +api_UserMgr_invoke_setScope(rad_instance_t *inst, adr_method_t *meth, + data_t **rtnval, data_t **args, int count, data_t **error) +{ + boolean_t setOK = B_TRUE; + conerr_t rtn_code = ce_ok; + int uscope = enum_tovalue(data_get_internal(args[0], dt_enum)); + + rad_log(RL_DEBUG, "In setScope : %d.", uscope); + if (uscope == 1) { + setOK = __ns_ldap_is_shadow_update_enabled(); + rad_log(RL_DEBUG, "is_shadow_update_enabled:%s", + (setOK == B_TRUE) ? "TRUE" : "FALSE"); + } + scope = (char *)strdup((uscope == 1) ? NSS_REP_LDAP : NSS_REP_FILES); + return (rtn_code); +} + +/*ARGSUSED*/ +conerr_t +api_UserMgr_invoke_setFilter(rad_instance_t *inst, adr_method_t *meth, + data_t **rtnval, data_t **args, int count, data_t **error) +{ + conerr_t rtn_code = ce_ok; + int utype = enum_tovalue(data_get_internal(args[0], dt_enum)); + + rad_log(RL_DEBUG, "In setFilter : %d.", utype); + if (utype != 0 && utype != 1) { + rad_log(RL_DEBUG, "Invalid type :%d", utype); + return (rtn_code); + } + type = (char *)strdup((utype == 1) ? + USERATTR_TYPE_ROLE : USERATTR_TYPE_NORMAL_KW); + return (rtn_code); +} + +/*ARGSUSED*/ +conerr_t +api_UserMgr_invoke_isSystemLabeled(rad_instance_t *inst, adr_method_t *meth, + data_t **rtnval, data_t **args, int count, data_t **error) +{ + /* will implement along with other fixes. */ + *rtnval = NULL; + *error = make_error(&e__UserMgrErrorType_READERROR); + return (ce_object); +} + static rad_modinfo_t modinfo = {"usermgr", "User Management"}; int _rad_init(void *handle) { + if (rad_module_register(handle, RAD_MODVERSION, &modinfo) == -1) return (-1); @@ -993,7 +1812,7 @@ return (0); (void) cont_insert_singleton(rad_container, adr_name_fromstr( - "com.oracle.solaris.vp.panels.usermgr:type=UserMgr"), + "com.oracle.solaris.rad.usermgr:type=UserMgr"), &api_UserMgr_svr); return (0); diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/build.xml --- a/usr/src/java/vpanels/app/usermgr/build.xml Thu Apr 26 00:14:30 2012 -0400 +++ b/usr/src/java/vpanels/app/usermgr/build.xml Fri Apr 27 00:52:26 2012 -0400 @@ -39,7 +39,7 @@ value="com.oracle.solaris.vp.panels.usermgr.client.swing.UserMgrPanelDescriptor" /> + value="com/oracle/solaris/vp/panels/usermgr/client/swing/images/usermgr-32.png" /> diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/ActionString.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/ActionString.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,142 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + */ + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import java.util.*; + +import com.oracle.solaris.vp.util.misc.finder.Finder; + +/** + * SMC code adapted for Visual Panels + * + * ActionString interposes between the application code and it's resource + * bundle, but parses the returned string for the mnemonic indicator and + * removes it. The mnemonic character is '&', as used in Windows. This + * class make it easy to localize the text and associated mnemonics in a + * resource properties file - mnemonics can be embedded within the string, + * obviating the need for seperate resource strings for the mnemonics. + * + * Note: many Swing components can now take in HTML encoded text in addition + * to plain text. To encode a mnemonic in HTML the '&' has to be encoded + * in the HTML escaped form '&'. Otherwise the HTML processing within + * Swing will remove the a single '&'. + * + */ +public class ActionString { + + private String string; + private int mnemonic = 0; + + /** + * Returns the localized message associated with the specified message key + * from the default resource bundle. Strip out the mnemonic indicator. + * Users of this class can then use getString() and getMnemonic(). + * + * @param key message lookup key + */ + public ActionString(String key) { + + string = Finder.getString(key); + split(); + + } // constructor + + /* + * Returns the text string without the mnemonic indicator + * + * @return the text string without the mnemonic character + */ + public String getString() { + + return string; + + } // getString + + + /* + * Returns the mnemonic character + * + * @return the mnemonic character + */ + public int getMnemonic() { + + return mnemonic; + + } // getMnemonic + + + /** + * Split the retrieved message into its string and mnemonic parts. + */ + private void split() { + + /* + * Simple check to see if the text is HTML or plain text. If the text + * is HTML the mnemonic indicator will be encoded as '&' and not + * the plain text '&'. Therefore extraction of the mnemonic itself + * is a little more interesting. Also the underline tags need to + * be inserted to ensure that the mnemonic character is correctly + * displayed underlined when the text is HTML. + */ + boolean isHtml = + (string.startsWith("") && string.endsWith("")); + + String ampString = null; + + if (isHtml) { + ampString = "&"; + } else { + ampString = "&"; + } + + int ampStringLen = ampString.length(); + int i = string.indexOf(ampString); + + if (i > -1) { + String sUpper = string.toUpperCase(); + mnemonic = sUpper.charAt(i + ampStringLen); + + StringBuffer s = new StringBuffer(); + s.append(string.substring(0, i)); + + if (isHtml) { + s.append(""); + } + + s.append(string.substring(i + ampStringLen, i+ ampStringLen + 1)); + + if (isHtml) { + s.append(""); + } + + s.append(string.substring(i + ampStringLen + 1, string.length())); + + string = s.toString(); + } + + } // split + +} // ActionString diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AddUserAction.java --- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AddUserAction.java Thu Apr 26 00:14:30 2012 -0400 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AddUserAction.java Fri Apr 27 00:52:26 2012 -0400 @@ -25,6 +25,7 @@ package com.oracle.solaris.vp.panels.usermgr.client.swing; +import java.awt.*; import java.awt.event.*; import java.util.List; import javax.swing.*; @@ -32,41 +33,77 @@ import com.oracle.solaris.vp.panel.common.action.*; import com.oracle.solaris.vp.panel.common.control.*; import com.oracle.solaris.vp.panel.swing.action.AddManagedObjectAction; -import com.oracle.solaris.vp.panels.usermgr.*; +import com.oracle.solaris.vp.panel.swing.view.ChangeIndicator; +import com.oracle.solaris.rad.usermgr.*; import com.oracle.solaris.vp.util.misc.ObjectUtil; import com.oracle.solaris.vp.util.misc.finder.Finder; import com.oracle.solaris.vp.util.misc.property.*; import com.oracle.solaris.vp.util.swing.*; import com.oracle.solaris.vp.util.swing.layout.*; import com.oracle.solaris.vp.util.swing.property.*; +import com.oracle.solaris.vp.util.misc.ChangeableAggregator; + +/* + * Add a new user or role + */ @SuppressWarnings({"serial"}) public class AddUserAction extends AddManagedObjectAction { + private UserManagedObject umo = null; + private UserImpl user = null; + // // Inner classes // - protected class Data { + protected class Data implements ActionListener { // // Instance data // - public StringProperty userNameProperty = new StringProperty(); - public StringProperty userDescProperty = new StringProperty(); + private JLabel uidLabel; + private HintTextField uidField; + private JLabel descLabel; + private JComboBox groupCombo; + private HintTextField homeField; + private JComboBox shellCombo; + public MutableProperty typeProperty = new StringProperty(); + public StringProperty nameProperty = new StringProperty(); + public LongProperty uidProperty = new LongProperty(); + public MutableProperty descProperty = new StringProperty(); + public MutableProperty groupProperty = new StringProperty(); + public MutableProperty homeProperty = new StringProperty(); + public MutableProperty shellProperty = new StringProperty(); public MutableProperty passProperty = new BasicMutableProperty(); public MutableProperty passConfirmProperty = new BasicMutableProperty(); - public JOptionPane pane; - public JDialog dialog; + + private JOptionPane pane; + private JDialog dialog; + private static final String ACTION_ADV_SETTINGS = "settings"; + private AdvancedSettingsDialog advDialog = null; + private UserMgrPanelDescriptor descriptor = null; + private ActionString actString = null; // // Constructors // public Data() { + pane = new JOptionPane(createForm(), JOptionPane.PLAIN_MESSAGE, + JOptionPane.OK_CANCEL_OPTION); + UserMgrUtils.removeIcons(pane); + + String title = Finder.getString("usermgr.new.title." + + descriptor.getTypeString()); + dialog = pane.createDialog(getHasComponent().getComponent(), + title); + } + + private JPanel createForm() { ActionListener listener = new ActionListener() { @Override @@ -75,79 +112,242 @@ } }; - // Intro text - JLabel introLabel = new JLabel( - Finder.getString("usermgr.adduser.label.intro")); + descriptor = control.getPanelDescriptor(); + user = descriptor.getDefaultUser(); + + JPanel form = new JPanel(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + int width = GUIUtil.getTextFieldWidth(); + + gbc.gridx = 0; + gbc.gridy = 0; + gbc.weightx = 1.0; + gbc.anchor = GridBagConstraints.LINE_START; + int hGap = GUIUtil.getHalfGap(); + gbc.insets = new Insets(0, 0, hGap, hGap); - // User name - JLabel userNameLabel = new JLabel( - Finder.getString("usermgr.basic.label.username")); - JTextField userNameField = GUIUtil.createTextField(); - userNameField.addActionListener(listener); + // Intro text + JLabel introLabel = new JLabel( + Finder.getString("usermgr.new.label." + + descriptor.getTypeString())); + form.add(introLabel, gbc); + + // User name + actString = new ActionString("usermgr.basic.name." + + descriptor.getTypeString()); + JLabel nameLabel = new JLabel(actString.getString()); + nameLabel.setDisplayedMnemonic(actString.getMnemonic()); + + JTextField nameField = GUIUtil.createTextField(); + nameField.addActionListener(listener); new TextComponentPropertySynchronizer - (userNameProperty, userNameField, false); + (nameProperty, nameField, false); + + // Connect the label to the field + nameLabel.setLabelFor(nameField); + + // Add to the layout + gbc.gridx = 0; + gbc.gridy++; // next row + form.add(nameLabel, gbc); + gbc.gridx = GridBagConstraints.RELATIVE; + form.add(nameField, gbc); + form.add(new Spacer(), gbc); + + // Description + actString = new ActionString("usermgr.basic.desc." + + descriptor.getTypeString()); + descLabel = new JLabel(actString.getString()); + descLabel.setDisplayedMnemonic(actString.getMnemonic()); + JTextField descField = GUIUtil.createTextField(); + new TextComponentPropertySynchronizer( + descProperty, descField); + + // Connect the label to the field + descLabel.setLabelFor(descField); + + // Add to the layout + gbc.gridx = 0; + gbc.gridy++; // next row + form.add(descLabel, gbc); + gbc.gridx = GridBagConstraints.RELATIVE; + form.add(descField, gbc); + + // User ID + actString = new ActionString("usermgr.basic.uid." + + descriptor.getTypeString()); + uidLabel = new JLabel(actString.getString()); + uidLabel.setDisplayedMnemonic(actString.getMnemonic()); + + + uidField = new HintTextField(width); + uidField.setHintText( + Finder.getString("usermgr.new.value.auto")); + uidField.setDocument(new NumericDocument()); + new HintTextPropertySynchronizer(uidProperty, + uidField, 0L); + ChangeIndicator uidChange = new ChangeIndicator(); + uidProperty.addChangeListener(uidChange); + uidProperty.save(); + // uidField.addActionListener(listener); + + // Connect the label to the field + uidLabel.setLabelFor(uidField); + + // Add to the layout + gbc.gridx = 0; + gbc.gridy++; // next row + form.add(uidLabel, gbc); + gbc.gridx = GridBagConstraints.RELATIVE; + form.add(uidField, gbc); + form.add(new Spacer(), gbc); - // User Description - JLabel userDescLabel = new JLabel( - Finder.getString("usermgr.basic.label.userdesc")); - JTextField userDescField = GUIUtil.createTextField(); - userDescField.addActionListener(listener); - new TextComponentPropertySynchronizer - (userDescProperty, userDescField, false); + // Group Name + actString = new ActionString("usermgr.basic.label.group"); + JLabel groupLabel = new JLabel(actString.getString()); + groupLabel.setDisplayedMnemonic(actString.getMnemonic()); + groupCombo = new JComboBox(); + new ComboBoxPropertySynchronizer(groupProperty, groupCombo); + + for (Group g : descriptor.getGroups()) { + groupCombo.addItem(g.getGroupName()); + if (user.getGroupID() == g.getGroupID()) { + groupCombo.setSelectedItem(g.getGroupName()); + } + } + + // Connect the label to the field + groupLabel.setLabelFor(groupCombo); + + gbc.gridx = 0; + gbc.gridy++; // next row + form.add(groupLabel, gbc); + gbc.gridx = GridBagConstraints.RELATIVE; + form.add(groupCombo, gbc); + + // Home Directory + actString = new ActionString("usermgr.basic.label.home"); + JLabel homeLabel = new JLabel(actString.getString()); + homeLabel.setDisplayedMnemonic(actString.getMnemonic()); + + homeField = new HintTextField(width); + homeField.setHintText(Finder.getString("usermgr.new.value.auto")); + new HintTextPropertySynchronizer(homeProperty, homeField, ""); + ChangeIndicator homeChange = new ChangeIndicator(); + homeProperty.addChangeListener(homeChange); + homeProperty.save(); + + // Connect the label to the field + homeLabel.setLabelFor(homeField); + + // Add to the layout + gbc.gridx = 0; + gbc.gridy++; // next row + form.add(homeLabel, gbc); + gbc.gridx = GridBagConstraints.RELATIVE; + form.add(homeField, gbc); + + // Login Shell + actString = new ActionString("usermgr.basic.label.shell"); + JLabel shellLabel = new JLabel(actString.getString()); + shellLabel.setDisplayedMnemonic(actString.getMnemonic()); + shellCombo = new JComboBox(); + new ComboBoxPropertySynchronizer(shellProperty, shellCombo); + for (String s : descriptor.getShells()) + shellCombo.addItem(s); + + shellCombo.setSelectedItem(user.getDefaultShell()); + // Connect the label to the field + shellLabel.setLabelFor(shellCombo); + + gbc.gridx = 0; + gbc.gridy++; // next row + form.add(shellLabel, gbc); + gbc.gridx = GridBagConstraints.RELATIVE; + form.add(shellCombo, gbc); // Password - int width = GUIUtil.getTextFieldWidth(); - JLabel passLabel = new JLabel( - Finder.getString("usermgr.basic.label.pass")); + actString = new ActionString("usermgr.basic.label.pass"); + JLabel passLabel = new JLabel(actString.getString()); + passLabel.setDisplayedMnemonic(actString.getMnemonic()); + JPasswordField passField = new JPasswordField(width); passField.addActionListener(listener); - new PasswordFieldPropertySynchronizer(passProperty, - passField, false); + new PasswordFieldPropertySynchronizer(passProperty, passField, false); + + // Connect the label to the field + passLabel.setLabelFor(passField); - // Password Confirm - JLabel passConfirmLabel = new JLabel( - Finder.getString("usermgr.basic.label.passconfirm")); - JPasswordField passConfirmField = new JPasswordField(width); - new PasswordFieldPropertySynchronizer(passConfirmProperty, - passConfirmField, false); + // Add to the layout + gbc.gridx = 0; + gbc.gridy++; // next row + form.add(passLabel, gbc); + gbc.gridx = GridBagConstraints.RELATIVE; + form.add(passField, gbc); + + // Password Confirm + actString = new ActionString("usermgr.basic.label.passconfirm"); + JLabel passConfirmLabel = new JLabel(actString.getString()); + passConfirmLabel.setDisplayedMnemonic(actString.getMnemonic()); - JPanel formPanel = new JPanel(); - formPanel.setOpaque(false); - Form form = new Form(formPanel, VerticalAnchor.TOP); + JPasswordField passConfirmField = new JPasswordField(width); + new PasswordFieldPropertySynchronizer( + passConfirmProperty, passConfirmField, false); - int gap = GUIUtil.getHalfGap() * 2; + // Connect the label to the field + passConfirmLabel.setLabelFor(passConfirmField); - ColumnLayoutConstraint c = new ColumnLayoutConstraint( - HorizontalAnchor.FILL, gap); - RowLayoutConstraint row = new RowLayoutConstraint( - VerticalAnchor.CENTER, gap); - row.setLayoutIfInvisible(true); - HasAnchors a = new SimpleHasAnchors( - HorizontalAnchor.LEFT, VerticalAnchor.CENTER); + // Add to the layout + gbc.gridx = 0; + gbc.gridy++; // next row + form.add(passConfirmLabel, gbc); + gbc.gridx = GridBagConstraints.RELATIVE; + form.add(passConfirmField, gbc); + + // Advanced Settings + actString = new ActionString("usermgr.advanced.settings"); + JButton advSettings = new JButton(actString.getString()); + advSettings.setActionCommand(ACTION_ADV_SETTINGS); + advSettings.addActionListener(this); + advSettings.setMnemonic(actString.getMnemonic()); - form.addRow(HorizontalAnchor.LEFT, c); - form.add(introLabel, row); - - form.addTable(2, gap, gap, HorizontalAnchor.LEFT, c); + // Add to the layout + gbc.gridx = 0; + gbc.gridy++; + gbc.gridwidth = GridBagConstraints.REMAINDER; + gbc.anchor = GridBagConstraints.SOUTHWEST; + form.add(advSettings, gbc); - form.add(userNameLabel, a); - form.add(userNameField, a); - - form.add(userDescLabel, a); - form.add(userDescField, a); + return form; + } - form.add(passLabel, a); - form.add(passField, a); - - form.add(passConfirmLabel, a); - form.add(passConfirmField, a); + /** + * action listener for Adv settings button + */ + @Override + public void actionPerformed(ActionEvent e) { + String actionCmd = e.getActionCommand(); + if (actionCmd == ACTION_ADV_SETTINGS) { + UserMgrPanelDescriptor descriptor = + control.getPanelDescriptor(); + if (umo == null || user == null) { + user = new UserImpl(); + umo = new UserManagedObject(descriptor, user, null); + } - pane = new JOptionPane(formPanel, JOptionPane.PLAIN_MESSAGE, - JOptionPane.OK_CANCEL_OPTION); - - dialog = pane.createDialog(getHasComponent().getComponent(), - Finder.getString("usermgr.adduser.title")); - } + if (advDialog == null || + descriptor.isTypeRole() != advDialog.isTypeRole()) { + advDialog = new AdvancedSettingsDialog( + getHasComponent().getComponent(), descriptor, umo); + } else { + advDialog.setUser(umo); + } + advDialog.show(); + if (advDialog.getValue() == JOptionPane.OK_OPTION) { + advDialog.update(); + } + } + } } // @@ -169,6 +369,10 @@ public AddUserAction(MainControl control) { super(ADD_TEXT, null, control); + ActionString actStr = new ActionString( + "usermgr.action.add.button"); + putValue(Action.NAME, actStr.getString()); + putValue(Action.MNEMONIC_KEY, actStr.getMnemonic()); this.control = control; setLoops(true); } @@ -178,8 +382,8 @@ // @Override - public Data getRuntimeInput(List selection, Data uData) - throws ActionAbortedException { + public Data getRuntimeInput(List selection, + Data uData) throws ActionAbortedException { // Since this action navigates to the new object once created, we must // first navigate to control so that any outstanding changes in the @@ -210,35 +414,53 @@ @Override public UserManagedObject workBusy(List selection, - Data uData) throws ActionAbortedException, ActionFailedException, + Data uData) throws ActionFailedException, + ActionAbortedException, ActionUnauthorizedException { + UserMgrPanelDescriptor descriptor = control.getPanelDescriptor(); - String username = uData.userNameProperty.getValue(); + String username = uData.nameProperty.getValue(); UserMgrUtils.validateUsername(descriptor, username); - String description = uData.userDescProperty.getValue(); + String description = uData.descProperty.getValue(); UserMgrUtils.validateUserDesc(description); + String group = uData.groupProperty.getValue(); + String shell = uData.shellProperty.getValue(); + String homedir = uData.homeProperty.getValue(); + char[] password = uData.passProperty.getValue(); char[] password2 = uData.passConfirmProperty.getValue(); UserMgrUtils.validatePassword(true, password, password2); - UserImpl user = descriptor.getDefaultUser(); - user.setUsername(username); - user.setDescription(description); UserMgrUtils.clearPassword(password2); - UserManagedObject umo = new UserManagedObject(descriptor, + user.setUsername(username); + if (uData.uidProperty.isChanged()) { + long uid = uData.uidProperty.getValue(); + user.setUserID(uid); + } + + user.setDescription(description); + user.setDefaultShell(shell); + user.setHomeDirectory(homedir); + + if (umo == null) { + umo = new UserManagedObject(descriptor, user, password); + } else { + umo.setUser(user, password); + } - descriptor.addUserManagedObject(umo); + descriptor.addToAddList(umo); + descriptor.saveAddedUsers(); // Navigate to the newly created user Navigable navigable = new SimpleNavigable( - UserMgrControl.ID, umo.getName(), - UserMgrControl.PARAM_USER, umo.getId()); + UserMgrBasicControl.ID, umo.getName(), + UserMgrBasicControl.PARAM_USER, umo.getId()); control.getNavigator().goToAsync(false, control, navigable); diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AdvancedSettings.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AdvancedSettings.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,70 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + */ + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import javax.swing.*; +import com.oracle.solaris.vp.util.misc.property.*; +import com.oracle.solaris.vp.util.misc.finder.Finder; + +/* + * AdvancedSettings abstract class. All the advanced settings + * such as Rights, Groups etc. implement this class + */ + +public abstract class AdvancedSettings { + + protected String label; // Text shown in the settings list + protected Icon icon; // Corresponding icon. + protected MutableProperty settingsProperty = new StringProperty(); + + public AdvancedSettings(String label, Icon icon) { + this.label = label; + this.icon = icon; + } + + public String getLabel() { + return label; + } + + @Override + public String toString() { + return label; + } + + public Icon getIcon() { + return icon; + } + + public MutableProperty getProperty() { + return settingsProperty; + } + + protected abstract void init(UserMgrPanelDescriptor paneDesc); + protected abstract JPanel getPanel(); + protected abstract void setUser(UserManagedObject userObj); + protected abstract void updateUser(); + protected abstract boolean isChanged(); +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AdvancedSettingsDialog.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AdvancedSettingsDialog.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,252 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + */ + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import java.util.ArrayList; +import java.util.List; +import java.util.Vector; +import java.awt.*; +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.border.Border; +import com.oracle.solaris.vp.panel.common.action.*; +import com.oracle.solaris.vp.panel.common.control.*; +import com.oracle.solaris.vp.panel.swing.control.*; +import com.oracle.solaris.vp.panel.swing.view.*; +import com.oracle.solaris.vp.util.misc.ChangeableAggregator; +import com.oracle.solaris.vp.util.misc.finder.Finder; +import com.oracle.solaris.vp.util.misc.property.*; +import com.oracle.solaris.vp.util.swing.ClippedBorder; +import com.oracle.solaris.vp.util.swing.SimpleCellRenderer; + +/* + * Dialog for advanced settings. The settings list varies + * depending on a user or a role. The Roles settings are + * shown only for the user, not for the role. + */ + +public class AdvancedSettingsDialog implements ListSelectionListener { + + // + // Static data + // + + private JPanel cards; + + class SettingsRenderer extends SimpleCellRenderer { + public SettingsRenderer() { + super(); + } + + @Override + public Icon getIcon(Component comp, AdvancedSettings value, + boolean isSelected, boolean hasFocus) { + + // + // Current Visual designer doesn't like any icons. + // If needed in future, just call return value.getIcon(); + + return (null); + } + + public String getText(Component comp, AdvancedSettings value, + boolean isSelected, boolean hasFocus) { + return (value.getLabel()); + } + } + + // + // Instance data + // + + private ManagedObjectTableModel model; + private UserMgrPanelDescriptor panelDesc; + private JOptionPane pane; + private JDialog dialog; + private AdvancedSettings userSettings[] = { + new GroupsSettings(), + new RolesSettings(), + new RightsSettings(), + new AuthsSettings() + }; + + // Role doesn't have roles to assign + private AdvancedSettings roleSettings[] = { + new GroupsSettings(), + new RightsSettings(), + new AuthsSettings() + }; + + private AdvancedSettings settingsList[]; + + private AdvancedSettings curSettings; + private UserManagedObject userObj; + private boolean isRole; + private String title = Finder.getString("usermgr.advanced.title"); + + private MutableProperty rightsProperty = new StringProperty(); + private MutableProperty rolesProperty = new StringProperty(); + private MutableProperty groupsProperty = new StringProperty(); + private MutableProperty authsProperty = new StringProperty(); + + + // + // Constructors + // + + public AdvancedSettingsDialog(Component parent, + UserMgrPanelDescriptor panelDesc, + UserManagedObject userObj) { + String utitle = title; + this.userObj = userObj; + if (panelDesc.isTypeRole()) { + settingsList = roleSettings; + isRole = true; + } else { + settingsList = userSettings; + isRole = false; + } + pane = new JOptionPane(createForm(panelDesc), + JOptionPane.PLAIN_MESSAGE, + JOptionPane.OK_CANCEL_OPTION); + UserMgrUtils.removeIcons(pane); + String name = userObj.getUsername(); + if (name != null) { + utitle = title + " (" + userObj.getUsername() + ")"; + } + // dialog = pane.createDialog(null, utitle); + dialog = pane.createDialog(parent, utitle); + dialog.setResizable(true); + } + + /** + * Populate various settings from the new user + */ + public void setUser(UserManagedObject userObj) { + this.userObj = userObj; + String utitle = title; + String name = userObj.getUsername(); + if (name != null) { + utitle = title + " (" + userObj.getUsername() + ")"; + } + dialog.setTitle(utitle); + + for (int i = 0; i < settingsList.length; i++) { + AdvancedSettings settings = settingsList[i]; + settings.setUser(userObj); + } + } + + /** + * Show the dialog. Block until dismissed + */ + public void show() { + dialog.setVisible(true); + } + + /** + * Create the main form/panel. + */ + private JPanel createForm(UserMgrPanelDescriptor panelDesc) { + JPanel form = new JPanel(new BorderLayout()); + cards = new JPanel(new CardLayout()); + JList list = new JList(settingsList); + SettingsRenderer renderer = new SettingsRenderer(); + renderer.configureFor(list); + list.setCellRenderer(renderer); + list.addListSelectionListener(this); + Border border = list.getBorder(); + list.setBorder(new ClippedBorder(border, false, true, true, true)); + JScrollPane scrollPane = new JScrollPane(list); + + scrollPane.setVerticalScrollBarPolicy( + ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); + scrollPane.setHorizontalScrollBarPolicy( + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); + form.add(scrollPane, BorderLayout.WEST); + for (int i = 0; i < settingsList.length; i++) { + curSettings = settingsList[i]; + curSettings.init(panelDesc); + curSettings.setUser(userObj); + cards.add(curSettings.getPanel(), curSettings.getLabel()); + } + list.setSelectedIndex(0); + form.add(cards, BorderLayout.CENTER); + form.setPreferredSize(new Dimension(700, 400)); + + return form; + } + + public void valueChanged(ListSelectionEvent e) { + JList list = (JList) e.getSource(); + curSettings = settingsList[list.getSelectedIndex()]; + CardLayout cl = (CardLayout) cards.getLayout(); + cl.show(cards, curSettings.getLabel()); + } + + public int getValue() { + Number n; + int option; + Object obj = pane.getValue(); + + if (obj.getClass().getSuperclass() == Number.class) { + n = (Number) obj; + option = n.intValue(); + return option; + } + + return JOptionPane.CANCEL_OPTION; + } + + /** + * Find out if any of the settings is changed + */ + public boolean isChanged() { + for (int i = 0; i < settingsList.length; i++) { + if (settingsList[i].isChanged()) { + return (true); + } + } + + return (false); + } + + /** + * Returns the type of user: role or normal user + */ + public boolean isTypeRole() { + return isRole; + } + + /** + * Update user object based on advanced settings + */ + public void update() { + for (int i = 0; i < settingsList.length; i++) { + settingsList[i].updateUser(); + } + } +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/Arranger.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/Arranger.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,377 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + */ + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.text.*; +import javax.swing.border.*; +import javax.swing.tree.*; + +import java.awt.*; +import java.awt.event.*; +import java.beans.*; +import java.util.*; +import java.io.*; + +import com.oracle.solaris.vp.util.misc.finder.Finder; + +/** + * SMC code adapted for Visual Panels + */ +public class Arranger extends DoubleTrees { + + JButton moveUpItem, moveDownItem; + + public Arranger() { + + // Map DoubleTrees variables here for better descriptive names + moveUpItem = addAllItem; + moveDownItem = delAllItem; + + setListeners(); + } + + public Arranger(String srcHeader, String dstHeader) { + + super(srcHeader, dstHeader); + + // Map DoubleTrees variables here for better descriptive names + moveUpItem = addAllItem; + moveDownItem = delAllItem; + + setListeners(); + + } + + /** + * Create any dynamic images we need. + */ + public void addNotify() { + + ActionString actionString; + + super.addNotify(); + + delItem.setIcon(Finder.getIcon("images/remove.png")); + delItem.setHorizontalTextPosition(JButton.RIGHT); + + moveDownItem.setIcon(Finder.getIcon("images/move_dn.png")); + moveDownItem.setHorizontalTextPosition(JButton.LEFT); + actionString = new ActionString("usermgr.advanced.move_down_btn"); + moveDownItem.setText(actionString.getString()); + moveDownItem.setMnemonic(actionString.getMnemonic()); + + addItem.setIcon(Finder.getIcon("images/add.png")); + addItem.setHorizontalTextPosition(JButton.LEFT); + + moveUpItem.setIcon(Finder.getIcon("images/move_up.png")); + moveUpItem.setHorizontalTextPosition(JButton.LEFT); + actionString = new ActionString("usermgr.advanced.move_up_btn"); + moveUpItem.setText(actionString.getString()); + moveUpItem.setMnemonic(actionString.getMnemonic()); + + } // addNotify + + public void setListeners() { + + addItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + move(srcTree, dstTree); + } + }); + + delItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + move(dstTree, srcTree); + } + }); + + moveUpItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + reorder(dstTree, -1); + } + }); + + moveDownItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + reorder(dstTree, +1); + } + }); + + MouseListener ml = new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + handleMouse(e); + } + + public void mousePressed(MouseEvent e) { + handleMouse(e); + } + }; + + srcTree.addMouseListener(ml); + dstTree.addMouseListener(ml); + + } + + private void updateMoveButtons(DblTreeNode node, boolean flag) { + + if (flag) { + DefaultTreeModel dstModel = (DefaultTreeModel)dstTree.getModel(); + DblTreeNode root = (DblTreeNode)dstModel.getRoot(); + + int index = dstModel.getIndexOfChild(root, node); + int limit = dstModel.getChildCount(root); + + if (index > 0) + moveUpItem.setEnabled(true); + else + moveUpItem.setEnabled(false); + if (index < (limit - 1)) + moveDownItem.setEnabled(true); + else + moveDownItem.setEnabled(false); + } else { + moveUpItem.setEnabled(false); + moveDownItem.setEnabled(false); + } + + } + + private void handleMouse(MouseEvent e) { + + JTree tree1, tree2; + + if (e.getSource() == srcTree) { + tree1 = srcTree; + tree2 = dstTree; + + delItem.setEnabled(false); + moveUpItem.setEnabled(false); + moveDownItem.setEnabled(false); + } else { + tree1 = dstTree; + tree2 = srcTree; + addItem.setEnabled(false); + } + TreePath selPath = tree1.getPathForLocation(e.getX(), e.getY()); + + if (selPath != null) { + tree2.clearSelection(); + int selCount = selPath.getPathCount(); + + DblTreeNode node = (DblTreeNode)selPath.getLastPathComponent(); + if (e.getClickCount() < 2) { + boolean flag; + if (selCount == 2) + flag = true; + else + flag = false; + + if (e.getSource() == srcTree) { + addItem.setEnabled(flag); + } else { + delItem.setEnabled(flag); + updateMoveButtons(node, flag); + } + } else if (e.getClickCount() == 2) { + if ((selCount == 2) && node.isLeaf()) + move(tree1, tree2); + } + } + + } + + public void move(JTree src, JTree dst) { + DblTreeNode node; + + TreePath selPath = src.getSelectionPath(); + if (selPath == null) // nothing selected (should be disabled) + return; + else if (selPath.getPathCount() != 2) + return; + else { + node = (DblTreeNode)selPath.getLastPathComponent(); + moveLeaf(src, dst, node); + + if (src == dstTree) { + addItem.setEnabled(true); + delItem.setEnabled(false); + updateMoveButtons(node, false); + } else { + addItem.setEnabled(false); + delItem.setEnabled(true); + updateMoveButtons(node, true); + } + } + + } + + + private int matchChild(JTree src, + JTree dst, + DblTreeNode srcNode, + DblTreeNode newparent, + Enumeration dstKids, + int index) { + + DefaultTreeModel srcModel = (DefaultTreeModel)src.getModel(); + DefaultTreeModel dstModel = (DefaultTreeModel)dst.getModel(); + + DblTreeNode dstNode = null; + String srcString = srcNode.toString(); + while (dstKids.hasMoreElements()) { + String teststring; + + dstNode = (DblTreeNode)dstKids.nextElement(); + // if(dstNode.isLeaf() == false) + // break; // leaves come first + teststring = dstNode.toString(); + if (teststring.compareTo(srcString) < 0) { + index++; + continue; + } else { + break; + } + } + + srcModel.removeNodeFromParent(srcNode); + dstModel.insertNodeInto(srcNode, newparent, index); + index++; + return index; + + } + + public void moveLeaf(JTree src, JTree dst, DblTreeNode node) { + + if (node.isEnabled()) { + TreePath nodepath = new TreePath(node.getPath()); + boolean expanded = src.isExpanded(nodepath); + initLeaf(src, dst, node); + nodepath = new TreePath(node.getPath()); + dst.setSelectionPath(nodepath); + + if (expanded) + dst.expandPath(nodepath); + } + + } + + + public void initLeaf(JTree src, JTree dst, DblTreeNode node) { + + DefaultTreeModel srcModel = (DefaultTreeModel)src.getModel(); + DefaultTreeModel dstModel = (DefaultTreeModel)dst.getModel(); + DblTreeNode parent, newparent, clonedParent, root; + int index = 0; + root = (DblTreeNode)dstModel.getRoot(); + int limit = dstModel.getChildCount(root); + + if (dst == dstTree) { + srcModel.removeNodeFromParent(node); + dstModel.insertNodeInto(node, root, limit); + } else { + Enumeration kids = root.children(); + index = matchChild(src, dst, node, root, kids, index); + } + + TreePath nodepath = new TreePath(node.getPath()); + dst.scrollPathToVisible(nodepath); + } + + + public void reorder(JTree dst, int delta) { + + DefaultTreeModel dstModel = (DefaultTreeModel)dst.getModel(); + DblTreeNode dstRoot = (DblTreeNode)dstModel.getRoot(); + DblTreeNode node; + + TreePath selPath = dst.getSelectionPath(); + if (selPath == null) // nothing selected (should be disabled) + return; + + node = (DblTreeNode)selPath.getLastPathComponent(); + int index = dstModel.getIndexOfChild(dstRoot, node); + int limit = dstModel.getChildCount(dstRoot); + index += delta; + + if ((index < 0) || (index >= limit)) + return; + + boolean expanded = dst.isExpanded(selPath); + dst.clearSelection(); + + dstModel.removeNodeFromParent(node); + dstModel.insertNodeInto(node, dstRoot, index); + + TreePath nodepath = new TreePath(node.getPath()); + if (expanded) + dst.expandPath(nodepath); + + dst.setSelectionPath(nodepath); + dst.scrollPathToVisible(nodepath); + + if (index > 0) + moveUpItem.setEnabled(true); + else + moveUpItem.setEnabled(false); + + if (index < (limit - 1)) + moveDownItem.setEnabled(true); + else + moveDownItem.setEnabled(false); + + } + + /** + * Set the focus listeners for the components in the selector panel that + * can have unique help that may be context-specific. Client apps + * should call this method after the Arranger is created, but + * before the dialog is shown. Any of the listener arguments can be + * null, if the client app can accept the default help for the particular + * component. + * + * @param upButtonListener listener for the move-up button + * @param downButtonListener listener for the move-down button + * @see ContextHelpListener + */ + public void setFocusListeners( + FocusListener upButtonListener, + FocusListener downButtonListener) { + + if (upButtonListener != null) + moveUpItem.addFocusListener(upButtonListener); + + if (downButtonListener != null) + moveDownItem.addFocusListener(downButtonListener); + + } // setFocusListeners + + public void resetModels() { + srcTree.setModel(new DefaultTreeModel(new DblTreeNode("All Items"))); + dstTree.setModel(new DefaultTreeModel(new DblTreeNode("All Items"))); + } +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AttrObj.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AttrObj.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,318 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + */ + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import java.lang.*; +import java.io.*; +import java.util.*; + +/** + * SMC code adapted for Visual Panels + * + * The AttrObj class implements a generic attribute key/value set. + * The set has a single key name and zero or more string values. + * + */ + +@SuppressWarnings("unchecked") +public class AttrObj extends Object implements Cloneable { + + // Private attributes backstopped by persistent storage + protected Vector vector = null; // Vector of values for key + private String key = null; // keyword for attribute + + /** + * Constructor takes the set key name. + * + * @param keyword A key name + * + */ + public AttrObj(String keyword) { + + super(); + key = keyword; + vector = new Vector(10); + + } + + /** + * Return an array of string values for the set. + * + * @return An array of string values + * + */ + public String [] get() { + + String [] attrArray = new String[vector.size()]; + vector.copyInto(attrArray); + return (attrArray); + + } + + /** + * Return a vector of string values for the set. + * + * @return A vector of string values + * + */ + public Vector getVector() { + + return ((Vector)vector.clone()); + + } + + /** + * Return the first string value in the set. + * + * @return A string value + * + */ + public String getString() { + + return (vector.elementAt(0)); + + } + + /** + * Return true if the set contains the specified key name. + * + * @param key The key name + * @return True if the set contains the key name + * + */ + public boolean contains(String key) { + + return (vector.contains(key)); + + } + + /** + * Return the key name for the set. + * + * @return A key name + * + */ + public String getKey() { + + return (key); + + } + + /** + * Set the specified string value as the values for the set. + * Replaces any existing values. + * + * @param string A string value + * + */ + public void set(String string) { + vector.removeAllElements(); + vector.addElement(string); + } + + /** + * Set the specified string values as the values for the set. + * Replaces any existing values. + * + * @param array An array of string values + * + */ + public void set(String [] array) { + + vector.removeAllElements(); + for (int i = 0; i < array.length; i++) { + vector.addElement(array[i]); + } + + } + + /** + * Set the specified int value as the values for the set. + * Replaces any existing values. + * + * @param value An integer value + * + */ + public void set(int value) { + + vector.removeAllElements(); + vector.addElement(Integer.toString(value)); + + } + + /** + * Set the specified string values as the values for the set. + * Replaces any existing values. + * + * @param newVec A vector of string values + * + */ + public void set(Vector newVec) { + + vector.removeAllElements(); + vector = (Vector) newVec.clone(); + + } + + /** + * Add the specified string value to the set. + * Duplicates are removed. + * + * @param string A string value + * + */ + public void add(String string) { + if (! vector.contains(string)) + vector.addElement(string); + } + + /** + * Add the specified string values to the set. + * Duplicates are removed. + * + * @param array An array of string values + * + */ + public void add(String [] array) { + + for (int i = 0; i < array.length; i++) { + if (! vector.contains(array[i])) + vector.addElement(array[i]); + } + + } + + /** + * Add the specified string values to the set. + * Duplicates are removed. + * + * @param newVec A vector of string values + * + */ + public void add(Vector newVec) { + + Enumeration v1 = newVec.elements(); + while (v1.hasMoreElements()) { + String string = (String) v1.nextElement(); + if (! vector.contains(string)) + vector.addElement(string); + } + + } + + /** + * Remove the specified string value from the set. + * + * @param string A string value + * + */ + public void del(String string) { + + vector.removeElement(string); + + } + + /** + * Remove the specified string values from the set. + * + * @param array An array of string values + * + */ + public void del(String [] array) { + + for (int i = 0; i < array.length; i++) { + vector.removeElement(array[i]); + } + + } + + /** + * Remove the specified string values from the set. + * + * @param oldVec A vector of string values + * + */ + public void del(Vector oldVec) { + + Enumeration v1 = oldVec.elements(); + while (v1.hasMoreElements()) { + String string = (String) v1.nextElement(); + if (vector.contains(string)) + vector.removeElement(string); + } + + } + + /** + * The equals method checks that all attributes of this user + * authorization attributes object equal the corresponding + * attributes of the specified user attributes object. + * If so, true is returned; otherwise, false is returned. + * + * @param userAttr Specified user attr object to be compared + * + * @return true if the specified object is identical + * + */ + public boolean equals(AttrObj newAttrObj) { + + String s1, s2; + + // Number and instances of attributes must be the same + if (vector.size() != newAttrObj.vector.size()) + return (false); + Enumeration v1 = vector.elements(); + Enumeration v2 = newAttrObj.vector.elements(); + + while (v1.hasMoreElements()) { + s1 = (String) v1.nextElement(); + s2 = (String) v2.nextElement(); + if (! s1.equals(s2)) + return (false); + } + // Everything matches, must be equal + return (true); + + } + + /** + * Display the contents of the set to sysout for debugging purposes. + * + */ + public void debugPrint() { + + String strlist = new String(""); + String sep = " "; + if (vector != null) { + Enumeration attrs = vector.elements(); + while (attrs.hasMoreElements()) { + strlist = strlist + sep + (String)attrs.nextElement(); + sep = ", "; + } + } + } + +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthAttrCompare.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthAttrCompare.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,88 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + */ + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + + +import java.util.*; + +/** + * SMC code adapted for Visual Panels + * + * The AuthAttrCompare class implements the Compare interface + * for the QuickSort sorting class. This implementation of compare + * compares two AuthAttrObj objects based upon comparing the + * authorization names in each object. + * + */ + +public class AuthAttrCompare implements Compare { + + /** + * The compare method compares two AuthAttrObj objects by comparing + * their authorization names. The parameters are specified as Object class + * objects for QuickSort. Special handling is required for header entry + * objects so that the headers with fewer name elements precede headers + * with more name elements, when the name elements match. + * + * @param a The first AuthAttrObj object. + * @param b The second AuthAttrObj object. + * + */ + public final int doCompare(Object a, Object b) { + + AuthAttrObj e1, e2; + StringTokenizer e1Tok, e2Tok; + String e1Name, e2Name; + int e1Count, e2Count; + + e1 = (AuthAttrObj)a; + e2 = (AuthAttrObj)b; + e1Name = e1.getAuthName(); + e2Name = e2.getAuthName(); + e1Count = 0; + e2Count = 0; + + // headers must immediately precede their authorizations + if (e1Name.endsWith(".")) + e1Count = 1; + if (e2Name.endsWith(".")) + e2Count = 1; + + // The entries must have the same + // number of components (dots) to be lexically compared + e1Tok = new StringTokenizer(e1Name, ".", true); + e2Tok = new StringTokenizer(e2Name, ".", true); + e1Count += e1Tok.countTokens(); + e2Count += e2Tok.countTokens(); + if (e1Count == e2Count) + return (e1Name.compareTo(e2Name)); + else if (e1Count > e2Count) + return 1; + else + return -1; + } + +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthAttrMgmt.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthAttrMgmt.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,451 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + */ + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + + +import java.lang.*; +import java.util.*; + +/** + * SMC code adapted for Visual Panels + * + * The AuthAttrMgmt class is a User Manager client object that supports + * the data underlying the Authorizations tab dialog panel. This class + * will remotely access the authorizations table for the management scope + * that User Manager is currently executing in, and cache this list in + * the VUserMgr object for this client. If the list has already been + * read (from a previous property dialog instance), that list is reused + * (a refresh will clear the list and cause it to be reread when the + * next instance of this class is created. + *

+ * This object reads the list of authorizations granted to the authenticated + * principal running User Manager. The authorization rights entry for the + * selected target entity in the property dialog is passed to this object + * in its constructor. Since authorizations could be assigned to a user, + * a role, and a profile, the constructor takes an ExtAttrObj instance. + * With the full list of authorizations, the target and authenticated user + * authorization entries, a list of AuthAttrModelEntry objects is created + * and sorted into authorization name order for use in the Authorizations + * tab dialog. When the property dialog completes (the OK button pushed), + * this object will build a new list of authorizations for the selected + * target user to replace the list in the ExtAttrObj instance passed in + * the constructor for the this entity (preserving other key/value + * attributes). + * + */ + +public class AuthAttrMgmt { + + // ======================================================================== + // + // Public static define constants + // + // ======================================================================== + + public static final int ATTRMGMT_USER = 0; + public static final int ATTRMGMT_PROFILE = 1; + + // ======================================================================== + // + // Private class attributes + // + // ======================================================================== + + private UserMgrPanelDescriptor panelDesc = null; + private UserManagedObject userObj = null; + private ExtAttrObj tgt_auth; // Authorizations for target entity + private AuthAttrObj [] auth_list; // List of authorizations + private AuthAttrModelEntry [] auth_entries; // List of auth model entries + private int tgt_type; // Type of target: user or profile + private String tgt_name; // Name of target user, role, profile + + // ======================================================================== + // + // Constructors + // + // ======================================================================== + + /** + * This constructor creates a new authorization management object. It + * accepts the reference to the application instance, the attribute + * authorization object for the user/role/profile, the type of target + * entity (user or profile), and the name of the target entity. + * The target attribute authorization object may be null, indicating + * no previous authorizations exist. + * + * @param theApp Application instance + * @param tgtAttr UserAttrObj or ProfAttrObj for the target entity + * @param tgtType Type of target: user or profile define constant + * @param tgtName Name of target user, role, or profile + * + */ + public AuthAttrMgmt(UserMgrPanelDescriptor panelDesc, + UserManagedObject userObj) { + + // Save stuff + this.panelDesc = panelDesc; + this.userObj = userObj; + + this.auth_list = null; + + } + + // ======================================================================== + // + // Public methods + // + // ======================================================================== + + /** + * The readAuthInfo method reads the full set of authorizations from + * the authorization table in the current management scope and retrieves + * the list of granted authorizations for the authenticated user currently + * running the User Manager tool. This information is retrieved + * from the remote management server by the application Content instance + * and cached there so it can be reused by instances of this object. + * + */ + public void readAuthInfo() { + + // See if we have already gotten the list of authorizations. + // If not, read the list from the application content instance. + if ((auth_list == null) && (panelDesc != null)) { + List auths = panelDesc.getAuths(); + updateAuths(auths); + int authsize = auths.size(); + auth_list = new AuthAttrObj[authsize]; + + for (int i = 0; i < authsize; i++) { + auth_list[i] = new AuthAttrObj(auths.get(i)); + } + } + } + + /** + * Return a list of AuthAttrModelEntry objects for the selected target + * user. Each entry object represents an authorization right or an + * authorization header (if its name ends in a period). Each entry is + * marked as to whether it can be granted or revoked in the tab dialog, + * and whether it is currently granted to the target user. The list + * is returned in sorted order by authorization name, so the rights + * for a particular set are found immediately after the header for the set. + * For those rights without header entries in the authorization attribute + * table, a dummy header entry is created. Header entries are used + * in the setAuthEntries method to condense the auth entries set for the + * target user. + * + * @return An array of authorization model entries in sorted order + * + */ + public AuthAttrModelEntry [] getAuthEntries() { + + AuthAttrModelEntry [] entrylist; + AuthAttrModelEntry entry; + // UserAttrObj tmp_auth; + Vector entries; + String auth_name, hdr_name, str; + int numauths, i, j; + + // See if we have already gotten the list of authorizations + // If not, read the list from the management server and save in views. + if (this.auth_list == null) + this.readAuthInfo(); + + // Sort the list of authorization objects. Need at least two entries + // to require sorting. + if (auth_list.length > 1) { + AuthAttrCompare comp = new AuthAttrCompare(); + Sort.sort(auth_list, comp); + } + + // Create a vector of auth model entry objects, one for each auth + // in the master list. Check if the current admin running the tool has + // the right to grant this right. Check if the target user has this + // right already granted. + // If the auth right prefix changes and the + // next entry is not a header entry, create a dummy header entry for + // the new right (and any subsequent rights with the same prefix). + hdr_name = ""; + numauths = auth_list.length; + entries = new Vector(numauths); + Vector authNames = getUserAuths(); + + AuthAttrModelEntry prev_entry = null; + for (i = 0; i < numauths; i++) { + auth_name = auth_list[i].getAuthName(); + + // Create a new auth model entry object + entry = new AuthAttrModelEntry(auth_list[i]); + + if (hasObject(auth_name)) { + if (hasWildAuth(auth_name) && prev_entry != null) { + prev_entry.setHeader(true); + } + } + prev_entry = entry; + + // Process explicit header entry + // if (auth_name.endsWith(".")) // Cannot grant header + if (entry.isHeader()) { // Cannot grant header + hdr_name = auth_name; + entries.addElement(entry); // Add hdr entry to list + continue; // and skip the rest... + } + + // Check for and process implicit header entry + j = auth_name.lastIndexOf('.'); + if (j > 0) { + str = auth_name.substring(0, (j + 1)); + if (! (str.equals(hdr_name))) { + hdr_name = str; // Add dummy hdr entry + entries.addElement( + new AuthAttrModelEntry(hdr_name, "", "")); + } + } + + // All entries can be granted + entry.setToBeGranted(); + + if ((authNames != null) && (checkAuthName(authNames, auth_name))) + entry.grant(); + entries.addElement(entry); // Add rights entry + + } // End of for loop + + // Turn vector of auth model objects into an array + entrylist = new AuthAttrModelEntry[entries.size()]; + entries.copyInto((Object [])entrylist); + + // Return the list of model entries for presentation + return (entrylist); + + } + + /** + * Update the selected target user list of granted authorizations based + * upon the list of authorization model entries returned from the Rights + * tab dialog. The existing list of authorizations will be deleted and + * a new list constructed. Each authorization model entry which is marked + * granted will be included in the new authorization object. The new + * user authorization attribute object is returned. + *

+ * Additionally, if all rights (except the "grant" + * right) for a common set of rights (all rights with the same prefix) + * are granted, then replace the set with the "*" right with that same + * prefix; e.g., if all rights under "com.sun.usermgr.xxx" are granted, + * set the single right "com.sun.usermgr.*" instead. This will collapse + * the granted rights into fewer entries. Note the com.sun.usermgr.grant + * right is not included in the com.sun.usermgr.* right, so it will be + * set separately. + *

+ * This method assumes it is processing the same auth model entry array + * that was previously returned by the getAuthEntries method; that is, + * the array of entries is in sorted order by auth right name. + * + * @param auth_entries Array of authorization model entry objects + * + * @return The new user authorization attribute object for the targer user + * + */ + public Vector setAuthEntries(AuthAttrModelEntry [] auth_entries) { + + String [] auth_names; + Vector v; + String name; + int i, last_hdr; + boolean sw; + + v = new Vector(); + + + // Walk through the authorization entries. When we encounter a header + // entry and it is granted, we set the "*" right (the entire common + // set of rights with the same prefix are granted) and do not set any + // of the specific rights. The "grant" right is an exception; that is, + // it is included in the granted rights if it is granted independently + // of checking the header entry. + sw = true; + for (i = 0; i < auth_entries.length; i++) { + name = auth_entries[i].getAuthName(); + + // Process header entry + if (auth_entries[i].isHeader()) { + if (auth_entries[i].isGranted()) { + sw = false; + + for (int j = 0; j < i; j++) { + if (auth_entries[j].isGranted()) { + if (auth_entries[i].getAuthName().startsWith( + auth_entries[j].getAuthName())) { + auth_entries[i].revoke(); + break; + } + } + } + if (auth_entries[i].isGranted()) { + if (name.endsWith(AuthAttrObj.SOLARIS_DOT)) { + v.addElement(name.concat(AuthAttrObj.SOLARIS_ALL)); + } else { + v.addElement(name); + } + } + } else { + sw = true; // Test each right + } + continue; + } + + // Process rights entry + if (auth_entries[i].isGranted()) { + if ((sw) || (name.endsWith(AuthAttrObj.SOLARIS_GRANT))) + v.addElement(name); + } + } // End of for loop + + ExtAttrObj new_auth = null; + + // Return the new auth object. + return (v); + + } + + /** + * Check if this user account has been granted the specified + * authorization. + * + * @param An authorization name + * + */ + public boolean checkAuthName(Vector authNames, String authStr) { + + String authname = authStr; + + if (authNames == null) + return (false); + if (authNames.contains(authname)) + return true; + + // try to find a wildcard match further up the tree + StringTokenizer tk = new StringTokenizer(authname, + AuthAttrObj.SOLARIS_DOT); + String matchType; + int tokCount = tk.countTokens() -1; + if (tokCount < 1) { + // not enough tokens; invalid authname? + return false; + } + + // Grant authorization does not match against "All" + // However, grant does match another grant further up the tree + if (authname.endsWith("." + AuthAttrObj.SOLARIS_GRANT)) + matchType = AuthAttrObj.SOLARIS_GRANT; + else + matchType = AuthAttrObj.SOLARIS_ALL; + + // walk the tree from the root, looking for implicit matches + String authPath = ""; + for (int i = 0; i < tokCount; i++) { + authPath = authPath.concat((String)tk.nextElement() + + AuthAttrObj.SOLARIS_DOT); + if (authNames.contains(authPath.concat(matchType))) + return true; + } + return false; + + } + + private Vector getUserAuths() { + String auths = userObj.getAuths(); + Vector userAuths = null; + + if (auths != null) { + String[] authList = userObj.getAuths().split(","); + userAuths = new Vector(authList.length); + for (String auth : authList) { + userAuths.add(auth); + } + } + + return (userAuths); + } + + private void updateAuths(List auths) { + Vector uAuths = getUserAuths(); + if (uAuths == null || uAuths.size() == 0) { + return; + } + + + for (String uAuth : uAuths) { + int idx = uAuth.indexOf(AuthAttrObj.SOLARIS_SLASH); + + if (idx == -1) { + continue; // doesn't contain object name + } + // Contains object name + String authStr = uAuth.substring(0, idx); + + for (int j = 0; j < auths.size(); j++) { + String auth = auths.get(j); + if (auth.equals(authStr)) { + String nextauth = auths.get(j+1); + String wildAuth = getWildAuth(authStr); + + if (nextauth.equals(wildAuth) == false) { + auths.add(j+1, wildAuth); + } + auths.add(j+2, uAuth); + } + } + } + } + + /* + * Translate the authname to authname + */ + private String getWildAuth(String auth) { + return (auth + AuthAttrObj.SOLARIS_SLASH + AuthAttrObj.SOLARIS_ALL); + } + + /** + * Check if the authname has the wildcard '*' + */ + private boolean hasWildAuth(String auth) { + return (auth.endsWith(AuthAttrObj.SOLARIS_SLASH + + AuthAttrObj.SOLARIS_ALL)); + } + + /** + * Check if the authname is in the form: auth/ + */ + private boolean hasObject(String auth) { + if (auth.indexOf(AuthAttrObj.SOLARIS_SLASH) == -1) { + return (false); + } else { + return (true); + } + } +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthAttrModelEntry.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthAttrModelEntry.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,323 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + */ + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import java.lang.*; + + +/** + * SMC code adapted for Visual Panels + * + * The AuthAttrModelEntry class encapsulates a single authorization right + * header entry or grantable right entry. This class is used to present + * the authorization rights in the User Manager Authorizations tab dialog. + * An array of instances of this class represent all the authorization rights + * in the management scope currently selected for User Manager. + *

+ * The instance contains the name of the authorization right or header, + * a short description of the right used in the presentation, a reference + * to a help file or localization resource property file and message id + * used to present a detailed explanation of the right or set of rights, + * a boolean grant attribute, and a boolean check attribute. + * If the grant attribute is true, the authorization can be granted to the + * selected user; that is, it can be selected in the presentation and checked + * or unchecked. If the check attribute is true, the user already has this + * authorization granted to them. + * + */ + +public class AuthAttrModelEntry { + + // ======================================================================== + // + // Private class attributes + // + // ======================================================================== + + private String name; // Authorization name + private String desc; // Authorization short description + private String help; // Authorization help file or message id + private boolean grant; // True if right can be granted + private boolean check; // True if right has been granted + private boolean header; // True if is a header + private boolean visible = true; // True is visible + + // ======================================================================== + // + // Constructors + // + // ======================================================================== + + /** + * This constructor creates a new authorization right model entry object + * from an AuthAttrObj object. + * + * @param authAttr The AuthAttrObj source object. + * + */ + public AuthAttrModelEntry(AuthAttrObj authAttr) { + + this.name = authAttr.getAuthName(); + this.desc = authAttr.getShortDesc(); + this.help = authAttr.getLongDescId(); + this.grant = false; + this.check = false; + this.header = hasHeader(); + } + + /** + * This constructor creates a new authorization right model entry object + * from its parameters. + * + * @param authName The authorization name. + * @param authDesc The authorization short description. + * @param authHelp The authorization help file or long message file+id + * + */ + public AuthAttrModelEntry(String authName, String authDesc, + String authHelp) { + + this.name = authName; + this.desc = authDesc; + this.help = authHelp; + this.grant = false; + this.check = false; + this.header = hasHeader(); + + } + // ======================================================================== + // + // Public methods + // + // ======================================================================== + + /** + * Return the authorizatino name. If the name ends with a period, it is + * an authorization set header name; otherwise, it is an authorization + * grantable right name. + * + * @return The name of the authorization + * + */ + public String getAuthName() { + + return (this.name); + + } + + /** + * Return the authorization name. + * + * @return The authorization name + * + */ + public String getName() { + + int i = name.indexOf(AuthAttrObj.SOLARIS_SLASH); + String nameStr; + + if (i >= 0) { + nameStr = name.substring(i+1); + if (nameStr.equals(AuthAttrObj.SOLARIS_ALL)) { + nameStr = "All"; + } + } else { + nameStr = name; + } + return (nameStr); + + } + + /** + * Return the short description of the authorization. This description + * is used in the presentation of the authorization in the User Manager + * Rights tab dialog. + * + * @return The short description of the authorization + * + */ + public String getDesc() { + + return (this.desc); + + } + + /** + * Return the help file name or long description file name and message + * identifier for the authorization. If the value returned ends in + * "html" or "htm", it is a help file relative path name. Add the + * path name to the management installation base directory path to get + * the full path to the help file, then generate a "file" URL from this + * path for HTML help file renderers. If the value contains a "+" + * character, it is a long message file relative path name and messaged + * identifier combination. Add the relative path to the installation + * base directory to get the full path name to the resource bundle + * property file. Use the string after the plus sign as the message + * key in that resource file. + * + * @return The help description file name URL or file name and message id + * + */ + public String getHelp() { + + return (this.help); + + } + + /** + * Determines if this authorization is a special authorization header entry. + * + * @return True if this authorization entry is for a header entry. + * + */ + public boolean isHeader() { + + return (header); + + } + + /** + * Determines if this authorization is a special authorization header entry. + * + * @return True if this authorization entry is for a header entry. + * + */ + public boolean hasHeader() { + + return (name.endsWith(AuthAttrObj.SOLARIS_DOT)); + + } + + /** + * Determines if this authorization is a special authorization header entry. + * + * @return True if this authorization entry is for a header entry. + * + */ + public void setHeader(boolean val) { + header = val; + } + + /** + * Determines if this authorization can be granted by the administrator + * currently running the User Manager tool. If the administrator can + * grant this authorization right to the selected user, a true value + * is returned. If the authorization is a header or cannot be granted, + * a false value is returned. + * + * @return True if the authorization can be granted + * + */ + public boolean canBeGranted() { + + return (this.grant); + + } + + /** + * Determines if this authorization is currently granted to the selected + * target user in the User Manager tool. If the user has this authorization + * right, a true value is returned; otherwise, a false value is returned. + * + * @return True if the user is granted this authorization right + * + */ + public boolean isGranted() { + + return (this.check); + + } + + /** + * Grant the authorization right to the selected target user in the + * User Manager tool. The caller should first test if the authorization + * is grantable by calling the canBeGranted method. + * + */ + public void grant() { + + this.check = true; + + } + + /** + * Revoke the authorization right for the selected target user in the + * User Manager tool. The caller should first test if the authorization + * is revokable by calling the canBeGranted method. The administrator + * must be capable of granting the right in order to revoke it. + * + */ + public void revoke() { + + this.check = false; + + } + + /** + * Set the ability to grant or revoke the authorization right. + * The administrator running the User Manager tool must have the grant + * right controlling this authorization. + * + */ + public void setToBeGranted() { + + this.grant = true; + + } + + public boolean hasObject() { + if (name.indexOf(AuthAttrObj.SOLARIS_SLASH) == -1) { + return (false); + } else { + return (true); + } + } + + /** + * Set the long descriptions for the authorization. + * Any existing log descriptions are replaced. + * + * @param An array of long descriptions + * + */ + public boolean isVisible() { + + return (visible); + } + + /** + * Set the long descriptions for the authorization. + * Any existing log descriptions are replaced. + * + * @param An array of long descriptions + * + */ + public void setVisible(boolean visibility) { + + visible = visibility; + } + +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthAttrObj.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthAttrObj.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,455 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + */ + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import java.lang.*; +import java.io.*; +import java.util.*; + +/** + * SMC code adapted for Visual Panels + * + * Description: + * The AuthAttrObj class encapsulates the set of authorizations currently + * set for the specified user. + * + * @return none. + */ + +public class AuthAttrObj extends ExtAttrObj implements Cloneable { + + // Private attributes back stopped by persistent storage + private String authName = null; // The authorization name + private String [] shortDesc = null; // Short description (32 chars) + private String [] longDesc = null; // Long description, not localized + private boolean visible = true; + + // The following is the list of attribute keys that are supported. + + public static final String SOLARIS_AUTH_HELP = "help"; + public static final String SOLARIS_ALL = "*"; + public static final String SOLARIS_DOT = "."; + public static final String SOLARIS_GRANT = "grant"; + public static final String SOLARIS_SLASH = "/"; + + + /** + * Null constructor. + * + */ + public AuthAttrObj() { + + super(); + + } + + /** + * This constructor takes the authorization name. + * + */ + public AuthAttrObj(String authName) { + + super(); + this.authName = authName; + + } + + + // Public methods + + /** + * Return a copy of this object. + * + * @return A new copy of this object + * + */ + public Object clone() { + + AuthAttrObj newobj = new AuthAttrObj(this.authName); + newobj.setShortDesc(this.shortDesc); + newobj.setLongDesc(this.longDesc); + + super.clone(newobj); + return (newobj); + + } + + /** + * Check if this instance matches another AuthAttrObj instance. + * The other instance matches this instance if it has the + * same authorization name. + * + * @param otherAttr The other AuthAttrObj instance + * + * @returnTrue if the other instance matches this one + * + */ + public boolean matches(AuthAttrObj otherAttr) { + + boolean bool = false; + try { + if (this.authName.equals(otherAttr.getAuthName())) + bool = true; + } catch (Exception ex) { + } + return (bool); + + } + + /** + * Return the authorization name. + * + * @return The authorization name + * + */ + public String getAuthName() { + + return (this.authName); + + } + + /** + * Return the authorization name. + * + * @return The authorization name + * + */ + public String getName() { + + int i = authName.indexOf(SOLARIS_SLASH); + String nameStr; + + if (i >= 0) { + nameStr = authName.substring(i+1); + if (nameStr.equals(SOLARIS_ALL)) { + nameStr = "All"; + } + } else { + nameStr = authName; + } + + return (nameStr); + + } + + /** + * Set the authorization name. + * + * @param The authorization name + * + */ + public void setAuthName(String authName) { + + this.authName = authName; + + } + + /** + * Return a copy of this object. + * + * @return A new copy of this object + * + */ + public String getShortDesc() { + + if (this.shortDesc == null) + return (null); + else + return (this.shortDesc[0]); + + } + + /** + * Return an array of short descriptions for the authorization. + * + * @return An array of short descriptions + * + */ + public String [] getShortDescs() { + + if (this.shortDesc == null) + return (null); + else + return (this.shortDesc); + + } + + /** + * Set the short description for this authorizations. + * Any existing descriptions are replaced. + * + * @param The short description + * + */ + public void setShortDesc(String shortDesc) { + + if (this.shortDesc == null) + this.shortDesc = new String [1]; + this.shortDesc[0] = shortDesc; + + } + + /** + * Set an array of short descriptions for the authorization. + * Any existing descriptions are replaced. + * + * @param The authorization name + * + */ + public void setShortDesc(String [] shortDesc) { + + this.shortDesc = shortDesc; + + } + + /** + * Return a localized short description. + * + * @return A localized short description + * + */ + public String getShortDesc(Locale locale) { + + if (this.shortDesc == null) + return null; + else + return (this.shortDesc[0]); + + } + + /** + * Return the relative pathname of the authorization help file + * on the management server. + * + * @return A help file pathname + * + */ + public String getHelpFileName() { + + Vector v = this.getAttribute(SOLARIS_AUTH_HELP); + if ((v != null) && (v.size() > 0)) + return ((String) v.elementAt(0)); + else + return (null); + } + + /** + * Set the relative pathname of the authorization help file + * on the management server. Any existing help file pathnames + * are replaced. + * + * @param A help file pathname + * + */ + public void setHelpFileName(String helpFile) { + + this.setAttribute(SOLARIS_AUTH_HELP, helpFile); + + } + + /** + /** + * Return the relative pathname of the authorization help file + * on the management server. + /** + * Return the relative pathname of the authorization help file + * on the management server. + * + * @return A help file pathname + * + */ + public String getLongDescId() { + + Vector v = this.getAttribute(SOLARIS_AUTH_HELP); + if ((v != null) && (v.size() > 0)) + return ((String) v.elementAt(0)); + else + return (null); + } + + /** + * Return the relative pathnames of the authorization help files + * on the management server. + * + * @return An array of help file pathnames + * + * + */ + public String [] getLongDescIds() { + + return (this.getAttributeArray(SOLARIS_AUTH_HELP)); + + } + + /** + * Return the relative pathnames of the authorization help files + * on the management server. + * + * @return A vector of help file pathnames + * + */ + public Vector getLongDescIdsVector() { + + return (this.getAttribute(SOLARIS_AUTH_HELP)); + + } + + /** + * Set the relative pathname of the authorization help file + * on the management server. Any existing help file pathnames + * are replaced. + * + * @param A help file pathname + * + */ + public void setLongDescId(String longDescHelp) { + + this.setAttribute(SOLARIS_AUTH_HELP, longDescHelp); + + } + + /** + * Set the relative pathnames of the authorization help files + * on the management server. Any existing help file pathnames + * are replaced. + * + * @param An array of help file pathnames + * + */ + public void setLongDescId(String [] longDescIdArray) { + + this.setAttribute(SOLARIS_AUTH_HELP, longDescIdArray); + + } + + /** + * Set the relative pathnames of the authorization help files + * on the management server. Any existing help file pathnames + * are replaced. + * + * @param A vector of help file pathnames + * + */ + public void setLongDescIdVector(Vector names) { + + this.setAttribute(SOLARIS_AUTH_HELP, names); + + } + + /** + * Return a long description for the authorization. + * + * @return A long description + * + */ + public String getLongDesc() { + + if (this.longDesc == null) + return null; + else + return (this.longDesc[0]); + + } + + /** + * Return an array of long descriptions for the authorization. + * + * @return An array of long descriptions + * + */ + public String [] getLongDescs() { + + if (this.longDesc == null) + return null; + else + return (this.longDesc); + + } + + /** + * Return a localized long description for the authorization. + * + * @return A localized long description + * + */ + public String getLongDesc(Locale locale) { + + if (this.longDesc == null) + return null; + else + return (this.longDesc[0]); + + } + + /** + * @param A long description + * + */ + public void setLongDesc(String longDesc) { + + if (this.longDesc == null) + this.longDesc = new String[1]; + this.longDesc[0] = longDesc; + + } + + /** + * Set the long descriptions for the authorization. + * Any existing log descriptions are replaced. + * + * @param An array of long descriptions + * + */ + public void setLongDesc(String [] longDesc) { + + this.longDesc = longDesc; + + } + + /** + * Set the long descriptions for the authorization. + * Any existing log descriptions are replaced. + * + * @param An array of long descriptions + * + */ + public boolean isVisible() { + + return (visible); + } + + /** + * Set the long descriptions for the authorization. + * Any existing log descriptions are replaced. + * + * @param An array of long descriptions + * + */ + public void setVisible(boolean visibility) { + + visible = visibility; + } +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthsPanel.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthsPanel.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,414 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + */ + + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.text.*; +import javax.swing.border.*; +import javax.swing.tree.*; + +import java.util.List; +import java.util.*; +import java.io.*; +import java.net.*; + +import java.awt.*; +import java.awt.event.*; + +import com.oracle.solaris.vp.util.misc.finder.Finder; + +/** + * SMC code adapted for Visual Panels + * + * Authorization Settings Panel + */ + +public class AuthsPanel extends JPanel { + + private UserManagedObject userObj = null; + private UserMgrPanelDescriptor panelDesc = null; + + private AuthAttrMgmt authAttrMgmt; + private AuthAttrModelEntry[] authArr; + private DblTreeNode root; + + public static SelPanel authPanel; + private DblTreeNode [] authNode; + + private boolean isNew; + private boolean viewNames = false; + + /** + * Constructs a panel to contain authorizations properties for the + * right object. + * + */ + public AuthsPanel(UserMgrPanelDescriptor panelDesc, + UserManagedObject userObj) { + super(); + this.panelDesc = panelDesc; + this.userObj = userObj; + isNew = userObj.isNewUser(); + + createGui(); + loadAuths(); + + } // constructor + + /** + * Method for creating GUI + */ + private void createGui() { + + // set the panel layout + GridBagLayout gridbag = new GridBagLayout(); + GridBagConstraints gbc = new GridBagConstraints(); + this.setLayout(gridbag); + + authPanel = new SelPanel("usermgr.advanced.auths.available", + "usermgr.advanced.auths.granted"); + + authPanel.srcTree.setCellRenderer(new AuthRenderer(this)); + authPanel.dstTree.setCellRenderer(new AuthRenderer(this)); + + Constraints.constrain(this, authPanel, + 0, 0, 1, 1, gbc.BOTH, gbc.CENTER, 1.0, 1, 10, 10, 10, 10); + } // end createGui + + public void loadUserAuths() { + authPanel.resetAll(); + + if (isNew == false) { + authAttrMgmt = new AuthAttrMgmt(panelDesc, userObj); + authArr = authAttrMgmt.getAuthEntries(); + setAuthArr(authArr); + } + + if (authArr == null) { + return; + } + + + // At this point, everything is in the left tree, with + // all of the branches collaped. + + for (int i = 0; i < authArr.length; i++) { + if (authArr[i].isHeader()) { + + // Expand all the headers + + TreePath nodepath = new TreePath(authNode[i].getPath()); + authPanel.srcTree.expandPath(nodepath); + } else { + + // Move all the granted auths leaves to the right + if (isNew == false && authArr[i].isGranted()) { + authPanel.initLeaf(authPanel.srcTree, authPanel.dstTree, + authNode[i]); + } + } + } + + authPanel.srcTree.setRootVisible(false); + authPanel.setInitSelection(); + } + + /** + * Load the Source and Destination trees for authorizations excluded and + * included lists. + */ + private void loadAuths() { + + // Reset the data models. So old data is discarded + authPanel.resetModels(); + + DefaultTreeModel srcModel = + (DefaultTreeModel)authPanel.srcTree.getModel(); + root = (DblTreeNode)srcModel.getRoot(); + int topCount = 0; + int headerCount = 0; + + // First time through use a dummy profile + authAttrMgmt = new AuthAttrMgmt(panelDesc, userObj); + + authArr = authAttrMgmt.getAuthEntries(); + + int [] headerList = new int[authArr.length]; + authNode = new DblTreeNode[authArr.length]; + + for (int i = 0; i < authArr.length; i++) { + AuthTreeNode authObject = new AuthTreeNode(authArr[i], i); + authNode[i] = new DblTreeNode((Object)authObject); + + String nodeName = authArr[i].getAuthName(); + if (authArr[i].isHeader()) { + // Add subheaders to headers + + boolean foundHeader = false; + int headerIndex = 0; + + for (int j = 0; j < headerCount; j++) { + int k = headerList[j]; + AuthTreeNode headerNode = + (AuthTreeNode)authNode[k].getUserObject(); + String headerName = headerNode.toString(); + if (nodeName.startsWith(headerName)) { + foundHeader = true; + headerIndex = k; + // loop for closest match + } + } + + if (foundHeader) { + authNode[headerIndex].add(authNode[i]); + } else { + srcModel.insertNodeInto(authNode[i], root, topCount++); + TreePath nodepath = new TreePath(authNode[i].getPath()); + authPanel.srcTree.scrollPathToVisible(nodepath); + } + // add header to header list + headerList[headerCount++] = i; + + } else { // Add the leaves to the headers + + // Set auth's treenode disabled to + // indicate the auth "can not be granted" to another user + // (No auths leaves could ever have child nodes) + + if (authArr[i].canBeGranted() == false) { + authNode[i].setEnabled(false); + } + if (headerCount > 0) { + for (int j = headerCount - 1; j >= 0; j--) { + AuthTreeNode headerNode = (AuthTreeNode) + authNode[headerList[j]].getUserObject(); + String headerName = headerNode.toString(); + if (nodeName.startsWith(headerName)) { + authNode[headerList[j]].add(authNode[i]); + break; + } + } + } else { + srcModel.insertNodeInto(authNode[i], root, topCount++); + } + } + } + + loadUserAuths(); + + } // end loadAuths + + + public void setAuthArr(AuthAttrModelEntry[] arr) { + authArr = arr; + } + + public AuthAttrModelEntry[] getAuthArr() { + return authArr; + } + + public boolean getViewNames() { + return viewNames; + } + + + public void getChecks() { + + AuthAttrModelEntry[] authEntryArr = getAuthArr(); + + if (authNode == null) { + return; + } + + for (int i = 0; i < authNode.length; i++) { + if (authEntryArr[i].isHeader()) { + authEntryArr[i].grant(); + continue; + } + + // root is in the excluded tree. + if (authNode[i].getRoot().equals(root)) + authEntryArr[i].revoke(); + else + authEntryArr[i].grant(); + } + + DblTreeNode node; + Enumeration inclAuths = root.depthFirstEnumeration(); + while (inclAuths.hasMoreElements()) { + node = (DblTreeNode)inclAuths.nextElement(); + if (node.isRoot()) + continue; + + AuthTreeNode authtreenode = (AuthTreeNode)node.getUserObject(); + int i = authtreenode.getSubscript(); + if (authEntryArr[i].isHeader()) + authEntryArr[i].revoke(); + } + + setAuthArr(authEntryArr); + + } // end getChecks + + /** + * Get the authorizations assigned to the selected user/role. + */ + public Vector getAssignedAuths() { + getChecks(); + Vector vAuths = authAttrMgmt.setAuthEntries(getAuthArr()); + + return vAuths; + } + + /** + * Get a list of available authorizations that can be assigned + * to selected user/role. + */ + private String[] getAvailableAuths() { + List auths = panelDesc.getAuths(); + int authsize = auths.size(); + String[] authList = new String[authsize]; + + for (int i = 0; i < authsize; i++) { + authList[i] = auths.get(i); + } + return (authList); + } + + /** + * Refresh authorizations for the new user. + */ + public void setUser(UserManagedObject userObj) { + this.userObj = userObj; + loadAuths(); + } + + public UserManagedObject updateUser() { + Vector vAuths = getAssignedAuths(); + String authStr; + + if (vAuths.size() > 0) { + authStr = vAuths.elementAt(0); + } else { + authStr = ""; + } + + for (int i = 1; i < vAuths.size(); i++) { + authStr = authStr.concat(","); + authStr = authStr.concat(vAuths.elementAt(i)); + } + + userObj.getAuthsProperty().setValue(authStr); + + return (userObj); + } + +} // end AuthsPanel + +class AuthTreeNode { + + String name = null; + AuthAttrModelEntry authModel = null; + boolean enabled = true; + int subscript; + + public AuthTreeNode(AuthAttrModelEntry authModel, int subscript) { + name = authModel.getName(); + enabled = authModel.canBeGranted(); + this.authModel = authModel; + this.subscript = subscript; + } + + public String getDesc() { + return authModel.getDesc(); + } + + public String toString() { + return name; + } + + public AuthAttrModelEntry getAuthModel() { + return authModel; + } + + public boolean isEnabled() { + return enabled; + } + + public int getSubscript() { + return this.subscript; + } + +} + +class AuthRenderer extends DefaultTreeCellRenderer { + + private boolean selected; + static AuthsPanel authsPanel; + + public AuthRenderer(AuthsPanel authsPanel) { + this.authsPanel = authsPanel; + setClosedIcon(null); + setOpenIcon(null); + } + + public Component getTreeCellRendererComponent( + JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + + AuthTreeNode authdef = null; + FocusEvent e = null; + + this.selected = selected; + + DefaultTreeCellRenderer cr = + (DefaultTreeCellRenderer)tree.getCellRenderer(); + + DblTreeNode node = (DblTreeNode)value; + // authdef = (AuthTreeNode)node.getUserObject(); + + if (node.getParent() == null) { + setText("All Authorizations"); + } else if (node.getUserObject() instanceof AuthTreeNode) { + authdef = (AuthTreeNode)node.getUserObject(); + setText(authdef.toString()); + + } + + super.getTreeCellRendererComponent(tree, value, + selected, expanded, leaf, row, hasFocus); + + return this; + + } +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthsSettings.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/AuthsSettings.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,79 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + */ + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import javax.swing.*; +import com.oracle.solaris.vp.util.misc.finder.Finder; + + +/** + * Implements Authorization Settings in the Advanced + * Settings + */ +public class AuthsSettings extends AdvancedSettings { + + private static final String NAME = + Finder.getString("usermgr.advanced.auths"); + private static final Icon ICON = Finder.getIcon( + "images/user-24.png"); + + private UserMgrPanelDescriptor panelDesc = null; + private UserManagedObject userObj = null; + private AuthsPanel panel = null; + + public AuthsSettings() { + super(NAME, ICON); + } + + public void setUser(UserManagedObject userObj) { + if (panel == null) { + panel = new AuthsPanel(panelDesc, userObj); + } + panel.setUser(userObj); + getProperty().update(userObj.getAuths(), false); + } + + public void updateUser() { + userObj = panel.updateUser(); + getProperty().setValue(userObj.getAuths()); + } + + public boolean isChanged() { + if (userObj != null) { + return (userObj.getAuthsProperty().isChanged()); + } else { + return false; + } + } + + public void init(UserMgrPanelDescriptor panelDesc) { + this.panelDesc = panelDesc; + } + + public JPanel getPanel() { + return panel; + } +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/Compare.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/Compare.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,47 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + */ + + +/** + * SMC code adapted for Visual Panels + * + * Compare: an interface to enable users to define the result of + * a comparison of two objects. + */ + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +public interface Compare { + + /** + * doCompare + * + * @param obj1 first object to compare. + * @param obj2 second object to compare. + * @return -1 if obj1 < obj2, 0 if obj1 == obj2, 1 if obj1 > obj2. + */ + public int doCompare(Object obj1, Object obj2); + +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/Constraints.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/Constraints.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,121 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + */ + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import java.applet.*; +import java.awt.*; +import java.lang.*; + + +/** + * SMC code adapted for Visual Panels + * + * A general utility class to make it easy to apply GridBagConstraints + * to GridBagLayout. + * Code lifted from "Java in a Nutshell", O'Reilly & Associated, Inc. + * and wrapped in a final class. + */ +public final class Constraints { + + /** + * This is the main constrain() method. It has arguments for + * all constraints. + */ + public static void constrain( + Container container, + Component component, + int gridx, + int gridy, + int gridwidth, + int gridheight, + int fill, + int anchor, + double weightx, + double weighty, + int top, + int left, + int bottom, + int right) + { + GridBagConstraints gbc = new GridBagConstraints(); + gbc.gridx = gridx; + gbc.gridy = gridy; + gbc.gridwidth = gridwidth; + gbc.gridheight = gridheight; + gbc.fill = fill; + gbc.anchor = anchor; + gbc.weightx = weightx; + gbc.weighty = weighty; + + if (top+bottom+left+right > 0) + gbc.insets = new Insets(top, left, bottom, right); + + ((GridBagLayout)container.getLayout()).setConstraints(component, gbc); + container.add(component); + } + + + /** + * This version of constrain() specifies the position of a component + * that does not grow and does not have margins. + */ + public static void constrain( + Container container, + Component component, + int gridx, + int gridy, + int gridwidth, + int gridheight) + { + constrain(container, component, + gridx, gridy, gridwidth, gridheight, + GridBagConstraints.NONE, GridBagConstraints.NORTHWEST, + 0.0, 0.0, 0, 0, 0, 0); + } + + + /** + * This version of constrain() specifies the position of a component + * that does not grow but does have margins. + */ + public static void constrain( + Container container, + Component component, + int gridx, + int gridy, + int gridwidth, + int gridheight, + int top, + int left, + int bottom, + int right) + { + constrain(container, component, + gridx, gridy, gridwidth, gridheight, + GridBagConstraints.NONE, GridBagConstraints.NORTHWEST, + 0.0, 0.0, top, left, bottom, right); + } +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/DblTreeNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/DblTreeNode.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,130 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + */ + + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import javax.swing.*; +import javax.swing.tree.*; + +/** + * SMC code adapted for Visual Panels + */ +public class DblTreeNode extends DefaultMutableTreeNode implements Comparable { + + boolean enabled = true; + boolean cyclic = false; + boolean conflict = false; + + /** + * The comparableObject is used when comparing two + * DblTreeNode objects. By default the String + * representation (toString()) is used when comparing + * DblTreeNode objects. This may not always give the + * desired ordering when displaying nodes in a list. To overcome this + * when the comparableObject is not null + * the String representation of the + * comparableObject is used. This could be as simple as an + * Integer. + */ + private Object comparableObject; + + public DblTreeNode() { + super(); + } + + public DblTreeNode(Object object) { + super(object); + } + + public DblTreeNode(String string) { + super(string); + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean flag) { + enabled = flag; + } + + public boolean isCyclic() { + return cyclic; + } + + public void setCyclic(boolean flag) { + cyclic = flag; + } + + public boolean isConflict() { + return conflict; + } + + public void setConflict(boolean flag) { + conflict = flag; + } + + /** + * Set the comparableObject which will be used by + * the compareTo() method. Use null to + * use this object (default). + * + * @param comparableObject + * Object used by compareTo() + */ + public void setComparableObject(Object comparableObject) { + this.comparableObject = comparableObject; + } + + /** + * Get the comparableObject which will be used by + * the compareTo() method. This method never returns + * null. If the comparableObject is set to + * null by setComparableObject(null) this + * method returns this. + * + * @return + * Object used by compareTo() + */ + public Object getComparableObject() { + if (comparableObject == null) { + return this; + } else { + return comparableObject; + } + } + + public int compareTo(Object object) { + String string = getComparableObject().toString(); + + if (object instanceof DblTreeNode) { + DblTreeNode other = (DblTreeNode) object; + return string.compareTo(other.getComparableObject().toString()); + } else { + return string.compareTo(object.toString()); + } + } +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/DeleteUserAction.java --- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/DeleteUserAction.java Thu Apr 26 00:14:30 2012 -0400 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/DeleteUserAction.java Fri Apr 27 00:52:26 2012 -0400 @@ -25,15 +25,22 @@ package com.oracle.solaris.vp.panels.usermgr.client.swing; +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; import java.util.List; import javax.swing.JOptionPane; import com.oracle.solaris.vp.panel.common.action.*; import com.oracle.solaris.vp.panel.common.control.Control; import com.oracle.solaris.vp.panel.swing.action.DeleteManagedObjectAction; import com.oracle.solaris.vp.panel.swing.control.SwingControl; +import com.oracle.solaris.vp.util.misc.*; import com.oracle.solaris.vp.util.misc.finder.Finder; import com.oracle.solaris.vp.util.swing.GUIUtil; +/** + * Delete a user or role + */ @SuppressWarnings({"serial"}) public class DeleteUserAction extends DeleteManagedObjectAction > { @@ -57,6 +64,10 @@ public DeleteUserAction(SwingControl control) { super(DELETE_TEXT, null, control); + ActionString actStr = new ActionString( + "usermgr.action.delete.button"); + putValue(Action.NAME, actStr.getString()); + putValue(Action.MNEMONIC_KEY, actStr.getMnemonic()); this.control = control; } @@ -71,17 +82,24 @@ if (selection.isEmpty()) { throw new ActionAbortedException(); } + UserMgrPanelDescriptor descriptor = (UserMgrPanelDescriptor) + control.getPanelDescriptor(); - String message = Finder.getString("usermgr.action.delete.confirm", - selection.get(0).getName()); + String message = Finder.getString("usermgr.action.delete.confirm." + + descriptor.getTypeString(), selection.get(0).getName()); - int response = GUIUtil.showConfirmation( - getHasComponent().getComponent(), null, message, - JOptionPane.YES_NO_OPTION); + JOptionPane pane = new JOptionPane(message, + JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION); + UserMgrUtils.removeIcons(pane); + JDialog dialog = pane.createDialog(getHasComponent().getComponent(), + Finder.getString("usermgr.action.delete.title." + + descriptor.getTypeString())); - if (response != JOptionPane.YES_OPTION) { + dialog.setVisible(true); + + if (!ObjectUtil.equals(pane.getValue(), JOptionPane.OK_OPTION)) { throw new ActionAbortedException(); - } + } return null; } @@ -98,13 +116,14 @@ if (!selection.isEmpty()) { UserMgrPanelDescriptor descriptor = (UserMgrPanelDescriptor) control.getPanelDescriptor(); - descriptor.deleteUserManagedObject(selection.get(0)); + descriptor.addToDeleteList(selection.get(0)); + descriptor.saveDeletedUsers(); // If the running Control is a UserMgrControl for a just-deleted // service, reset the Control and navigate back to its parent Control child = control.getRunningChild(); - if (child instanceof UserMgrControl) { + if (child instanceof UserMgrBasicControl) { UserManagedObject umo = - ((UserMgrControl)child).getUserManagedObject(); + ((UserMgrBasicControl)child).getUserManagedObject(); if (selection.contains(umo)) { child.doCancel(); diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/DoubleTrees.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/DoubleTrees.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,282 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + */ + + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.text.*; +import javax.swing.border.*; +import javax.swing.tree.*; + +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import java.io.*; +import com.oracle.solaris.vp.util.misc.finder.Finder; + + +/** + * SMC code adapted for Visual Panels + * + * DoubleTrees class implements an excluded and included tree + */ +public class DoubleTrees extends JPanel { + + public final static Border emptyBorder10 = new EmptyBorder(10, 10, 10, 10); + + public JTree srcTree; + public JTree dstTree; + public JButton addItem; + public JButton delItem; + public JButton addAllItem; + public JButton delAllItem; + + public JPanel selPanel = this; + + /** + * Constructor. + */ + public DoubleTrees() { + String srcHeader = "excluded_tree_header"; + String dstHeader = "included_tree_header"; + + makePanel(srcHeader, dstHeader); + } + + + public DoubleTrees(String srcHeader, String dstHeader) { + makePanel(srcHeader, dstHeader); + } + + private void makePanel(JPanel panel, String srcHeader, String dstHeader) { + DoubleTreesLayout layout = new DoubleTreesLayout(); + panel.setLayout(layout); + + DoubleTreesConstraints constraints = new DoubleTreesConstraints(); + + // src label + + JLabel srcLabel = new JLabel(); + setUpLabel(srcLabel, srcHeader); + + constraints.location = constraints.LEFT_LABEL; + constraints.insets = new Insets(5, 5, 5, 5); + + layout.setConstraints(srcLabel, constraints); + panel.add(srcLabel); + + // src tree + + JScrollPane srcScroll = newTree(); + srcTree = (JTree) srcScroll.getViewport().getView(); + + constraints.location = constraints.LEFT_SCROLLPANE; + constraints.insets = new Insets(5, 5, 5, 5); + + layout.setConstraints(srcScroll, constraints); + panel.add(srcScroll); + + srcLabel.setLabelFor(srcTree); + + // buttons + + JPanel buttonPanel = new JPanel(); + + Component spacer1 = Box.createVerticalStrut(5); + Component spacer2 = Box.createVerticalStrut(25); + Component spacer3 = Box.createVerticalStrut(5); + + GridBagLayout buttonLayout = new GridBagLayout(); + GridBagConstraints buttonConstraints = new GridBagConstraints(); + + buttonPanel.setLayout(buttonLayout); + + addItem = new JButton(); + addItem.setEnabled(false); + setUpButton(addItem, "usermgr.advanced.add_btn"); + + delItem = new JButton(); + delItem.setEnabled(false); + setUpButton(delItem, "usermgr.advanced.remove_btn"); + + addAllItem = new JButton(); + setUpButton(addAllItem, "usermgr.advanced.add_all_btn"); + + delAllItem = new JButton(); + setUpButton(delAllItem, "usermgr.advanced.remove_all_btn"); + + buttonConstraints.gridx = 0; + buttonConstraints.gridy = buttonConstraints.RELATIVE; + buttonConstraints.gridwidth = 1; + buttonConstraints.gridheight = 1; + buttonConstraints.weightx = 0.0; + buttonConstraints.weighty = 0.0; + buttonConstraints.fill = buttonConstraints.HORIZONTAL; + buttonConstraints.anchor = buttonConstraints.CENTER; + + buttonPanel.add(addItem, buttonConstraints); + buttonPanel.add(spacer1, buttonConstraints); + buttonPanel.add(delItem, buttonConstraints); + buttonPanel.add(spacer2, buttonConstraints); + buttonPanel.add(addAllItem, buttonConstraints); + buttonPanel.add(spacer3, buttonConstraints); + buttonPanel.add(delAllItem, buttonConstraints); + + constraints.location = constraints.BUTTONS; + + layout.setConstraints(buttonPanel, constraints); + panel.add(buttonPanel); + + // dst label + + JLabel dstLabel = new JLabel(); + setUpLabel(dstLabel, dstHeader); + + constraints.location = constraints.RIGHT_LABEL; + constraints.insets = new Insets(5, 5, 5, 5); + + layout.setConstraints(dstLabel, constraints); + panel.add(dstLabel); + + // dst tree + + JScrollPane dstScroll = newTree(); + dstTree = (JTree) dstScroll.getViewport().getView(); + + constraints.location = constraints.RIGHT_SCROLLPANE; + constraints.insets = new Insets(5, 5, 5, 5); + + layout.setConstraints(dstScroll, constraints); + panel.add(dstScroll); + + dstLabel.setLabelFor(dstTree); + } + + private void makePanel(String srcHeader, String dstHeader) { + makePanel(this, srcHeader, dstHeader); + } + + private JScrollPane newTree() { + DefaultTreeModel treeModel = new DefaultTreeModel( + new DblTreeNode("All Items")); + + JTree tree = new JTree(treeModel); + JScrollPane treeScroll = new JScrollPane(tree); + + tree.getSelectionModel().setSelectionMode( + TreeSelectionModel.SINGLE_TREE_SELECTION); + + tree.setLargeModel(true); + tree.setRootVisible(false); + tree.setShowsRootHandles(true); + + treeScroll.setVerticalScrollBarPolicy( + ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); + treeScroll.setHorizontalScrollBarPolicy( + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); + + tree.putClientProperty("JTree.lineStyle", "Angled"); + + return treeScroll; + } + + /** + * Convenience method for creating & initializing + * a new JLabel + * + * @param label the component to initialize + * @param txt the text displayed + */ + private void setUpLabel(JLabel label, String txt) { + ActionString actionString = new ActionString(txt); + label.setText(actionString.getString()); + label.setDisplayedMnemonic(actionString.getMnemonic()); + label.setHorizontalAlignment(label.LEFT); + label.setVerticalAlignment(label.BOTTOM); + } + + /** + * Convenience method for creating & initializing + * a new JButton + * + * @param button the component to initialize + * @param txt the text displayed + */ + private void setUpButton(AbstractButton button, String txt) { + ActionString actionString = new ActionString(txt); + button.setText(actionString.getString()); + button.setMnemonic(actionString.getMnemonic()); + } + + /** + * Set initial selection of a tree node + * + */ + public void setInitSelection() { + DblTreeNode child; + TreePath nodepath; + + DefaultTreeModel srcModel = (DefaultTreeModel)srcTree.getModel(); + DefaultTreeModel dstModel = (DefaultTreeModel)dstTree.getModel(); + DblTreeNode srcRoot = (DblTreeNode)srcModel.getRoot(); + DblTreeNode dstRoot = (DblTreeNode)dstModel.getRoot(); + + if (srcTree.isRootVisible()) { + + nodepath = new TreePath(srcRoot); + srcTree.setSelectionPath(nodepath); + addItem.setEnabled(true); + delItem.setEnabled(false); + + } else if (srcRoot.getChildCount() > 0) { + + child = (DblTreeNode)srcRoot.getFirstChild(); + nodepath = new TreePath(child.getPath()); + srcTree.setSelectionPath(nodepath); + srcTree.scrollPathToVisible(nodepath); + addItem.setEnabled(true); + delItem.setEnabled(false); + + } else if (dstTree.isRootVisible()) { + + nodepath = new TreePath(dstRoot); + dstTree.setSelectionPath(nodepath); + addItem.setEnabled(false); + delItem.setEnabled(true); + + } else if (dstRoot.getChildCount() > 0) { + + child = (DblTreeNode)dstRoot.getFirstChild(); + nodepath = new TreePath(child.getPath()); + dstTree.setSelectionPath(nodepath); + dstTree.scrollPathToVisible(nodepath); + addItem.setEnabled(false); + delItem.setEnabled(true); + + } + } +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/DoubleTreesConstraints.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/DoubleTreesConstraints.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,164 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + */ + + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import java.awt.*; + +/** + * SMC code adapted for Visual Panels + * + * This class provides the DoubleTreesLayout manager constraints. + * + */ +public class DoubleTreesConstraints implements Cloneable, java.io.Serializable { + + /** + * Default location field value. + * Used to determine if the location + * field has not been set. + */ + private static final int UNKNOWN = 0; + + /** + * location field value for the left label + * above the left scrollpane. + */ + public static final int LEFT_LABEL = 1; + + /** + * location field value for the left scrollpane. + */ + public static final int LEFT_SCROLLPANE = 2; + + /** + * location field value for the right label above the right + * scrollpane. + */ + public static final int RIGHT_LABEL = 3; + + /** + * location field value for the right scrollpane. + */ + public static final int RIGHT_SCROLLPANE = 4; + + /** + * location field value for the central buttons between the + * left and right scrollpane. + */ + public static final int BUTTONS = 5; + + /** + * This field identifies which component within the + * DoubleTreesLayout the constraints belong to. If the + * location has not been set the value is undefined but will not + * default to any of the valid field values. + *
+ * Valid field + * values are + * LEFT_LABEL, + * RIGHT_LABEL, + * LEFT_SCROLLPANE, + * RIGHT_SCROLLPANE and + * BUTTONS. + */ + public int location; + + /** + * This field specifies the external padding of the + * component, the minimum amount of space between the component and the + * edges of its display area. + *
+ * The default value is + * new Insets(0, 0, 0, 0). + */ + public Insets insets; + + /** + * This field specifies the internal padding of the component, + * how much space to add to the minimum width of the component. + * The width of the component is at least its minimum width plus + * (ipadx * 2) pixels. + *
+ * The default value is 0. + */ + public int ipadx; + + /** + * This field specifies the internal padding of the component, + * how much space to add to the minimum height of the component. + * The height of the component is at least its minimum height plus + * (ipadx * 2) pixels. + *
+ * The default value is 0. + */ + public int ipady; + + /** + * Creates a DoubleTreesConstraint object with all of + * the fields set to the default value. + */ + public DoubleTreesConstraints() { + location = UNKNOWN; + insets = new Insets(0, 0, 0, 0); + ipadx = 0; + ipady = 0; + } + + /** + * Creates a DoubleTreesConstraints object with all of the + * fields set to the passed-in arguments. + * + * @param location + * location field value. + * @param insets + * insets field value. + * @param ipadx + * ipadx field value. + * @param ipady + * ipady field value. + */ + public DoubleTreesConstraints( + int location, + Insets insets, + int ipadx, int ipady) { + this.location = location; + this.insets = insets; + this.ipadx = ipadx; + this.ipady = ipady; + } + +// ---------------------------------------------------------------------- + + public Object clone() { + try { + return ((DoubleTreesConstraints)super.clone()); + } catch (CloneNotSupportedException e) { + // this shouldn't happen, since we are Cloneable + throw new InternalError(); + } + } +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/DoubleTreesLayout.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/DoubleTreesLayout.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,453 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + */ + + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import java.awt.*; +import javax.swing.*; +import java.util.*; + +import com.oracle.solaris.vp.util.misc.finder.Finder; + +/** + * SMC code adapted for Visual Panels + * + * This class provides the DoubleTreesLayout manager used + * by the DoubleTrees component. The layout manager assumes + * that the DoubleTrees component contains the following + * interior components. + *
+ * + * +---------------------------------------------------+ + * | LEFT_LABEL RIGHT_LABEL | + * | +----------------+ +----------------+ | + * | |LEFT_SCROLLPANE | |RIGHT_SCROLLPANE| | + * | | | +-------+ | | | + * | | | |BUTTONS| | | | + * | | | | | | | | + * | | | | | | | | + * | | | +-------+ | | | + * | | | | | | + * | +----------------+ +----------------+ | + * | | + * +---------------------------------------------------+ + * + *
+ * Each component is laid out and sized with respect to its own + * DoubleTreesConstraints object. + * + */ +public class DoubleTreesLayout implements LayoutManager2, java.io.Serializable { + + protected final static Dimension ZERO_SIZE = new Dimension(0, 0); + protected final static Dimension MAXIMUM_SIZE = + new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); + + protected Dimension size; + protected Dimension minimumSize = new Dimension(400, 250); + protected Dimension preferredSize = minimumSize; + protected Dimension maximumSize; + protected DoubleTreesConstraints defaultConstraints; + + /** + * Constraints location to component map. Location key is wrapped in an + * Integer. + */ + protected HashMap componentsMap; + + /** + * Component to constraints map. + */ + protected HashMap constraintsMap; + +// ---------------------------------------------------------------------- + + /** + * Construct a DoubleTreesLayout manager with default values. + */ + public DoubleTreesLayout() { + size = ZERO_SIZE; + maximumSize = MAXIMUM_SIZE; + defaultConstraints = new DoubleTreesConstraints(); + componentsMap = new HashMap(); + constraintsMap = new HashMap(); + } + +// ---------------------------------------------------------------------- + + /** + * Set the constraints for a given component. If the component has + * not previously been added to the layout, setting the components + * constraints will add the component to the layout. + * + * @param component + * Component. + * @param constraints + * Components constraints. + */ + public void setConstraints( + Component component, + DoubleTreesConstraints constraints) { + addLayoutComponent(component, constraints); + } + + /** + * Get the constraints for a given component. If the component has + * not had previously added to the layout the default constraints + * are returned. + * + * @param component + * Component. + * @param constraints + * Components constraints. + */ + public DoubleTreesConstraints getConstraints(Component component) { + if (constraintsMap.containsKey(component)) { + return constraintsMap.get(component); + } else { + return defaultConstraints; + } + } + + public void addLayoutComponent(String name, Component component) { + // Copied from GridBayLayout. + throw new RuntimeException("Not used by this layout manager"); + } + + public void addLayoutComponent(Component component, Object object) { + if (object == null) { + if (!constraintsMap.containsKey(component)) { + // No constraints for component. + object = defaultConstraints; + } else { + // Don't add again. + return; + } + } + + // Can only deal with our own constraints objects. + if (!(object instanceof DoubleTreesConstraints)) { + throw new RuntimeException( + "Constraints not sub class of DoubleTreesConstraints"); + } + + /** + * Clone constraints in case caller is re-using the same constraints + * object. + */ + DoubleTreesConstraints constraints = + (DoubleTreesConstraints) ((DoubleTreesConstraints) object).clone(); + + // Update maps. + componentsMap.put(new Integer(constraints.location), component); + constraintsMap.put(component, constraints); + + } + + public void removeLayoutComponent(Component component) { + DoubleTreesConstraints constraints = + constraintsMap.get(component); + + if (constraints != null) { + componentsMap.remove(new Integer(constraints.location)); + } + + constraintsMap.remove(component); + } + + public Dimension preferredLayoutSize(Container parent) { + return preferredSize; + } + + public Dimension minimumLayoutSize(Container parent) { + return minimumSize; + } + + public Dimension maximumLayoutSize(Container parent) { + return maximumSize; + } + + public float getLayoutAlignmentX(Container parent) { + return 0.5f; + } + + public float getLayoutAlignmentY(Container parent) { + return 0.5f; + } + + public void invalidateLayout(Container target) { + } + + public void layoutContainer(Container parent) { + synchronized (parent.getTreeLock()) { + doLayoutContainer(parent); + } + } + + /** + * Layout the components. + * + * @param parent + * Container component where the DoubleTrees component + * resides. + */ + private void doLayoutContainer(Container parent) { + size = parent.getSize(); + + JComponent ll = (JComponent) componentsMap.get( + new Integer(DoubleTreesConstraints.LEFT_LABEL)); + DoubleTreesConstraints llc = + constraintsMap.get(ll); + + JComponent rl = (JComponent) componentsMap.get( + new Integer(DoubleTreesConstraints.RIGHT_LABEL)); + DoubleTreesConstraints rlc = constraintsMap.get(rl); + + Component b = componentsMap.get( + new Integer(DoubleTreesConstraints.BUTTONS)); + DoubleTreesConstraints bc = constraintsMap.get(b); + + Component ls = componentsMap.get( + new Integer(DoubleTreesConstraints.LEFT_SCROLLPANE)); + DoubleTreesConstraints lsc = constraintsMap.get(ls); + + Component rs = componentsMap.get( + new Integer(DoubleTreesConstraints.RIGHT_SCROLLPANE)); + DoubleTreesConstraints rsc = constraintsMap.get(rs); + + double pw = parent.getSize().getWidth(); + double ph = parent.getSize().getHeight(); + + double llw = ll.getPreferredSize().getWidth(); + double llh = ll.getPreferredSize().getHeight(); + + double lsw = ls.getPreferredSize().getWidth(); + double lsh = ls.getPreferredSize().getHeight(); + + double rlw = rl.getPreferredSize().getWidth(); + double rlh = rl.getPreferredSize().getHeight(); + + double rsw = rs.getPreferredSize().getWidth(); + double rsh = rs.getPreferredSize().getHeight(); + + double bw = b.getPreferredSize().getWidth(); + double bh = b.getPreferredSize().getHeight(); + + // button w and h inc. insets + + bw += bc.insets.left + bc.insets.right; + bh += bc.insets.top + bc.insets.bottom; + + // leave button w fixed, give rest of parent w to scroll panes + + lsw = rsw = (pw - bw) / 2.0; + + // left label w must not exceed left scroll pane w + + ls.setSize(new Dimension((int) lsw, (int) lsh)); + + ll.setMaximumSize(setDimensionAxis(ll.getMaximumSize(), lsw, true)); + + llw = lsw - llc.insets.left - llc.insets.right; + + ll.setSize(setDimensionAxis(ll.getSize(), llw, true)); + + llw = ll.getPreferredSize().getWidth(); + llh = ll.getPreferredSize().getHeight(); + + // right label w must not exceed right scroll pane w + + rs.setSize(new Dimension((int) rsw, (int) rsh)); + + rl.setMaximumSize(setDimensionAxis(ll.getMaximumSize(), rsw, true)); + + llw = lsw - llc.insets.left - llc.insets.right; + + rl.setSize(setDimensionAxis(rl.getSize(), rlw, true)); + + rlw = rl.getPreferredSize().getWidth(); + rlh = rl.getPreferredSize().getHeight(); + + // both label h must be equal and accomodate both labels + + double lh = Math.max( + llh + llc.insets.top + llc.insets.bottom, + rlh + rlc.insets.top + rlc.insets.bottom); + + ll.setSize(new Dimension((int) lsw, (int) lh)); + + rl.setSize(new Dimension((int) rsw, (int) lh)); + + // both label w must not exceed scroll pane w + + llw = lsw; + rlw = rsw; + + // scroll pane h gets rest of parent h after label h allocated + + lsh = rsh = ph - lh; + + ls.setSize(new Dimension((int) lsw, (int) lsh)); + rs.setSize(new Dimension((int) rsw, (int) rsh)); + b.setSize(new Dimension((int) bw, (int) bh)); + + // see if we have a preferred size > minimum size + + if (preferredSize == minimumSize) { + int w = (int) (lsw + bw + rsw); + int h = (int) (lh + lsh); + + w = Math.max(w, (int) minimumSize.getWidth()); + h = Math.max(h, (int) minimumSize.getHeight()); + + preferredSize = new Dimension(w, h); + } + + // set locations for labels, scroll panes and buttons + + int llx = 0; + int lly = 0; + + int lsx = 0; + int lsy = lly + (int) lh; + + int bx = lsx + (int) lsw; + int by = (int) (lh + (lsh - bh) / 2); + + int rlx = bx + (int) bw; + int rly = 0; + + int rsx = bx + (int) bw; + int rsy = rly + (int) lh; + + ll.setLocation(llx, lly); + ls.setLocation(lsx, lsy); + rs.setLocation(rsx, rsy); + rl.setLocation(rlx, rly); + b.setLocation(bx, by); + + // adjust size and locations to accomodate insets + + includeInsets(ll, llc.insets); + includeInsets(rl, rlc.insets); + includeInsets(ls, lsc.insets); + includeInsets(rs, rsc.insets); + includeInsets(b, bc.insets); + } + + /** + * Adjust components size and location to accomodate an Inset. + * + * @param component + * Component to be resized and relocated. + * @param insets + * Inserts that must surround the component. + */ + private void includeInsets(Component component, Insets insets) { + Point location = component.getLocation(); + Dimension size = component.getSize(); + + double x = location.getX(); + double y = location.getY(); + double width = size.getWidth(); + double height = size.getHeight(); + + component.setLocation( + (int) (x + insets.left), + (int) (y + insets.top)); + component.setSize( + (int) (width - insets.left - insets.right), + (int) (height - insets.top - insets.bottom)); + } + +// ---------------------------------------------------------------------- + + /** + * Get axis of a Dimension. + * + * @param dimension + * Dimension being inspected. + * @param xAxis + * True if the width (X axis) is required, otherwise false if the + * height (Y axis) is required. + * @return + * Required axis value. + */ + private double getDimensionAxis(Dimension dimension, boolean xAxis) { + if (xAxis) { + return dimension.getWidth(); + } else { + return dimension.getHeight(); + } + } + + /** + * Set axis of a Dimension. + * + * @param dimension + * Dimension being modified. + * @param value + * New axis value. + * @param xAxis + * True if the width (X axis) is required, otherwise false if the + * height (Y axis) is required. + * @return + * The modified Dimension. + */ + private Dimension setDimensionAxis( + Dimension dimension, + double value, + boolean xAxis) { + if (xAxis) { + dimension.setSize(value, dimension.getHeight()); + } else { + dimension.setSize(dimension.getWidth(), value); + } + + return dimension; + } + + /** + * Set axis of a Dimension. + * + * @param dimension + * Dimension being modified. + * @param value + * New axis value. + * @param xAxis + * True if the width (X axis) is required, otherwise false if the + * height (Y axis) is required. + * @return + * The modified Dimension. + */ + private Dimension setDimensionAxis( + Dimension dimension, + int value, + boolean xAxis) { + return setDimensionAxis(dimension, (double) value, xAxis); + } + +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/ExtAttrObj.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/ExtAttrObj.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,357 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + */ + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import java.lang.*; +import java.io.*; +import java.util.*; + + +/** + * SMC code adapted for Visual Panels + * + * The ExtAttrObj class is the base class for all RBAC attribute objects + * stored in the RBAC "_attr" table data stores in a name service. + * It contains convenience methods for manipulating key/value sets; + * a comma separated set of string values with a specific keyword. + * All key/value sets are maintained in a hash table in this superclass. + * + */ + + +public class ExtAttrObj extends Object implements Cloneable { + + // Private attributes backstopped by persistent storage + + public Hashtable attrSet; // Key-Value Attributes + + /** + * Null constructor creates an empty has table of key/values. + * + */ + public ExtAttrObj() { + + attrSet = new Hashtable(); + + } + + /** + * Return the values for a specified key name. + * + * @param A key name + * + * @return A vector of string values + * + */ + public Vector getAttribute(String keyName) { + + if (!attrSet.containsKey(keyName)) { + return (null); + } else { + AttrObj attr = locate(keyName); + return (attr.getVector()); + } + + } + + /** + * Set the value for a specified key name. Any existing values + * for that key are replaced. + * + * @param A key name + * @param A string value + * + */ + public void setAttribute(String keyName, String value) { + + AttrObj attr = locate(keyName); + attr.set(value); + + } + + /** + * Set one or more values for a specified key name. + * Any existing values for that key are replaced. + * + * @param A key name + * @param A vector of string values + * + */ + public void setAttribute(String keyName, Vector values) { + + AttrObj attr = locate(keyName); + attr.set(values); + + } + + /** + * Return an array of string values for a specified key name. + * + * @param A key name + * + * @return An array of string values + * + */ + public String [] getAttributeArray(String keyName) { + + if (! attrSet.containsKey(keyName)) { + return (null); + } else { + AttrObj attr = locate(keyName); + Vector v = attr.getVector(); + String [] star = new String[v.size()]; + v.copyInto(star); + return (star); + } + + } + + /** + * Set one or more values for a specified key name. + * Any existing values for that key are replaced. + * + * @param A key name + * @param An array of string values + * + */ + public void setAttribute(String keyName, String [] values) { + + AttrObj attr = locate(keyName); + attr.set(values); + + } + + /** + * Add a string value to the set of values for a key name. + * + * @param A key name + * @param A string value + * + */ + public void addAttribute(String keyName, String value) { + + AttrObj attr = locate(keyName); + attr.add(value); + + } + + /** + * Add one or more string values to the set of values for a key name. + * + * @param A key name + * @param A vector of string values + * + */ + public void addAttribute(String keyName, Vector values) { + + AttrObj attr = locate(keyName); + attr.add(values); + + } + + /** + * Add one or more string values to the set of values for a key name. + * + * @param A key name + * @param An array of string values + * + */ + public void addAttribute(String keyName, String [] values) { + + AttrObj attr = locate(keyName); + attr.add(values); + + } + + /** + * Remove a string value from the set of values for a key name. + * + * @param A key name + * @param A string value + * + */ + public void delAttribute(String keyName, String value) { + + AttrObj attr = locate(keyName); + attr.del(value); + + } + + /** + * Remove one or more string values from the set of values + * for a key name. + * + * @param A key name + * @param A vector of string values + * + */ + public void delAttribute(String keyName, Vector values) { + + AttrObj attr = locate(keyName); + attr.del(values); + + } + + /** + * Remove one or more string values from the set of values + * for a key name. + * + * @param A key name + * @param An array of string values + * + */ + public void delAttribute(String keyName, String [] values) { + + AttrObj attr = locate(keyName); + attr.del(values); + + } + /** + * Remove a key name and all its values. + * + * @param A key name + * + */ + public void clearAttribute(String keyName) { + + // Because KeyValue will do a merge, cannot remove the + // key/value from the hash table. Rather, set its value + // to empty. + AttrObj attr = locate(keyName); + attr.set(""); + + } + + /** + * Remove all key name and all their values; that is, + * reset the key/values attributes to a null set. + * + */ + public void clearAttributes() { + + // Because KeyValue will do a merge, cannot remove the + // key/values from the hash table. Rather, set the values + // for all keys to empty. + Enumeration values = attrSet.elements(); + while (values.hasMoreElements()) { + AttrObj attr = (AttrObj) values.nextElement(); + attr.set(""); + } + + } + + /** + * Update the key/value attributes from this object into + * another attribute object (clone the attributes). + * + * @param An attribute object + * + */ + public void clone(ExtAttrObj newExtAttrObj) { + + Enumeration values = attrSet.elements(); + while (values.hasMoreElements()) { + AttrObj attrObj = (AttrObj) values.nextElement(); + String key = attrObj.getKey(); + AttrObj newAttrObj = newExtAttrObj.locate(key); + newAttrObj.set((attrObj.getVector())); + } + + } + + /** + * Find the attributes for a key name. If not found, create + * a new key/value attribute with null values. + * + * @param A key name + * + */ + public AttrObj locate(String key) { + + AttrObj attrObj; + if (attrSet.containsKey(key)) { + attrObj = attrSet.get(key); + } else { + attrObj = new AttrObj(key); + attrSet.put(key, attrObj); + } + return attrObj; + + } + + /** + * The equals method checks that all attributes of this user + * authorization attributes object equal the corresponding + * attributes of the specified user attributes object. + * If so, true is returned; otherwise, false is returned. + * + * @param extAttr Specified user attr object to be compared + * + * @return true if the specified object is identical + * + */ + public boolean equals(ExtAttrObj extAttr) { + + String [] s2; + String ts; + int i, j, k; + + if (! (attrSet.size() == extAttr.attrSet.size())) + return (false); + + Enumeration values = attrSet.elements(); + while (values.hasMoreElements()) { + AttrObj attrObj = (AttrObj) values.nextElement(); + String key = attrObj.getKey(); + if (! (extAttr.attrSet.containsKey(key))) + return (false); + + AttrObj newAttrObj = extAttr.locate(key); + + if (! (attrObj.equals(newAttrObj))) + return (false); + } + + // Everything matches, must be equal + return (true); + + } + + /** + * Display the contents of the key/values of this attribute + * object to sysout for debugging purposes. + * + */ + public void debugPrint() { + + Enumeration values = attrSet.elements(); + while (values.hasMoreElements()) { + AttrObj attrObj = (AttrObj) values.nextElement(); + attrObj.debugPrint(); + } + } + +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/FilterUserAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/FilterUserAction.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,313 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + */ + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import java.util.List; +import javax.swing.text.JTextComponent; +import com.oracle.solaris.vp.panel.common.action.*; +import com.oracle.solaris.vp.panel.common.control.*; +import com.oracle.solaris.vp.panel.swing.action.SwingManagedObjectAction; +import com.oracle.solaris.rad.usermgr.*; +import com.oracle.solaris.vp.util.misc.ObjectUtil; +import com.oracle.solaris.vp.util.misc.finder.Finder; +import com.oracle.solaris.vp.util.misc.property.*; +import com.oracle.solaris.vp.util.swing.*; +import com.oracle.solaris.vp.util.swing.layout.*; +import com.oracle.solaris.vp.util.swing.property.*; + +/** + * Filter users based on the scope (files or ldap) + * and type (user or role). The search string provides + * additional filtering. + */ +@SuppressWarnings({"serial"}) +public class FilterUserAction extends SwingManagedObjectAction + { + + private UserManagedObject umo = null; + private UserImpl user = null; + + // + // Inner classes + // + + protected class Data { // implements ActionListener + // + // Instance data + // + + private ButtonGroup scopeGroup; + private ButtonGroup typeGroup; + private JTextField matchField; + private JOptionPane pane; + private JDialog dialog; + + private UserMgrPanelDescriptor descriptor = null; + + public MutableProperty matchProperty = new StringProperty(); + public MutableProperty typeProperty = new StringProperty(); + + + // + // Constructors + // + + public Data() { + pane = new JOptionPane(CreateGui(), + JOptionPane.PLAIN_MESSAGE, + JOptionPane.OK_CANCEL_OPTION); + UserMgrUtils.removeIcons(pane); + + dialog = pane.createDialog(getHasComponent().getComponent(), + Finder.getString("usermgr.filter.title")); + } + + private JPanel CreateGui() { + ActionListener listener = + new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + pane.setValue(JOptionPane.OK_OPTION); + } + }; + + ActionString actString = null; + JRadioButton scopeButton = null; + descriptor = control.getPanelDescriptor(); + JPanel form = new JPanel(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + int width = GUIUtil.getTextFieldWidth(); + + gbc.gridx = 0; + gbc.gridy = 0; + // gbc.weightx = 1.0; + gbc.fill = GridBagConstraints.REMAINDER; + gbc.anchor = GridBagConstraints.LINE_START; + int hGap = GUIUtil.getHalfGap(); + gbc.insets = new Insets(0, 0, hGap, hGap); + + // Label for the dialog + JLabel introLabel = new JLabel( + Finder.getString("usermgr.filter.label")); + form.add(introLabel, gbc); + + // + // Scope: files or ldap + // + JLabel scopeLabel = new JLabel( + Finder.getString("usermgr.filter.scope")); + JPanel scopePanel = new JPanel(); + + scopeGroup = new ButtonGroup(); + List scopes = descriptor.getScopes(); + JRadioButton[] buttons = new JRadioButton[scopes.size()]; + for (int i = 0; i < scopes.size(); i++) { + String scope = scopes.get(i); + scopeButton = new JRadioButton(scope); + scopeButton.setActionCommand(scope); + int mnemonic = scope.toUpperCase().charAt(0); + scopeButton.setMnemonic(mnemonic); + scopeGroup.add(scopeButton); + scopePanel.add(scopeButton); + buttons[i] = scopeButton; + } + + // For single scope, disable the button + if (scopes.size() == 1) { + buttons[0].setEnabled(false); + } + + gbc.gridy++; + gbc.gridwidth = 1; + gbc.fill = GridBagConstraints.NONE; + form.add(scopeLabel, gbc); + gbc.fill = GridBagConstraints.REMAINDER; + gbc.gridx = GridBagConstraints.RELATIVE; + form.add(scopePanel, gbc); + + // + // Type: User or Role + // + JLabel typeLabel = new JLabel( + Finder.getString("usermgr.filter.type")); + JPanel typePanel = new JPanel(); + + typeGroup = new ButtonGroup(); + actString = new ActionString("usermgr.filter.type.user"); + JRadioButton userButton = new JRadioButton(actString.getString()); + userButton.setMnemonic(actString.getMnemonic()); + userButton.setSelected(true); + userButton.setActionCommand("normal"); + typeGroup.add(userButton); + typePanel.add(userButton); + + actString = new ActionString("usermgr.filter.type.role"); + JRadioButton roleButton = new JRadioButton(actString.getString()); + roleButton.setMnemonic(actString.getMnemonic()); + roleButton.setActionCommand("role"); + typeGroup.add(roleButton); + typePanel.add(roleButton); + + gbc.gridy++; + gbc.gridwidth = 1; + gbc.fill = GridBagConstraints.NONE; + form.add(typeLabel, gbc); + gbc.fill = GridBagConstraints.REMAINDER; + gbc.gridx = GridBagConstraints.RELATIVE; + form.add(typePanel, gbc); + + // Match String + actString = new ActionString("usermgr.filter.match"); + JLabel matchLabel = new JLabel(actString.getString()); + matchLabel.setDisplayedMnemonic(actString.getMnemonic()); + gbc.gridx = 0; + gbc.gridy++; // next row + form.add(matchLabel, gbc); + + matchField = GUIUtil.createTextField(); + matchField.addActionListener(listener); + new TextComponentPropertySynchronizer + (matchProperty, matchField, false); + + matchLabel.setLabelFor(matchField); + gbc.gridx = GridBagConstraints.RELATIVE; + form.add(matchField, gbc); + + // + // Start with previously selected filter entries + // + if (userButton.getActionCommand().equals(descriptor.getType())) { + userButton.setSelected(true); + } else { + roleButton.setSelected(true); + } + matchField.setText(descriptor.getMatch()); + + for (int j = 0; j < buttons.length; j++) { + if (buttons[j].getActionCommand().equals(descriptor.getScope())) { + buttons[j].setSelected(true); + break; + } + } + + return form; + } + + public String getScope() { + ButtonModel bm = scopeGroup.getSelection(); + return bm.getActionCommand(); + } + + public String getType() { + ButtonModel bm = typeGroup.getSelection(); + return bm.getActionCommand(); + } + + public String getString() { + return matchField.getText(); + } + } + + // + // Static data + // + + private static final String FILTER_TEXT = Finder.getString( + "usermgr.action.filter.button"); + + // + // Instance data + // + + private MainControl control; + + // + // Constructors + // + + public FilterUserAction(MainControl control) { + super(FILTER_TEXT, null, control); + ActionString actStr = new ActionString( + "usermgr.action.filter.button"); + putValue(Action.NAME, actStr.getString()); + putValue(Action.MNEMONIC_KEY, actStr.getMnemonic()); + // putValue(Action.MNEMONIC_KEY, KeyEvent.VK_F); + this.control = control; + setLoops(true); + } + + // + // StructuredAction methods + // + + // @Override + public Data getRuntimeInput(List selection, + Data uData) throws ActionAbortedException { + + // Since this action navigates to the new object once created, we must + // first navigate to control so that any outstanding changes in the + // current Control are handled. + try { + control.getNavigator().goToAsyncAndWait(false, control); + } catch (NavigationException e) { + throw new ActionAbortedException(e); + } + + if (uData == null) { + uData = new Data(); + } + + // Blocks until dismissed + uData.dialog.setVisible(true); + + if (!ObjectUtil.equals(uData.pane.getValue(), JOptionPane.OK_OPTION)) { + throw new ActionAbortedException(); + } + + return uData; + } + + // + // DefaultStructuredAction methods + // + + // @Override + public UserManagedObject workBusy(List selection, + Data uData) throws ActionFailedException, + ActionAbortedException, + ActionUnauthorizedException { + + UserMgrPanelDescriptor descriptor = control.getPanelDescriptor(); + descriptor.initUsers(uData.getScope(), + uData.getType(), uData.getString()); + + return null; // umo; + } + +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/GroupsPanel.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/GroupsPanel.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,345 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + */ + + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.text.*; +import javax.swing.tree.*; + +import java.awt.*; +import java.awt.event.*; +import java.util.*; + +import com.oracle.solaris.vp.util.misc.finder.Finder; + +/** + * SMC code adapted for Visual Panels + * + * Groups Panel for Groups settings + */ +public class GroupsPanel extends JPanel { + + public static SelPanel groupPanel; + private static DblTreeNode srcRoot; + private static DblTreeNode dstRoot; + private DefaultTreeModel srcModel, dstModel; + private DblTreeNode[] groupNodes; + private GroupTreeNode[] groupTreeNodes; + + private UserManagedObject userObj = null; + private UserMgrPanelDescriptor panelDesc = null; + + private boolean isGroupListOK = true; + + /** + * Creates the Group Tab for the User. + */ + public GroupsPanel(UserMgrPanelDescriptor panelDesc, + UserManagedObject userObj) { + + super(); + this.panelDesc = panelDesc; + this.userObj = userObj; + + createGui(); + loadGroupTrees(); + + } // end constructor + + private void createGui() { + + GridBagLayout gbl = new GridBagLayout(); + GridBagConstraints gbc = new GridBagConstraints(); + setLayout(gbl); + + // Excluded and Included rights panel + groupPanel = new SelPanel("usermgr.advanced.groups.available", + "usermgr.advanced.groups.assigned"); + + groupPanel.srcTree.setCellRenderer(new GroupRenderer(this)); + groupPanel.dstTree.setCellRenderer(new GroupRenderer(this)); + + Constraints.constrain(this, groupPanel, + 0, 0, 1, 1, gbc.BOTH, gbc.CENTER, 1.0, 1.0, 10, 10, 10, 10); + + } // end of CreateGui + + /** + * Load the Source and Destination trees for rights excluded and + * included lists. + */ + private void loadGroupTrees() { + + Vector vAllGroupObjs = getAvailableGroups(); + + groupPanel.resetModels(); + // For modifying a user: + // Initialize the excluded rights list with all groups + + srcModel = (DefaultTreeModel) groupPanel.srcTree.getModel(); + srcRoot = (DblTreeNode) srcModel.getRoot(); + + dstModel = (DefaultTreeModel) groupPanel.dstTree.getModel(); + dstRoot = (DblTreeNode) dstModel.getRoot(); + + groupNodes = new DblTreeNode[vAllGroupObjs.size()]; + groupTreeNodes = new GroupTreeNode[vAllGroupObjs.size()]; + + int n = 0; + Enumeration e = vAllGroupObjs.elements(); + + // Build an array of tree nodes that can be used for sorting. + while (e.hasMoreElements()) { + String groupObj = (String)e.nextElement(); + String groupName = groupObj; + groupTreeNodes[n] = new GroupTreeNode(groupObj); + n++; + } + + // Sort the list of GroupTreeNode objects. + + if (groupTreeNodes.length > 1) { + NodeCompare comp = new NodeCompare(); + Sort.sort(groupTreeNodes, comp); + } + + // With the sorted tree nodes, now we build the src tree. + for (int i = 0; i < groupTreeNodes.length; i++) { + + groupNodes[i] = new DblTreeNode((Object) groupTreeNodes[i]); + + srcModel.insertNodeInto(groupNodes[i], srcRoot, i); + TreePath nodepath = new TreePath(groupNodes[i].getPath()); + + // Make initial display of excluded list + groupPanel.srcTree.scrollPathToVisible(nodepath); + } + + String groupsStr = userObj.getGroups(); + if (groupsStr == null) + return; + + String[] assignedGroups = userObj.getGroups().split(","); + if (assignedGroups.length == 0) { + return; + } + + // Move groups of current user from excluded list + // to included list. + // Note that a dimmed group will stay dimmed after the move. + // Therefore, a user can not "unassign" a dimmed group on the + // included list. + + for (int i = 0; i < groupNodes.length; i++) { + boolean foundGroup = false; + String groupString = groupNodes[i].toString(); + + for (int j = 0; j < assignedGroups.length; j++) { + if (groupString.equals(assignedGroups[j])) { + foundGroup = true; + break; + } + } + + if (foundGroup) { + groupPanel.initLeaf(groupPanel.srcTree, + groupPanel.dstTree, groupNodes[i]); + } + } + + } // end loadGroupTrees + + private Vector getAvailableGroups() { + Vector groups = new Vector(); + for (String s : panelDesc.getSupplGroups()) { + groups.add(s); + + } + return (groups); + } + + public void setUser(UserManagedObject userObj) { + this.userObj = userObj; + loadGroupTrees(); + } + + public UserManagedObject updateUser() { + Vector vGroups = getAssignedGroups(); + String groupsStr; + + if (vGroups.size() > 0) { + groupsStr = vGroups.elementAt(0); + } else { + groupsStr = ""; + } + + for (int i = 1; i < vGroups.size(); i++) { + groupsStr = groupsStr.concat(","); + groupsStr = groupsStr.concat(vGroups.elementAt(i)); + } + userObj.getGroupsProperty().setValue(groupsStr); + return (userObj); + } + + /** + */ + public Vector getAssignedGroups() { + Vector newGroups = new Vector(); + + if (isGroupListOK == false) { + return newGroups; + } + + DblTreeNode root = (DblTreeNode) dstModel.getRoot(); + Enumeration kids; + kids = root.children(); + + while (kids.hasMoreElements()) { + DblTreeNode childNode; + childNode = (DblTreeNode)kids.nextElement(); + newGroups.addElement(childNode.toString()); + } + + return newGroups; + } + + + class GroupTreeNode { + + String name; + String groupObj = null; + + public GroupTreeNode(String groupObj) { + this.groupObj = groupObj; + this.name = groupObj; + } + + public String getGroupObj() { + return groupObj; + } + + public String toString() { + return name; + } + } + + + class NodeCompare implements Compare { + + /** + * The compare method compares two GroupTreeNode objects by comparing + * their group names. The parameters are specified as Object class + * objects for QuickSort. + * + * @param a - The first Node. + * @param b - The second Node. + * + */ + public final int doCompare(Object a, Object b) { + + GroupTreeNode e1, e2; + String e1Name, e2Name; + + e1 = (GroupTreeNode) a; + e2 = (GroupTreeNode)b; + e1Name = e1.toString(); + e2Name = e2.toString(); + return (e1Name.compareTo(e2Name)); + + } + + } + + + class GroupRenderer extends DefaultTreeCellRenderer { + + private boolean selected; + GroupsPanel rightSubProps; + + public GroupRenderer(GroupsPanel rightSubProps) { + + this.rightSubProps = rightSubProps; + setClosedIcon(null); + setOpenIcon(null); + setLeafIcon(null); + + } + + public Component getTreeCellRendererComponent( + JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + + this.selected = selected; + + DefaultTreeCellRenderer cr = + (DefaultTreeCellRenderer) tree.getCellRenderer(); + cr.setLeafIcon(null); + DblTreeNode node = (DblTreeNode) value; + + if (node.getParent() == null) { + // maybe the same as row == 0 + setText(node.toString()); + + } else if (node.getUserObject() instanceof GroupTreeNode) { + GroupTreeNode groupsdef = (GroupTreeNode) node.getUserObject(); + setText(groupsdef.toString()); + + if (selected) { + if (node.isEnabled()) { + cr.setTextSelectionColor(SystemColor.textText); + } else { + cr.setTextSelectionColor( + SystemColor.inactiveCaptionText); + } + + } else { + if (node.isEnabled()) { + cr.setTextNonSelectionColor(SystemColor.textText); + } else { + + cr.setTextNonSelectionColor( + SystemColor.inactiveCaptionText); + } + } + } + + super.getTreeCellRendererComponent(tree, value, selected, expanded, + leaf, row, hasFocus); + + return this; + + } // end getTreeCellRendererComponent + + } // GroupRenderer + +} // GroupsPanel diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/GroupsSettings.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/GroupsSettings.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,76 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + */ + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import javax.swing.*; +import com.oracle.solaris.vp.util.misc.finder.Finder; + + +/** + * Implements Groups Settings in Advanced Settings + */ +public class GroupsSettings extends AdvancedSettings { + + private static final String NAME = + Finder.getString("usermgr.advanced.groups"); + private static final Icon ICON = Finder.getIcon( + "images/group-24.png"); + + private UserMgrPanelDescriptor panelDesc = null; + private UserManagedObject userObj = null; + private GroupsPanel panel = null; + + public GroupsSettings() { + super(NAME, ICON); + } + + public void setUser(UserManagedObject userObj) { + if (panel == null) { + panel = new GroupsPanel(panelDesc, userObj); + } + panel.setUser(userObj); + } + + public void updateUser() { + userObj = panel.updateUser(); + } + + public boolean isChanged() { + if (userObj != null) { + return (userObj.getGroupsProperty().isChanged()); + } else { + return false; + } + } + + public void init(UserMgrPanelDescriptor panelDesc) { + this.panelDesc = panelDesc; + } + + public JPanel getPanel() { + return panel; + } +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/HintTextPropertySynchronizer.java --- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/HintTextPropertySynchronizer.java Thu Apr 26 00:14:30 2012 -0400 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/HintTextPropertySynchronizer.java Fri Apr 27 00:52:26 2012 -0400 @@ -20,7 +20,7 @@ */ /* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. */ package com.oracle.solaris.vp.panels.usermgr.client.swing; diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/MainControl.java --- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/MainControl.java Thu Apr 26 00:14:30 2012 -0400 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/MainControl.java Fri Apr 27 00:52:26 2012 -0400 @@ -26,7 +26,10 @@ package com.oracle.solaris.vp.panels.usermgr.client.swing; import java.util.List; +import java.util.Map; import javax.swing.*; +import javax.swing.event.*; +import java.awt.event.*; import javax.swing.border.Border; import com.oracle.solaris.vp.panel.common.action.*; import com.oracle.solaris.vp.panel.common.control.*; @@ -36,6 +39,9 @@ import com.oracle.solaris.vp.util.misc.finder.Finder; import com.oracle.solaris.vp.util.swing.ClippedBorder; +/** + * Main User Manager Control + */ public class MainControl extends ListSelectorControl { @@ -50,6 +56,8 @@ // private ManagedObjectTableModel model; + private ListSelectorPanel panel; + private UserMgrBasicControl control = null; // // Constructors @@ -64,6 +72,11 @@ // @Override + public String getHelpMapID() { + return "usermgr-mainpanel"; + } + + @Override protected void save() throws ActionAbortedException, ActionFailedException, ActionUnauthorizedException { @@ -73,11 +86,9 @@ getPanelDescriptor().saveAddedUsers(); getPanelDescriptor().saveModifiedUsers(); + control.clearChanges(); super.save(); - - // update status counts - getPanelDescriptor().setStatusText(); } // @@ -87,7 +98,7 @@ @Override protected void ensureChildrenCreated() { if (children.size() == 0) { - SwingControl control = new UserMgrControl(getPanelDescriptor()); + control = new UserMgrBasicControl(getPanelDescriptor()); addChildren(control); addToLayout(control); } @@ -98,8 +109,8 @@ // @Override protected ListSelectorPanel createComponent() { - ListSelectorPanel panel = new ListSelectorPanel(); - panel.setSelectionTitle(Finder.getString("usermgr.list.title")); + panel = new ListSelectorPanel(); + panel.setSelectionTitle(Finder.getString("usermgr.list.title.user")); Border border = panel.getBorder(); panel.setBorder(new ClippedBorder(border, false, true, true, true)); @@ -114,9 +125,10 @@ panel.getChangeableAggregator().addChangeables( getPanelDescriptor().getChangeableAggregator()); - // Add actions to create/delete users + // Add actions to create/delete/filter users addAction(panel, new AddUserAction(this), true, true); addAction(panel, new DeleteUserAction(this), true, true); + addAction(panel, new FilterUserAction(this), true, true); setDefaultContentView(new UserMgrEmptyPanel()); @@ -129,6 +141,7 @@ addDefaultApplyAction(); addDefaultCancelAction(true); addDefaultOkayAction(true); + addDefaultHelpAction(); } @Override @@ -180,8 +193,8 @@ return null; } UserManagedObject uobj = selection.get(0); - Navigable navigable = new SimpleNavigable(UserMgrControl.ID, - uobj.getName(), UserMgrControl.PARAM_USER, uobj.getId()); + Navigable navigable = new SimpleNavigable(UserMgrBasicControl.ID, + uobj.getName(), UserMgrBasicControl.PARAM_USER, uobj.getId()); return new Navigable[] {navigable}; } @@ -194,7 +207,8 @@ */ @Override protected int getListIndexOf(Control child) { - UserManagedObject umo = ((UserMgrControl)child).getUserManagedObject(); + UserManagedObject umo = + ((UserMgrBasicControl)child).getUserManagedObject(); int uIndex = getPanelDescriptor().indexOf(umo); UserManagedObject utemp = (UserManagedObject) getComponent(). @@ -216,4 +230,40 @@ return model; } + /** + * Get the model to use in the Users list + */ + public void setListTitle(String listTitle) { + if (panel != null) + panel.setSelectionTitle(listTitle); + } + + + @Override + protected void addDefaultCancelAction(final boolean quit) { + getComponent().getButtonBar().getCancelButton().addActionListener( + new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Control.UnsavedChangesAction action; + ChangeableAggregator aggregator = + getComponent().getChangeableAggregator(); + if (aggregator != null && aggregator.isChanged()) { + action = getUnsavedChangesAction(); + } else { + action = Control.UnsavedChangesAction.DISCARD; + } + switch (action) { + case SAVE: + doSaveAndQuit(); + break; + case DISCARD: + doQuit(); + break; + case CANCEL: + break; + } + } + }); + } } diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/QuickVector.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/QuickVector.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,123 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + */ + + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import java.util.Vector; + +/** + * SMC code adapted for Visual Panels + * + * The QuickVector class extends the Vector class, + * providing additional methods which allow faster + * access to elements of the array. + * + */ +public +class QuickVector extends Vector { + + /** + * Constructs an empty vector with the specified initial capacity and + * capacity increment. + * + * @param initialCapacity the initial capacity of the vector. + * @param capacityIncrement the amount by which the capacity is + * increased when the vector overflows. + */ + public QuickVector(int initialCapacity, int capacityIncrement) { + super(initialCapacity, capacityIncrement); + } + + /** + * Constructs an empty vector with the specified initial capacity. + * + * @param initialCapacity the initial capacity of the vector. + */ + public QuickVector(int initialCapacity) { + super(initialCapacity); + } + + /** + * Constructs an empty vector. + * + */ + public QuickVector() { + super(); + } + + /** + * Returns the component at the specified index. + * + * @param index an index into this vector. + * @return the component at the specified index. + * @exception ArrayIndexOutOfBoundsException if an invalid index was + * given. + */ + public final Object quickElementAt(int index) { + if (index >= elementCount) { + throw new ArrayIndexOutOfBoundsException( + index + " >= " + elementCount); + } + return elementData[index]; + } + + /** + * Sets the component at the specified index of this + * vector to be the specified object. The previous component at that + * position is discarded. + *

+ * The index must be a value greater than or equal to 0 + * and less than the current size of the vector. + * + * @param obj what the component is to be set to. + * @param index the specified index. + * @exception ArrayIndexOutOfBoundsException if the index was invalid. + */ + public final void quickSetElementAt(Object obj, int index) { + if (index >= elementCount) { + throw new ArrayIndexOutOfBoundsException( + index + " >= " + elementCount); + } + elementData[index] = obj; + } + + public final void quickSwapElementsAt(int element1, int element2) { + Object obj = null; + + if (element1 >= elementCount) { + throw new ArrayIndexOutOfBoundsException( + element1 + " >= " + elementCount); + } + if (element2 >= elementCount) { + throw new ArrayIndexOutOfBoundsException( + element2 + " >= " + elementCount); + } + obj = elementData[element1]; + elementData[element1] = elementData[element2]; + elementData[element2] = obj; + } + +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/RightsPanel.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/RightsPanel.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,630 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + */ + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.tree.*; +import javax.swing.border.*; + +import java.awt.*; +import java.awt.event.*; +import java.util.*; + +import com.oracle.solaris.vp.util.misc.finder.Finder; + +/** + * SMC code adapted for Visual Panels + * + * Rights Profiles Panel for Rights Settings + */ +public class RightsPanel extends JPanel { + + + public static Arranger profPanel; + private static DblTreeNode srcRoot; + private static DblTreeNode dstRoot; + private DefaultTreeModel srcModel, dstModel; + + private DblTreeNode [] profNodes; + private ProfTreeNode [] profTreeNodes; + + private ProfTreeNode currProfTreeNode; + private DblTreeNode currDblTreeNode; + + private String targetRightName; + private String targetRight; + private JPanel securityPanel; + + private UserManagedObject userObj = null; + private UserMgrPanelDescriptor panelDesc = null; + + private Vector vAllRightObjs = null; + + private boolean isProfListOK = true; + + /** + * Constructs a panel to contain supplementary rights properties for + * the right object. + */ + public RightsPanel(UserMgrPanelDescriptor panelDesc, + UserManagedObject userObj) { + + super(); + this.panelDesc = panelDesc; + this.userObj = userObj; + + createGui(); + loadProfiles(); + } // constructor + + + /** + * Method for creating GUI + */ + private void createGui() { + + // Set the panel layout + GridBagConstraints gbc = new GridBagConstraints(); + this.setLayout(new GridBagLayout()); + + // Excluded and Included rights panel + securityPanel = null; + + profPanel = new Arranger("usermgr.advanced.rights.available", + "usermgr.advanced.rights.granted"); + + Dimension dimension = new Dimension(200, 300); + profPanel.srcTree.setCellRenderer(new ProfileRenderer(this)); + profPanel.srcTree.setVisibleRowCount(10); + profPanel.srcTree.setSize(dimension); + + profPanel.dstTree.setCellRenderer(new ProfileRenderer(this)); + profPanel.dstTree.setVisibleRowCount(10); + profPanel.dstTree.setSize(dimension); + + Constraints.constrain(this, profPanel, + 0, 0, 1, 1, + gbc.BOTH, gbc.CENTER, + 1.0, 1.0, 10, 10, 10, 10); + + } // end createGui + + + /** + * Load the Source and Destination trees for rights excluded and + * included lists. + */ + private void loadProfiles() { + + // Reset the data models. So old data is discarded + profPanel.resetModels(); + + + // Initialize the excluded rights list with all profiles + // except for the current one, since a profile can not be + // assigned to itself. Note that all profiles are created + // as top-level profiles. + + vAllRightObjs = getAvailableProfs(); + + srcModel = (DefaultTreeModel) profPanel.srcTree.getModel(); + srcRoot = (DblTreeNode) srcModel.getRoot(); + + dstModel = (DefaultTreeModel) profPanel.dstTree.getModel(); + dstRoot = (DblTreeNode) dstModel.getRoot(); + + profNodes = new DblTreeNode[vAllRightObjs.size()]; + profTreeNodes = new ProfTreeNode[vAllRightObjs.size()]; + + int n = 0; + Enumeration e = vAllRightObjs.elements(); + + // Build an array of tree nodes that can be used for sorting. + + while (e.hasMoreElements()) { + String rightObj = (String)e.nextElement(); + String rightName = rightObj; + + profTreeNodes[n] = new ProfTreeNode(rightObj); + + n++; + } + + // Sort the list of ProfTreeNode objects. + + if (profTreeNodes.length > 1) { + NodeCompare comp = new NodeCompare(); + Sort.sort(profTreeNodes, comp); + } + + // With the sorted tree nodes, now we build the src tree. + for (int i = 0; i < profTreeNodes.length; i++) { + profNodes[i] = new DblTreeNode((Object)profTreeNodes[i]); + + srcModel.insertNodeInto(profNodes[i], srcRoot, i); + TreePath nodepath = new TreePath(profNodes[i].getPath()); + // Make initial display of excluded list + profPanel.srcTree.scrollPathToVisible(nodepath); + } + + + // Set TreeModel listeners + srcModel.addTreeModelListener(new TreeModelListener() { + + public void treeNodesInserted(TreeModelEvent e) { + enableProfileChoices(e); + } + + public void treeNodesRemoved(TreeModelEvent e) { + disableProfileChoices(e); + } + + public void treeNodesChanged(TreeModelEvent e) {} + + public void treeStructureChanged(TreeModelEvent e) {} + + }); + + dstModel.addTreeModelListener(new TreeModelListener() { + + public void treeNodesInserted(TreeModelEvent e) { + updateDstTree(e); + } + + public void treeNodesRemoved(TreeModelEvent e) { + updateDstTree(e); + } + + public void treeNodesChanged(TreeModelEvent e) {} + + public void treeStructureChanged(TreeModelEvent e) {} + + }); + + // Build subprofiles recursively + for (int i = 0; i < profNodes.length; i++) { + rebuildSubProfiles(profNodes[i], profNodes[i]); + } + + String [] subProfList = null; + + // Get the list of profiles that are assigned to current user/role + // (in user_attr entry). + String rights = userObj.getRights(); + if (rights != null) { + subProfList = userObj.getRights().split(","); + } + + profPanel.setInitSelection(); + if (rights == null || subProfList == null) { + return; + } + + // Move subprofiles of current profile from excluded list + // to included list. + // Note that a dimmed profile will stay dimmed after the move. + // Therefore, a user can not "unassign" a dimmed profile on the + // included list. + + + for (int j = 0; j < subProfList.length; j++) { + boolean foundSubProf = false; + + int count = 0; + for (int i = 0; i < profNodes.length; i++) { + String profString = profNodes[i].toString(); + + if (profString.equals(subProfList[j])) { + foundSubProf = true; + count = i; + break; + } + + } + + if (foundSubProf) { + profPanel.initLeaf(profPanel.srcTree, + profPanel.dstTree, profNodes[count]); + } + } + + profPanel.setInitSelection(); + + } // end loadProfiles + + + private void updateDstTree(TreeModelEvent e) { + + Vector inclProfsVec = new Vector(); + Enumeration inclProfsEnum = dstRoot.breadthFirstEnumeration(); + + while (inclProfsEnum.hasMoreElements()) { + DblTreeNode node = (DblTreeNode)inclProfsEnum.nextElement(); + inclProfsVec.addElement(node); + node.setConflict(false); + } + + // Maintain included names as array as optimization + + DblTreeNode [] inclProfs = new DblTreeNode[inclProfsVec.size()]; + inclProfsVec.copyInto(inclProfs); + + if (inclProfs.length < 2) + return; + + for (int i = 0; i < inclProfs.length; i++) { + String testString = inclProfs[i].toString(); + + for (int j = i + 1; j < inclProfs.length; j++) { + if (testString.equals(inclProfs[j].toString())) { + inclProfs[j].setConflict(true); + inclProfs[i].setConflict(true); + TreeNode [] nodes = inclProfs[j].getPath(); + DblTreeNode parentProf = (DblTreeNode)nodes[1]; + parentProf.setConflict(true); + } + } + } + + } // end updateDstTree + + + private void enableProfileChoices(TreeModelEvent e) { + + // Get names of currently included profiles + if (e.getPath().length > 1) + return; + + Vector inclProfsVec = new Vector(); + Enumeration inclProfs = dstRoot.depthFirstEnumeration(); + + while (inclProfs.hasMoreElements()) { + inclProfsVec.addElement(inclProfs.nextElement().toString()); + } + + // Maintain included names as array as optimization + + String [] inclProfNames = new String[inclProfsVec.size()]; + inclProfsVec.copyInto(inclProfNames); + + // Look for excluded list items needing updating + + Enumeration topProfs = srcRoot.children(); + while (topProfs.hasMoreElements()) { + DblTreeNode nextTop = (DblTreeNode)topProfs.nextElement(); + boolean matchFound = false; + Enumeration exclProfs = nextTop.depthFirstEnumeration(); + + while (exclProfs.hasMoreElements()) { + String testString = exclProfs.nextElement().toString(); + for (int i = 0; i < inclProfNames.length; i++) { + if (testString.equals(inclProfNames[i])) { + matchFound = true; + break; + } + } + if (matchFound) + break; + } + + // A Profile hierarchy needs to be enabled + + if (!matchFound) { + exclProfs = nextTop.depthFirstEnumeration(); + while (exclProfs.hasMoreElements()) { + DblTreeNode onNode = + (DblTreeNode) exclProfs.nextElement(); + onNode.setConflict(false); + } + nextTop.setConflict(false); + } + } + + } // end enableProfileChoices + + + private void disableProfileChoices(TreeModelEvent e) { + + if (e.getPath().length > 1) + return; + + Object[] children = e.getChildren(); + DblTreeNode node = (DblTreeNode)children[0]; + Enumeration kids = node.breadthFirstEnumeration(); + while (kids.hasMoreElements()) { + disableRecursively((DblTreeNode)kids.nextElement()); + } + + } // end disableProfileChoices + + + private void disableRecursively(DblTreeNode node) { + + String testString = node.toString(); + Enumeration exclProfs = srcRoot.breadthFirstEnumeration(); + while (exclProfs.hasMoreElements()) { + DblTreeNode exclNode = (DblTreeNode)exclProfs.nextElement(); + if (testString.equals(exclNode.toString())) { + TreeNode [] nodes = exclNode.getPath(); + + DblTreeNode parentProf = (DblTreeNode)nodes[1]; + if (!parentProf.isConflict()) { + parentProf.setConflict(true); + exclNode.setConflict(true); + } + } + } + + } // end disableRecursively + + + private void rebuildSubProfiles(DblTreeNode profNode, DblTreeNode topNode) { + + // First unlink the old children + int childCount = profNode.getChildCount(); + for (int i = 0; i < childCount; i++) { + DblTreeNode child = (DblTreeNode) srcModel.getChild(profNode, 0); + srcModel.removeNodeFromParent(child); + } + + // Then recursively construct new nodes for all the children + DblTreeNode childNode; + int i = 0; + Enumeration topList = topNode.breadthFirstEnumeration(); + + // Find sub-profile list in RightObj of cached tree node + ProfTreeNode pTreeNode = (ProfTreeNode)profNode.getUserObject(); + String rObj = pTreeNode.getRightObj(); + // ProfAttrObj targetProfAttr = rObj.getProfAttr(); + + String [] profList = null; // targetProfAttr.getProfNames(); + + if (profList == null) + return; + + for (int k = 0; k < profList.length; k++) { + String name = profList[k]; + + // Prevent infinite recursive loops + boolean cyclic = false; + while (topList.hasMoreElements()) { + if (name.equals(topList.nextElement().toString())) { + cyclic = true; + // Mark the parent as cyclic + topNode.setCyclic(true); + Enumeration dupNodes = topNode.breadthFirstEnumeration(); + while (dupNodes.hasMoreElements()) { + childNode = (DblTreeNode)dupNodes.nextElement(); + if (name.equals(childNode.toString())) { + childNode.setCyclic(true); + } + } + break; + } + } + + for (int j = 0; j < profTreeNodes.length; j++) { + if (name.equals(profTreeNodes[j].toString())) { + childNode = new DblTreeNode((Object)profTreeNodes[j]); + + srcModel.insertNodeInto(childNode, profNode, i++); + childNode.setEnabled(false); + if (cyclic) + childNode.setCyclic(true); + else + rebuildSubProfiles(childNode, topNode); + } + } + } + + } // end rebuildSubProfiles + + + public String updateRightSubProps(String rightObj) { + + if (isProfListOK) { + Vector vAssignedProfs = new Vector(); + + // Get the first generation children that are assigned to + // current profile. + DblTreeNode root = (DblTreeNode)dstModel.getRoot(); + Enumeration kids; + kids = root.children(); + + while (kids.hasMoreElements()) { + DblTreeNode childNode; + childNode = (DblTreeNode)kids.nextElement(); + vAssignedProfs.addElement(childNode.toString()); + } + + // ProfAttrObj profAttr = rightObj.getProfAttr(); + // profAttr.setProfNamesVector(vAssignedProfs); + } + return (rightObj); + + } // end updateRightSubProps + + public Vector getAssignedProfs() { + Vector vAssignedProfs = new Vector(); + + if (!isProfListOK) { + return vAssignedProfs; + } + + // Get the first generation children that are assigned to + // current profile. + DblTreeNode root = (DblTreeNode)dstModel.getRoot(); + Enumeration kids; + kids = root.children(); + while (kids.hasMoreElements()) { + DblTreeNode childNode; + childNode = (DblTreeNode)kids.nextElement(); + vAssignedProfs.addElement(childNode.toString()); + } + + return vAssignedProfs; + } + + private Vector getAvailableProfs() { + Vector rights = new Vector(); + for (String s : panelDesc.getProfiles()) { + rights.add(s); + + } + return (rights); + } + + public void setUser(UserManagedObject userObj) { + this.userObj = userObj; + loadProfiles(); + } + + public UserManagedObject updateUser() { + Vector vProfs = getAssignedProfs(); + String profStr; + + if (vProfs.size() > 0) { + profStr = vProfs.elementAt(0); + } else { + profStr = ""; + } + + for (int i = 1; i < vProfs.size(); i++) { + profStr = profStr.concat(","); + profStr = profStr.concat(vProfs.elementAt(i)); + } + + userObj.getRightsProperty().setValue(profStr); + + return (userObj); + } +} + + +class ProfileRenderer extends DefaultTreeCellRenderer { + + private boolean selected; + Icon warningIcon; + static RightsPanel rightsPanel; + + public ProfileRenderer(RightsPanel rightsPanel) { + + this.rightsPanel = rightsPanel; + setClosedIcon(null); + setOpenIcon(null); + setLeafIcon(null); + warningIcon = Finder.getIcon("images/warning.gif"); + + } + + + public Component getTreeCellRendererComponent( + JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + + FocusEvent e = null; + + this.selected = selected; + + DefaultTreeCellRenderer cr = + (DefaultTreeCellRenderer)tree.getCellRenderer(); + cr.setLeafIcon(null); + DblTreeNode node = (DblTreeNode)value; + + if (node.getParent() == null) { + // maybe the same as row == 0 + setText(node.toString()); + + } else if (node.getUserObject() instanceof ProfTreeNode) { + ProfTreeNode profsdef = (ProfTreeNode)node.getUserObject(); + setText(profsdef.toString()); + // setIcon(actionIcon); + + if (node.isConflict()) + if (tree == rightsPanel.profPanel.dstTree) + cr.setLeafIcon(warningIcon); + } + + super.getTreeCellRendererComponent(tree, value, selected, expanded, + leaf, row, hasFocus); + + return this; + + } // end getTreeCellRendererComponent + +} + +class ProfTreeNode { + + String name; + String rightObj = null; + + public ProfTreeNode(String rightObj) { + this.rightObj = rightObj; + this.name = rightObj; + } + + public String getRightObj() { + return rightObj; + } + + public String toString() { + return name; + } + +} + +class NodeCompare implements Compare { + + /** + * The compare method compares two ProfTreeNode objects by comparing + * their profile names. The parameters are specified as Object class + * objects for QuickSort. + * + * @param a The first Node. + * @param b The second Node. + * + */ + public final int doCompare(Object a, Object b) { + + ProfTreeNode e1, e2; + String e1Name, e2Name; + + e1 = (ProfTreeNode)a; + e2 = (ProfTreeNode)b; + e1Name = e1.toString(); + e2Name = e2.toString(); + return (e1Name.compareTo(e2Name)); + + } + +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/RightsSettings.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/RightsSettings.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,78 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + */ + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import javax.swing.*; +import com.oracle.solaris.vp.util.misc.finder.Finder; +import com.oracle.solaris.vp.util.misc.property.*; + +/** + * Implements Advanced Settings for Rights profiles + */ +public class RightsSettings extends AdvancedSettings { + + private static final String NAME = + Finder.getString("usermgr.advanced.rights"); + private static final Icon ICON = Finder.getIcon( + "images/rights-24.png"); + + private UserMgrPanelDescriptor panelDesc = null; + private UserManagedObject userObj = null; + private RightsPanel panel = null; + + public RightsSettings() { + super(NAME, ICON); + } + + public void setUser(UserManagedObject userObj) { + if (panel == null) { + panel = new RightsPanel(panelDesc, userObj); + } + panel.setUser(userObj); + getProperty().update(userObj.getRights(), false); + } + + public void updateUser() { + userObj = panel.updateUser(); + getProperty().update(userObj.getRights(), false); + } + + public boolean isChanged() { + if (userObj != null) { + return (userObj.getRightsProperty().isChanged()); + } else { + return false; + } + } + + public void init(UserMgrPanelDescriptor panelDesc) { + this.panelDesc = panelDesc; + } + + public JPanel getPanel() { + return panel; + } +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/RolesPanel.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/RolesPanel.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,348 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + */ + + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.text.*; +import javax.swing.tree.*; + +import java.awt.*; +import java.awt.event.*; +import java.util.*; + +import com.oracle.solaris.vp.util.misc.finder.Finder; + +/** + * SMC code adapted for Visual Panels + * + * Roles Panels for Roles settings + * + */ +public class RolesPanel extends JPanel { + + public static SelPanel rolePanel; + private static DblTreeNode srcRoot; + private static DblTreeNode dstRoot; + private DefaultTreeModel srcModel, dstModel; + private DblTreeNode[] roleNodes; + private RoleTreeNode[] roleTreeNodes; + + private UserManagedObject userObj = null; + private UserMgrPanelDescriptor panelDesc = null; + + private boolean isRoleListOK = true; + + /** + * Creates the Role Tab for the User. + */ + public RolesPanel(UserMgrPanelDescriptor panelDesc, + UserManagedObject userObj) { + + super(); + this.panelDesc = panelDesc; + this.userObj = userObj; + + createGui(); + loadRoleTrees(); + + } // end constructor + + private void createGui() { + + GridBagLayout gbl = new GridBagLayout(); + GridBagConstraints gbc = new GridBagConstraints(); + setLayout(gbl); + + // Excluded and Included rights panel + rolePanel = new SelPanel("usermgr.advanced.roles.available", + "usermgr.advanced.roles.assigned"); + + rolePanel.srcTree.setCellRenderer(new RoleRenderer(this)); + rolePanel.dstTree.setCellRenderer(new RoleRenderer(this)); + + Constraints.constrain(this, rolePanel, + 0, 0, 1, 1, gbc.BOTH, gbc.CENTER, 1.0, 1.0, 10, 10, 10, 10); + + } // end of CreateGui + + /** + * Load the Source and Destination trees for rights excluded and + * included lists. + */ + private void loadRoleTrees() { + + Vector vAllRoleObjs = getAvailableRoles(); + + rolePanel.resetModels(); + // For modifying a user: + // Initialize the excluded rights list with all roles + + srcModel = (DefaultTreeModel) rolePanel.srcTree.getModel(); + srcRoot = (DblTreeNode) srcModel.getRoot(); + + dstModel = (DefaultTreeModel) rolePanel.dstTree.getModel(); + dstRoot = (DblTreeNode) dstModel.getRoot(); + + roleNodes = new DblTreeNode[vAllRoleObjs.size()]; + roleTreeNodes = new RoleTreeNode[vAllRoleObjs.size()]; + + int n = 0; + Enumeration e = vAllRoleObjs.elements(); + + // Build an array of tree nodes that can be used for sorting. + while (e.hasMoreElements()) { + String roleObj = (String)e.nextElement(); + String roleName = roleObj; + roleTreeNodes[n] = new RoleTreeNode(roleObj); + n++; + } + + // Sort the list of RoleTreeNode objects. + + if (roleTreeNodes.length > 1) { + NodeCompare comp = new NodeCompare(); + Sort.sort(roleTreeNodes, comp); + } + + // With the sorted tree nodes, now we build the src tree. + for (int i = 0; i < roleTreeNodes.length; i++) { + + roleNodes[i] = new DblTreeNode((Object) roleTreeNodes[i]); + + srcModel.insertNodeInto(roleNodes[i], srcRoot, i); + TreePath nodepath = new TreePath(roleNodes[i].getPath()); + + // Make initial display of excluded list + rolePanel.srcTree.scrollPathToVisible(nodepath); + } + + String rolesStr = userObj.getRoles(); + if (rolesStr == null) + return; + + String[] assignedRoles = userObj.getRoles().split(","); + if (assignedRoles.length == 0) { + return; + } + + // Move roles of current user from excluded list + // to included list. + // Note that a dimmed role will stay dimmed after the move. + // Therefore, a user can not "unassign" a dimmed role on the + // included list. + + for (int i = 0; i < roleNodes.length; i++) { + boolean foundRole = false; + String roleString = roleNodes[i].toString(); + + for (int j = 0; j < assignedRoles.length; j++) { + if (roleString.equals(assignedRoles[j])) { + foundRole = true; + break; + } + } + + if (foundRole) { + rolePanel.initLeaf(rolePanel.srcTree, + rolePanel.dstTree, roleNodes[i]); + } + } + + } // end loadRoleTrees + + private Vector getAvailableRoles() { + Vector roles = new Vector(); + for (String s : panelDesc.getRoles()) { + roles.add(s); + + } + return (roles); + } + + public void setUser(UserManagedObject userObj) { + this.userObj = userObj; + loadRoleTrees(); + } + + public UserManagedObject updateUser() { + Vector vRoles = getAssignedRoles(); + String rolesStr; + + if (vRoles.size() > 0) { + rolesStr = vRoles.elementAt(0); + } else { + rolesStr = ""; + } + + for (int i = 1; i < vRoles.size(); i++) { + rolesStr = rolesStr.concat(","); + rolesStr = rolesStr.concat(vRoles.elementAt(i)); + } + userObj.getRolesProperty().setValue(rolesStr); + + return (userObj); + } + + /** + * Get list of roles assigned to a user + */ + public Vector getAssignedRoles() { + Vector newRoles = new Vector(); + + if (isRoleListOK == false) { + return newRoles; + } + + DblTreeNode root = (DblTreeNode) dstModel.getRoot(); + Enumeration kids; + kids = root.children(); + + while (kids.hasMoreElements()) { + DblTreeNode childNode; + childNode = (DblTreeNode)kids.nextElement(); + newRoles.addElement(childNode.toString()); + } + + return newRoles; + } + + + class RoleTreeNode { + + String name; + String roleObj = null; + + public RoleTreeNode(String roleObj) { + this.roleObj = roleObj; + this.name = roleObj; + } + + public String getRoleObj() { + return roleObj; + } + + public String toString() { + return name; + } + } + + + class NodeCompare implements Compare { + + /** + * The compare method compares two RoleTreeNode objects by comparing + * their role names. The parameters are specified as Object class + * objects for QuickSort. + * + * @param a - The first Node. + * @param b - The second Node. + * + */ + public final int doCompare(Object a, Object b) { + + RoleTreeNode e1, e2; + String e1Name, e2Name; + + e1 = (RoleTreeNode) a; + e2 = (RoleTreeNode)b; + e1Name = e1.toString(); + e2Name = e2.toString(); + return (e1Name.compareTo(e2Name)); + + } + + } + + + class RoleRenderer extends DefaultTreeCellRenderer { + + private boolean selected; + RolesPanel rightSubProps; + + public RoleRenderer(RolesPanel rightSubProps) { + + this.rightSubProps = rightSubProps; + setClosedIcon(null); + setOpenIcon(null); + setLeafIcon(null); + + } + + public Component getTreeCellRendererComponent( + JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + + this.selected = selected; + + DefaultTreeCellRenderer cr = + (DefaultTreeCellRenderer) tree.getCellRenderer(); + cr.setLeafIcon(null); + DblTreeNode node = (DblTreeNode) value; + + if (node.getParent() == null) { + // maybe the same as row == 0 + setText(node.toString()); + + } else if (node.getUserObject() instanceof RoleTreeNode) { + RoleTreeNode rolesdef = (RoleTreeNode) node.getUserObject(); + setText(rolesdef.toString()); + + if (selected) { + if (node.isEnabled()) { + cr.setTextSelectionColor(SystemColor.textText); + } else { + cr.setTextSelectionColor( + SystemColor.inactiveCaptionText); + } + + } else { + if (node.isEnabled()) { + cr.setTextNonSelectionColor(SystemColor.textText); + } else { + + cr.setTextNonSelectionColor( + SystemColor.inactiveCaptionText); + } + } + } + + super.getTreeCellRendererComponent(tree, value, selected, expanded, + leaf, row, hasFocus); + + return this; + + } // end getTreeCellRendererComponent + + } // RoleRenderer + +} // RolesPanel diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/RolesSettings.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/RolesSettings.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,85 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + */ + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import javax.swing.*; +import com.oracle.solaris.vp.util.misc.finder.Finder; + +/** + * Implements Advanced Settings for Roles + */ +public class RolesSettings extends AdvancedSettings { + + private static final String NAME = + Finder.getString("usermgr.advanced.roles"); + private static final Icon ICON = Finder.getIcon( + "images/roles-24.png"); + + private UserMgrPanelDescriptor panelDesc = null; + private UserManagedObject userObj = null; + private RolesPanel panel = null; + + public RolesSettings() { + super(NAME, ICON); + } + + public void setUser(UserManagedObject userObj) { + if (panel == null) { + panel = new RolesPanel(panelDesc, userObj); + } + panel.setUser(userObj); + String roleStr = userObj.getRoles(); + if (roleStr == null) { + roleStr = ""; + } + getProperty().update(roleStr, true); + } + + public void updateUser() { + userObj = panel.updateUser(); + String roleStr = userObj.getRoles(); + if (roleStr == null) { + roleStr = ""; + } + getProperty().setValue(roleStr); + } + + public boolean isChanged() { + if (userObj != null) { + return (userObj.getRolesProperty().isChanged()); + } else { + return false; + } + } + + public void init(UserMgrPanelDescriptor panelDesc) { + this.panelDesc = panelDesc; + } + + public JPanel getPanel() { + return panel; + } +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/SelPanel.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/SelPanel.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,646 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + */ + + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.text.*; +import javax.swing.border.*; +import javax.swing.tree.*; +import javax.accessibility.*; + +import java.awt.*; +import java.awt.event.*; +import java.beans.*; +import java.util.*; +import java.io.*; + +import com.oracle.solaris.vp.util.misc.finder.Finder; + +/** + * SMC code adapted for Visual Panels + * + * Selection Panel incorpoarting exclude/include trees + */ +public class SelPanel extends DoubleTrees { + + public SelPanel() { + + setListeners(); + + } + + public SelPanel(String srcHeader, String dstHeader) { + + super(srcHeader, dstHeader); + setListeners(); + + } + + /** + * Create any dynamic images we need. + */ + public void addNotify() { + + super.addNotify(); + + delItem.setIcon(Finder.getIcon("images/remove.png")); + delItem.setHorizontalTextPosition(JButton.RIGHT); + + delAllItem.setIcon(Finder.getIcon("images/remove_all.png")); + delAllItem.setHorizontalTextPosition(JButton.RIGHT); + + addItem.setIcon(Finder.getIcon("images/add.png")); + addItem.setHorizontalTextPosition(JButton.LEFT); + + addAllItem.setIcon(Finder.getIcon("images/add_all.png")); + addAllItem.setHorizontalTextPosition(JButton.LEFT); + + } // addNotify + + + public void setListeners() { + + addItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + move(srcTree, dstTree); + } + }); + + delItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + move(dstTree, srcTree); + } + }); + + addAllItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + moveAll(srcTree, dstTree); + } + }); + + delAllItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + moveAll(dstTree, srcTree); + } + }); + + MouseListener ml = new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + handleMouse(e); + } + public void mousePressed(MouseEvent e) { + handleMouse(e); + } + }; + + srcTree.addMouseListener(ml); + dstTree.addMouseListener(ml); + + } + + private void handleMouse(MouseEvent e) { + + JTree tree1, tree2; + + if (e.getSource() == srcTree) { + tree1 = srcTree; + tree2 = dstTree; + addItem.setEnabled(true); + delItem.setEnabled(false); + } else { + tree1 = dstTree; + tree2 = srcTree; + addItem.setEnabled(false); + delItem.setEnabled(true); + } + TreePath selPath = tree1.getPathForLocation(e.getX(), e.getY()); + + if (selPath != null) { + tree2.clearSelection(); + int selCount = selPath.getPathCount(); + DblTreeNode node = (DblTreeNode)selPath.getLastPathComponent(); + if (e.getClickCount() == 1) { + // mySingleClick(tree1, selPath); + } else if (e.getClickCount() == 2) { + if (node.isLeaf()) + move(tree1, tree2); + } + } + + } + + + public void move(JTree src, JTree dst) { + + DblTreeNode node; + + TreePath selPath = src.getSelectionPath(); + if (selPath == null) // nothing selected (should be disabled) + return; + else if (selPath.getPathCount() == 1) + moveAll(src, dst); + else { + node = (DblTreeNode)selPath.getLastPathComponent(); + + if (node.isLeaf()) { + moveLeaf(src, dst, node); + } else { // node is branch + moveBranch(src, dst, node, true, true); + } + + if (src == srcTree) { + addItem.setEnabled(false); + delItem.setEnabled(true); + } else { + addItem.setEnabled(true); + delItem.setEnabled(false); + } + } + + } + + + private SelPTreeNode matchParent( + DblTreeNode parent, + DblTreeNode root, + DefaultTreeModel dstModel) { + + Enumeration kids; + SelPTreeNode treeNode = new SelPTreeNode(); + int level = parent.getLevel(); + if (level == 0) { + treeNode.newparent = root; + return treeNode; + } + + DblTreeNode [] nodes = new DblTreeNode[level]; + nodes[level - 1] = parent; + for (int i = nodes.length; i > 1; i--) { + nodes [i - 2] = (DblTreeNode) nodes[i - 1].getParent(); + } + + for (int i = 0; i < nodes.length; i++) { + treeNode.newparent = null; + treeNode.index = 0; + String parentString = nodes[i].toString(); + kids = root.children(); + while (kids.hasMoreElements()) { + DblTreeNode testnode; + String teststring; + int diff; + + testnode = (DblTreeNode)kids.nextElement(); + + diff = testnode.compareTo(nodes[i]); + + if (diff == 0) { // matching branch + treeNode.newparent = testnode; + break; + } else if (testnode.isLeaf()) { + treeNode.index++; + continue; + } else if (diff < 0) { + treeNode.index++; + continue; + } else { + break; + } + } + + if (treeNode.newparent != null) { + root = treeNode.newparent; + } else { + DblTreeNode newNode = (DblTreeNode)nodes[i].clone(); + dstModel.insertNodeInto(newNode, root, treeNode.index); + treeNode.newparent = newNode; + root = newNode; + } + } + return treeNode; + + } + + + private int matchChild(JTree src, + JTree dst, + DblTreeNode srcNode, + DblTreeNode newparent, + Enumeration dstKids, + int index) { + + DefaultTreeModel srcModel = (DefaultTreeModel)src.getModel(); + DefaultTreeModel dstModel = (DefaultTreeModel)dst.getModel(); + + DblTreeNode dstNode = null; + String srcString = srcNode.toString(); + while (dstKids.hasMoreElements()) { + String teststring; + + dstNode = (DblTreeNode)dstKids.nextElement(); + if (dstNode.isLeaf() == false) + break; // leaves come first + teststring = dstNode.toString(); + if (teststring.compareTo(srcString) < 0) { + index++; + continue; + } else { + break; + } + } + + srcModel.removeNodeFromParent(srcNode); + dstModel.insertNodeInto(srcNode, newparent, index); + index++; + return index; + + } + + public void moveBranch(JTree src, JTree dst, DblTreeNode parent, + boolean top, boolean select) { + initBranch(src, dst, parent, top, select, false); + } + + public void initBranch(JTree src, JTree dst, DblTreeNode parent, + boolean top, boolean select, boolean force) { + + DefaultTreeModel srcModel = (DefaultTreeModel)src.getModel(); + DefaultTreeModel dstModel = (DefaultTreeModel)dst.getModel(); + DblTreeNode newparent, clonedParent, root; + + root = (DblTreeNode)dstModel.getRoot(); + + DblTreeNode [] kidsArray = new DblTreeNode[parent.getChildCount()]; + Enumeration kids = parent.children(); + int i = 0; + while (kids.hasMoreElements()) { + kidsArray[i++] = (DblTreeNode)kids.nextElement(); + } + int index = 0; + + // find same branch in destination tree + SelPTreeNode treeNode = matchParent(parent, root, dstModel); + newparent = treeNode.newparent; + + // add all the kids + // At this point we know there is at least one child of dst parent + + for (i = 0; i < kidsArray.length; i++) { + DblTreeNode srcNode = kidsArray[i]; + + if (srcNode.isLeaf() == false) { + initBranch(src, dst, srcNode, false, false, force); + continue; + } + if (force == false && srcNode.isEnabled() == false) + continue; + + Enumeration dstKids = newparent.children(); + index = matchChild(src, dst, srcNode, newparent, dstKids, 0); + } + + if (parent.isRoot() == false) + while (parent.getChildCount() == 0) { + DblTreeNode grandParent; + grandParent = (DblTreeNode) parent.getParent(); + srcModel.removeNodeFromParent(parent); + if (grandParent == null || grandParent.isRoot()) + break; + else + parent = grandParent; + } + + if (newparent.getChildCount() == 0) { + if (top) + while (newparent.getChildCount() == 0) { + DblTreeNode grandParent; + grandParent = (DblTreeNode) newparent.getParent(); + dstModel.removeNodeFromParent(newparent); + if (grandParent == null || grandParent.isRoot()) + break; + else + newparent = grandParent; + } + else + dstModel.removeNodeFromParent(newparent); + } else if (select) { + TreePath nodepath = new TreePath(newparent.getPath()); + + dst.expandPath(nodepath); + // dst.makeVisible(nodepath); + dst.setSelectionPath(nodepath); + dst.scrollPathToVisible(nodepath); + } + + } + + + public void moveLeaf(JTree src, JTree dst, DblTreeNode node) { + + if (node.isEnabled()) + initLeaf(src, dst, node); + TreePath nodepath = new TreePath(node.getPath()); + dst.setSelectionPath(nodepath); + + } + + + public void initLeaf(JTree src, JTree dst, DblTreeNode node) { + + DefaultTreeModel srcModel = (DefaultTreeModel)src.getModel(); + DefaultTreeModel dstModel = (DefaultTreeModel)dst.getModel(); + DblTreeNode parent, newparent, clonedParent, root; + int index = 0; + root = (DblTreeNode)dstModel.getRoot(); + + // find parent + parent = (DblTreeNode)node.getParent(); + + // find same branch in destination tree + + SelPTreeNode treeNode = matchParent(parent, root, dstModel); + newparent = treeNode.newparent; + + Enumeration kids = newparent.children(); + index = matchChild(src, dst, node, newparent, kids, index); + TreePath nodepath = new TreePath(node.getPath()); + + dst.expandPath(nodepath); + dst.scrollPathToVisible(nodepath); + + // check for last child + while ((parent.isRoot() == false) + && parent.getChildCount() == 0) { + DblTreeNode grandParent; + grandParent = (DblTreeNode) parent.getParent(); + srcModel.removeNodeFromParent(parent); + if (grandParent == null) + break; + else + parent = grandParent; + } + + } + + + public void moveAll(JTree src, JTree dst) { + + DefaultTreeModel srcModel = (DefaultTreeModel)src.getModel(); + DblTreeNode srcRoot = (DblTreeNode)srcModel.getRoot(); + + src.clearSelection(); + Enumeration kids = srcRoot.children(); + DblTreeNode [] kidsArray = new DblTreeNode[srcRoot.getChildCount()]; + int i = 0; + while (kids.hasMoreElements()) { + kidsArray[i++] = (DblTreeNode)kids.nextElement(); + } + + for (i = 0; i < kidsArray.length; i++) { + if (kidsArray[i].isLeaf()) + moveLeaf(src, dst, kidsArray[i]); + else + moveBranch(src, dst, kidsArray[i], true, false); + + } + DblTreeNode dstRoot = (DblTreeNode)dst.getModel().getRoot(); + if (dstRoot.getChildCount() > 0) { + DblTreeNode child = (DblTreeNode)dstRoot.getFirstChild(); + TreePath nodepath = new TreePath(child.getPath()); + dst.setSelectionPath(nodepath); + dst.scrollPathToVisible(nodepath); + } + + if (src == srcTree) { + addItem.setEnabled(false); + delItem.setEnabled(true); + } else { + addItem.setEnabled(true); + delItem.setEnabled(false); + } + } + + + public boolean findNode(String findStr) { + + DblTreeNode root; + DblTreeNode otherRoot; + DblTreeNode currentNode; + JTree currentTree; + JTree otherTree; + Enumeration searchNodes; + DefaultTreeModel srcModel = (DefaultTreeModel)srcTree.getModel(); + DefaultTreeModel dstModel = (DefaultTreeModel)dstTree.getModel(); + + TreePath selPath = srcTree.getSelectionPath(); + if (selPath == null) { // Try the other tree + selPath = dstTree.getSelectionPath(); + if (selPath == null) { // Start at the upper left + return false; + } + currentTree = dstTree; + otherTree = srcTree; + root = (DblTreeNode)dstModel.getRoot(); + otherRoot = (DblTreeNode)srcModel.getRoot(); + + } else { + currentTree = srcTree; + otherTree = dstTree; + root = (DblTreeNode)srcModel.getRoot(); + otherRoot = (DblTreeNode)dstModel.getRoot(); + } + + currentNode = (DblTreeNode)selPath.getLastPathComponent(); + + searchNodes = myRowFirstEnumeration(root, null); + Vector fromTop = new Vector(); + while (searchNodes.hasMoreElements()) { + DblTreeNode node = (DblTreeNode) searchNodes.nextElement(); + + if (node == currentNode) { + while (searchNodes.hasMoreElements()) { + node = (DblTreeNode) searchNodes.nextElement(); + String nodeStr = node.toString(); + if (nodeStr.lastIndexOf(findStr) != -1) { + TreePath nodepath = new TreePath(node.getPath()); + currentTree.expandPath(nodepath); + currentTree.setSelectionPath(nodepath); + currentTree.scrollPathToVisible(nodepath); + return true; + } + } + } else { + fromTop.addElement(node); + continue; + } + } + + // Not found in remainder of current tree... + + searchNodes = myRowFirstEnumeration(otherRoot, null); + while (searchNodes.hasMoreElements()) { + DblTreeNode node = (DblTreeNode) searchNodes.nextElement(); + String nodeStr = node.toString(); + if (nodeStr.lastIndexOf(findStr) != -1) { + currentTree.clearSelection(); + TreePath nodepath = new TreePath(node.getPath()); + otherTree.expandPath(nodepath); + otherTree.setSelectionPath(nodepath); + otherTree.scrollPathToVisible(nodepath); + + // Switch buttons + + if (otherTree == srcTree) { + addItem.setEnabled(true); + delItem.setEnabled(false); + } else { + addItem.setEnabled(false); + delItem.setEnabled(true); + } + return true; + } + } + + // Not found in other tree + // Try from top of current tree... + + searchNodes = fromTop.elements(); + while (searchNodes.hasMoreElements()) { + DblTreeNode node = (DblTreeNode) searchNodes.nextElement(); + String nodeStr = node.toString(); + if (nodeStr.lastIndexOf(findStr) != -1) { + TreePath nodepath = new TreePath(node.getPath()); + currentTree.expandPath(nodepath); + currentTree.setSelectionPath(nodepath); + currentTree.scrollPathToVisible(nodepath); + return true; + } else + continue; + } + // Not found in current tree... + return false; + + } + + private Enumeration myRowFirstEnumeration(DblTreeNode root, + Vector v) { + + if (v == null) + v = new Vector(); + Enumeration kids = root.children(); + while (kids.hasMoreElements()) { + DblTreeNode node = (DblTreeNode)kids.nextElement(); + v.addElement(node); + Enumeration gkids = myRowFirstEnumeration(node, v); + } + return v.elements(); + + } + + + public void refreshTrees() { + + JTree currentTree; + JTree dummyTree; + TreePath selPath = srcTree.getSelectionPath(); + if (selPath == null) { + selPath = dstTree.getSelectionPath(); + if (selPath == null) + return; + currentTree = dstTree; + } else { + currentTree = srcTree; + } + + DefaultTreeModel treeModel = + new DefaultTreeModel(new DblTreeNode("dummy")); + dummyTree = new JTree(treeModel); + + moveAll(srcTree, dummyTree); + moveAll(dummyTree, srcTree); + moveAll(dstTree, dummyTree); + moveAll(dummyTree, dstTree); + + if (currentTree == srcTree) { + addItem.setEnabled(true); + delItem.setEnabled(false); + dstTree.setSelectionPath(selPath); + } else { + addItem.setEnabled(false); + delItem.setEnabled(true); + srcTree.setSelectionPath(selPath); + } + + } + + public void resetAll() { + + DblTreeNode srcRoot = (DblTreeNode)srcTree.getModel().getRoot(); + DblTreeNode dstRoot = (DblTreeNode)dstTree.getModel().getRoot(); + + dstTree.clearSelection(); + Enumeration kids = dstRoot.children(); + DblTreeNode [] kidsArray = new DblTreeNode[dstRoot.getChildCount()]; + int i = 0; + while (kids.hasMoreElements()) { + kidsArray[i++] = (DblTreeNode)kids.nextElement(); + } + + for (i = 0; i < kidsArray.length; i++) { + if (kidsArray[i].isLeaf()) + initLeaf(dstTree, srcTree, kidsArray[i]); + else + initBranch(dstTree, srcTree, kidsArray[i], true, false, true); + + } + if (srcRoot.getChildCount() > 0) { + DblTreeNode child = (DblTreeNode)srcRoot.getFirstChild(); + TreePath nodepath = new TreePath(child.getPath()); + srcTree.setSelectionPath(nodepath); + srcTree.scrollPathToVisible(nodepath); + } + + addItem.setEnabled(true); + delItem.setEnabled(false); + } + + public void resetModels() { + srcTree.setModel(new DefaultTreeModel(new DblTreeNode("All Items"))); + dstTree.setModel(new DefaultTreeModel(new DblTreeNode("All Items"))); + } +} + +class SelPTreeNode { + + DblTreeNode newparent; + int index; + + public SelPTreeNode() { + newparent = null; + index = 0; + } +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/Sort.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/Sort.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,384 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + */ + + +/** + * SMC code adapted for Visual Panels + * + * Sort: a class that uses the quicksort algorithm to sort an + * array of objects. + */ + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import java.util.Vector; +import java.util.Random; +import java.lang.Math; + +@SuppressWarnings("unchecked") +public class Sort { + + private static Random rn = null; + + private static int MAX_ELEMENTS_FOR_COPY = 15000; + + static final int ASCENDING_SORT = 0; + static final int DESCENDING_SORT = 0; + + private static void swap(Object arr[], int i, int j) { + Object tmp; + + tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + } + + /** + * quicksort the array of objects. + * + * @param arr[] - an array of objects + * @param left - the start index - from where to begin sorting + * @param right - the last index + * @param comp - object that implemnts the Compare interface + */ + private static void quicksort(Object arr[], int left, int right, + Compare comp) { + + int i, last; + + if (left >= right) { /* do nothing if array contains fewer than two */ + return; /* two elements */ + } + + swap(arr, left, left+(Math.abs(rn.nextInt())%(right-left)+1)); + last = left; + for (i = left+1; i <= right; i++) { + if (comp.doCompare(arr[i], arr[left]) < 0) { + swap(arr, ++last, i); + } + } + swap(arr, left, last); + + quicksort(arr, left, last-1, comp); + quicksort(arr, last+1, right, comp); + } + + /** + * quicksort the array of strings. + * + * @param arr[] - an array of strings + * @param left - the start index - from where to begin sorting + * @param right - the last index. + * @param order - ASCENDING_SORT or DESCENDING_SORT + */ + private static void quicksort(String arr[], int left, int right, + int order) { + + int i, last; + + if (left >= right) { /* do nothing if array contains fewer than two */ + return; /* two elements */ + } + swap(arr, left, left+(Math.abs(rn.nextInt())%(right-left)+1)); + last = left; + for (i = left+1; i <= right; i++) { + if (order == ASCENDING_SORT) { + if (arr[i].compareTo(arr[left]) < 0) { + swap(arr, ++last, i); + } + } else { + if (arr[i].compareTo(arr[left]) > 0) { + swap(arr, ++last, i); + } + } + } + swap(arr, left, last); + quicksort(arr, left, last-1, order); + quicksort(arr, last+1, right, order); + } + + private static void swap(Vector vec, int i, int j) { + Object tmp; + + tmp = vec.elementAt(i); + vec.setElementAt(vec.elementAt(j), i); + vec.setElementAt(tmp, j); + } + + /** + * quicksort the vector of objects. + * + * @param vec - a vector of objects + * @param left - the start index - from where to begin sorting + * @param right - the last index + * @param comp - object that implements the Compare interface + */ + private static void quicksort(Vector vec, int left, int right, + Compare comp) { + + int i, last; + + if (left >= right) { /* do nothing if vector contains fewer than two */ + return; /* two elements */ + } + swap(vec, left, left+(Math.abs(rn.nextInt())%(right-left)+1)); + last = left; + for (i = left+1; i <= right; i++) { + if (comp.doCompare(vec.elementAt(i), vec.elementAt(left)) < 0) { + swap(vec, ++last, i); + } + } + swap(vec, left, last); + quicksort(vec, left, last-1, comp); + quicksort(vec, last+1, right, comp); + } + + /** + * quicksort the vector of strings. + * + * @param vec - a vector of strings + * @param left - the start index - from where to begin sorting + * @param right - the last index. + * @param order - ASCENDING_SORT or DESCENDING_SORT + */ + private static void quicksort(Vector vec, int left, int right, int order) { + int i, last; + + if (left >= right) { /* do nothing if vector contains fewer than two */ + return; /* two elements */ + } + swap(vec, left, left+(Math.abs(rn.nextInt())%(right-left)+1)); + last = left; + for (i = left+1; i <= right; i++) { + if (order == ASCENDING_SORT) { + if (((String)(vec.elementAt(i))).compareTo( + (String)vec.elementAt(left)) < 0) { + swap(vec, ++last, i); + } + } else { + if (((String)(vec.elementAt(i))).compareTo( + (String)vec.elementAt(left)) > 0) { + swap(vec, ++last, i); + } + } + } + swap(vec, left, last); + quicksort(vec, left, last-1, order); + quicksort(vec, last+1, right, order); + } + + /** + * quicksort the vector of objects. + * + * @param vec - a vector of objects + * @param left - the start index - from where to begin sorting + * @param right - the last index + * @param comp - object that implemnts the Compare interface + */ + private static void quicksort(QuickVector vec, int left, int right, + Compare comp) { + + int i, last; + + if (left >= right) { /* do nothing if vector contains fewer than two */ + return; /* two elements */ + } + vec.quickSwapElementsAt(left, + left+(Math.abs(rn.nextInt())%(right-left)+1)); + last = left; + for (i = left+1; i <= right; i++) { + if (comp.doCompare(vec.quickElementAt(i), + vec.quickElementAt(left)) < 0) { + vec.quickSwapElementsAt(++last, i); + } + } + vec.quickSwapElementsAt(left, last); + quicksort(vec, left, last-1, comp); + quicksort(vec, last+1, right, comp); + } + + /** + * quicksort the vector of strings. + * + * @param vec - a vector of strings + * @param left - the start index - from where to begin sorting + * @param right - the last index. + * @param order - ASCENDING_SORT or DESCENDING_SORT + */ + private static void quicksort(QuickVector vec, int left, int right, + int order) { + + int i, last; + + if (left >= right) { /* do nothing if vector contains fewer than two */ + return; /* two elements */ + } + vec.quickSwapElementsAt(left, + left+(Math.abs(rn.nextInt())%(right-left)+1)); + last = left; + for (i = left+1; i <= right; i++) { + if (order == ASCENDING_SORT) { + if (((String)(vec.quickElementAt(i))).compareTo( + (String)vec.quickElementAt(left)) < 0) { + vec.quickSwapElementsAt(++last, i); + } + } else { + if (((String)(vec.quickElementAt(i))).compareTo( + (String)vec.quickElementAt(left)) > 0) { + vec.quickSwapElementsAt(++last, i); + } + } + } + vec.quickSwapElementsAt(left, last); + quicksort(vec, left, last-1, order); + quicksort(vec, last+1, right, order); + } + + /** + * sort the array of objects. + * + * @param arr - a array of objects + * @param comp - object that implemnts the Compare interface + */ + public static void sort(Object arr[], Compare comp) { + if (rn == null) + rn = new Random(); + quicksort(arr, 0, arr.length-1, comp); + } + + /** + * sort the array of strings. + * + * @param arr - an array of strings + * @param order - ASCENDING_SORT or DESCENDING_SORT + */ + public static void sort(String arr[], int order) { + if (rn == null) + rn = new Random(); + quicksort(arr, 0, arr.length-1, order); + } + + /** + * sort the array of strings in ascending order + * + * @param arr - an array of strings + */ + public static void sort(String arr[]) { + sort(arr, ASCENDING_SORT); + } + + /** + * sort the vector of objects. + * + * @param vec - a vector of objects + * @param comp - object that implemnts the Compare interface + */ + public static void sort(Vector vec, Compare comp) { + if (rn == null) + rn = new Random(); + if (vec.size() > MAX_ELEMENTS_FOR_COPY) { + // Would use up too much memory, so have to do an in place sort + quicksort(vec, 0, vec.size()-1, comp); + } else { + // For small vector, optimize the sort by copying to an array + // first + Object[] arr = new Object[vec.size()]; + vec.copyInto(arr); + quicksort(arr, 0, arr.length-1, comp); + for (int i = 0; i < arr.length; i++) { + vec.setElementAt(arr[i], i); + } + } + } + + /** + * sort the vector of strings. + * + * @param vec - a vector of strings + * @param order - ASCENDING_SORT or DESCENDING_SORT + */ + public static void sort(Vector vec, int order) { + if (rn == null) + rn = new Random(); + if (vec.size() > MAX_ELEMENTS_FOR_COPY) { + // Would use up too much memory, so have to do an in place sort + quicksort(vec, 0, vec.size()-1, order); + } else { + // For small vector, we can optimize the sort by copying to an array + // first + String[] arr = new String[vec.size()]; + vec.copyInto(arr); + vec.removeAllElements(); + quicksort(arr, 0, arr.length-1, order); + vec.setSize(arr.length); + for (int i = 0; i < arr.length; i++) { + vec.setElementAt(arr[i], i); + } + } + } + + /** + * sort the vector of strings in ascending order + * + * @param vec - a vector of strings + */ + public static void sort(Vector vec) { + sort(vec, ASCENDING_SORT); + } + + /** + * sort the vector of objects. + * + * @param vec - a vector of objects + * @param comp - object that implemnts the Compare interface + */ + public static void sort(QuickVector vec, Compare comp) { + if (rn == null) + rn = new Random(); + quicksort(vec, 0, vec.size()-1, comp); + } + + /** + * sort the vector of strings. + * + * @param vec - a vector of strings + * @param order - ASCENDING_SORT or DESCENDING_SORT + */ + public static void sort(QuickVector vec, int order) { + if (rn == null) + rn = new Random(); + quicksort(vec, 0, vec.size()-1, order); + } + + /** + * sort the vector of strings in ascending order + * + * @param vec - a vector of strings + */ + public static void sort(QuickVector vec) { + sort(vec, ASCENDING_SORT); + } + +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/TableMap.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/TableMap.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,101 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + */ + + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import javax.swing.table.*; +import javax.swing.event.TableModelListener; +import javax.swing.event.TableModelEvent; + +/** + * SMC code adapted for Visual Panels + * + * In a chain of data manipulators some behaviour is common. TableMap + * provides most of this behavour and can be subclassed by filters + * that only need to override a handful of specific methods. TableMap + * implements TableModel by routing all requests to its model, and + * TableModelListener by routing all events to its listeners. Inserting + * a TableMap which has not been subclassed into a chain of table filters + * should have no effect. + * + * (This code taken from the Swing table examples.) + * + */ +public class TableMap extends AbstractTableModel implements TableModelListener { + + protected TableModel model; + + public TableModel getModel() { + return model; + } + + public void setModel(TableModel model) { + this.model = model; + model.addTableModelListener(this); + } + + // By default, Implement TableModel by forwarding all messages + // to the model. + + public Object getValueAt(int aRow, int aColumn) { + return model.getValueAt(aRow, aColumn); + } + + public void setValueAt(Object aValue, int aRow, int aColumn) { + model.setValueAt(aValue, aRow, aColumn); + } + + public int getRowCount() { + return (model == null) ? 0 : model.getRowCount(); + } + + public int getColumnCount() { + return (model == null) ? 0 : model.getColumnCount(); + } + + public String getColumnName(int aColumn) { + return model.getColumnName(aColumn); + } + + public Class getColumnClass(int aColumn) { + return model.getColumnClass(aColumn); + } + + public boolean isCellEditable(int row, int column) { + return model.isCellEditable(row, column); + } + + + // + // Implementation of the TableModelListener interface, + // + + // By default forward all events to all the listeners. + public void tableChanged(TableModelEvent e) { + fireTableChanged(e); + } + +} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/TableSorter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/TableSorter.java Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,351 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + */ + + +package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import java.util.*; + +import javax.swing.table.TableModel; +import javax.swing.event.TableModelEvent; + +// Imports for picking up mouse events from the JTable. + +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.InputEvent; +import javax.swing.JTable; +import javax.swing.table.JTableHeader; +import javax.swing.table.TableColumn; +import javax.swing.table.TableColumnModel; + + +/** + * SMC code adapted for Visual Panels + * + * A sorter for TableModels. The sorter has a model (conforming to TableModel) + * and itself implements TableModel. TableSorter does not store or copy + * the data in the TableModel, instead it maintains an array of + * integers which it keeps the same size as the number of rows in its + * model. When the model changes it notifies the sorter that something + * has changed eg. "rowsAdded" so that its internal array of integers + * can be reallocated. As requests are made of the sorter (like + * getValueAt(row, col) it redirects them to its model via the mapping + * array. That way the TableSorter appears to hold another copy of the table + * with the rows in a different order. The sorting algorthm used is stable + * which means that it does not move around rows when its comparison + * function returns 0 to denote that they are equivalent. + * + * (This code taken from the Swing table examples.) + * + */ +public class TableSorter extends TableMap { + + int indexes[]; + Vector sortingColumns = new Vector(); + boolean ascending = true; + int compares; + + public TableSorter() { + indexes = new int[0]; // For consistency. + } + + public TableSorter(TableModel model) { + setModel(model); + } + + public void setModel(TableModel model) { + super.setModel(model); + reallocateIndexes(); + } + + public int compareRowsByColumn(int row1, int row2, int column) { + Class type = model.getColumnClass(column); + TableModel data = model; + + // Check for nulls + + Object o1 = data.getValueAt(row1, column); + Object o2 = data.getValueAt(row2, column); + + // If both values are null return 0 + if (o1 == null && o2 == null) + return 0; + else if (o1 == null) // Define null less than everything. + return -1; + else if (o2 == null) + return 1; + + // We copy all returned values from the getValue call in case + // an optimised model is reusing one object to return many values. + // The Number subclasses in the JDK are immutable and so will not + // be used in this way but other subclasses of Number might want + // to do this to save space and avoid unnecessary heap allocation. + + if (type.getSuperclass() == java.lang.Number.class) { + Number n1 = (Number)data.getValueAt(row1, column); + double d1 = n1.doubleValue(); + Number n2 = (Number)data.getValueAt(row2, column); + double d2 = n2.doubleValue(); + + if (d1 < d2) + return -1; + else if (d1 > d2) + return 1; + else + return 0; + } else if (type == java.util.Date.class) { + Date d1 = (Date)data.getValueAt(row1, column); + long n1 = d1.getTime(); + Date d2 = (Date)data.getValueAt(row2, column); + long n2 = d2.getTime(); + + if (n1 < n2) + return -1; + else if (n1 > n2) + return 1; + else + return 0; + } else if (type == String.class) { + String s1 = (String)data.getValueAt(row1, column); + String s2 = (String)data.getValueAt(row2, column); + int result = s1.compareTo(s2); + + if (result < 0) + return -1; + else if (result > 0) + return 1; + else + return 0; + } else if (type == Boolean.class) { + Boolean bool1 = (Boolean)data.getValueAt(row1, column); + boolean b1 = bool1.booleanValue(); + Boolean bool2 = (Boolean)data.getValueAt(row2, column); + boolean b2 = bool2.booleanValue(); + + if (b1 == b2) + return 0; + else if (b1) // Define false < true + return 1; + else + return -1; + } else { + Object v1 = data.getValueAt(row1, column); + String s1 = v1.toString(); + Object v2 = data.getValueAt(row2, column); + String s2 = v2.toString(); + int result = s1.compareTo(s2); + + if (result < 0) + return -1; + else if (result > 0) + return 1; + else + return 0; + } + } + + public int compare(int row1, int row2) { + compares++; + for (int level = 0; level < sortingColumns.size(); level++) { + Integer column = sortingColumns.elementAt(level); + int result = compareRowsByColumn(row1, row2, column.intValue()); + if (result != 0) + return ascending ? result : -result; + } + return 0; + } + + public void reallocateIndexes() { + int rowCount = model.getRowCount(); + + // Set up a new array of indexes with the right number of elements + // for the new data model. + indexes = new int[rowCount]; + + // Initialise with the identity mapping. + for (int row = 0; row < rowCount; row++) + indexes[row] = row; + } + + + /** + * Return the index of the row in the model whose data is being displayed + * in the row viewRowIndex in the display. Returns viewRowIndex unchanged + * viewRowIndex is less than zero. Returns -1 if there are no rows or + * viewRowIndex exceeds the number of rows. + */ + public int convertRowIndexToModel(int viewRowIndex) { + if (viewRowIndex < 0) + return viewRowIndex; + + if ((indexes.length == 0) || (viewRowIndex >= indexes.length)) + return -1; + + return indexes[viewRowIndex]; + } + + public void tableChanged(TableModelEvent e) { + reallocateIndexes(); + + super.tableChanged(e); + } + + public void checkModel() { + if (indexes.length != model.getRowCount()) + System.err.println("Sorter not informed of a change in model."); + } + + public void sort(Object sender) { + checkModel(); + + compares = 0; + // n2sort(); + // qsort(0, indexes.length-1); + shuttlesort(indexes.clone(), indexes, 0, indexes.length); + } + + public void n2sort() { + for (int i = 0; i < getRowCount(); i++) { + for (int j = i+1; j < getRowCount(); j++) { + if (compare(indexes[i], indexes[j]) == -1) { + swap(i, j); + } + } + } + } + + // This is a home-grown implementation which we have not had time + // to research - it may perform poorly in some circumstances. It + // requires twice the space of an in-place algorithm and makes + // NlogN assigments shuttling the values between the two + // arrays. The number of compares appears to vary between N-1 and + // NlogN depending on the initial order but the main reason for + // using it here is that, unlike qsort, it is stable. + public void shuttlesort(int from[], int to[], int low, int high) { + + if (high - low < 2) + return; + + int middle = (low + high)/2; + shuttlesort(to, from, low, middle); + shuttlesort(to, from, middle, high); + + int p = low; + int q = middle; + + // This is an optional short-cut; at each recursive call, + // check to see if the elements in this subset are already + // ordered. If so, no further comparisons are needed; the + // sub-array can just be copied. The array must be copied rather + // than assigned otherwise sister calls in the recursion might + // get out of sinc. When the number of elements is three they + // are partitioned so that the first set, [low, mid), has one + // element and and the second, [mid, high), has two. We skip the + // optimisation when the number of elements is three or less as + // the first compare in the normal merge will produce the same + // sequence of steps. This optimisation seems to be worthwhile + // for partially ordered lists but some analysis is needed to + // find out how the performance drops to Nlog(N) as the initial + // order diminishes - it may drop very quickly. + + if (high - low >= 4 && compare(from[middle-1], from[middle]) <= 0) { + for (int i = low; i < high; i++) + to[i] = from[i]; + + return; + } + + // A normal merge. + + for (int i = low; i < high; i++) { + if (q >= high || (p < middle && compare(from[p], from[q]) <= 0)) + to[i] = from[p++]; + else + to[i] = from[q++]; + } + } + + public void swap(int i, int j) { + int tmp = indexes[i]; + indexes[i] = indexes[j]; + indexes[j] = tmp; + } + + // The mapping only affects the contents of the data rows. + // Pass all requests to these rows through the mapping array: "indexes". + + public Object getValueAt(int aRow, int aColumn) { + checkModel(); + if (indexes.length == 0) + return null; + return model.getValueAt(indexes[aRow], aColumn); + } + + public void setValueAt(Object aValue, int aRow, int aColumn) { + checkModel(); + model.setValueAt(aValue, indexes[aRow], aColumn); + } + + public void sortByColumn(int column) { + sortByColumn(column, true); + } + + public void sortByColumn(int column, boolean ascending) { + this.ascending = ascending; + sortingColumns.removeAllElements(); + sortingColumns.addElement(new Integer(column)); + sort(this); + super.tableChanged(new TableModelEvent(this)); + } + + // There is no-where else to put this. + // Add a mouse listener to the Table to trigger a table sort + // when a column heading is clicked in the JTable. + public void addMouseListenerToHeaderInTable(JTable table) { + + final TableSorter sorter = this; + final JTable tableView = table; + + tableView.setColumnSelectionAllowed(false); + + MouseAdapter listMouseListener = new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + TableColumnModel columnModel = tableView.getColumnModel(); + int viewColumn = columnModel.getColumnIndexAtX(e.getX()); + int column = tableView.convertColumnIndexToModel(viewColumn); + if (e.getClickCount() == 1 && column != -1) { + int shiftPressed = e.getModifiers()&InputEvent.SHIFT_MASK; + boolean ascending = (shiftPressed == 0); + sorter.sortByColumn(column, ascending); + } + } + }; + + JTableHeader th = tableView.getTableHeader(); + th.addMouseListener(listMouseListener); + } + +} // TableSorter diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserManagedObject.java --- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserManagedObject.java Thu Apr 26 00:14:30 2012 -0400 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserManagedObject.java Fri Apr 27 00:52:26 2012 -0400 @@ -25,15 +25,18 @@ package com.oracle.solaris.vp.panels.usermgr.client.swing; -import java.util.List; +import java.util.*; import javax.swing.*; import com.oracle.solaris.vp.panel.common.model.AbstractManagedObject; -import com.oracle.solaris.vp.panels.usermgr.*; +import com.oracle.solaris.rad.usermgr.*; import com.oracle.solaris.vp.util.misc.*; import com.oracle.solaris.vp.util.misc.finder.Finder; import com.oracle.solaris.vp.util.misc.property.*; import com.oracle.solaris.vp.util.swing.HasIcon; +/** + * User Managed Object represents user object + */ @SuppressWarnings({"serial"}) public class UserManagedObject extends AbstractManagedObject implements HasIcon { @@ -41,19 +44,16 @@ // // Static data // + public static final String PASSWORD = "PASSWORD"; + public static final String NOTACTIVE = "NOTACTIVATED"; + // Icons - for user, roles protected static final List userIcons = Finder.getIcons( - "images/config-users-16.png", - "images/config-users-22.png", - "images/config-users-24.png", - "images/config-users-32.png"); + "images/user-24.png"); protected static final List roleIcons = Finder.getIcons( - "images/config-roles-16.png", - "images/config-roles-22.png", - "images/config-roles-24.png", - "images/config-roles-32.png"); + "images/role-24.png"); // // Instance data @@ -62,6 +62,7 @@ private UserMgrPanelDescriptor descriptor; private UserType type = UserType.NORMAL; private boolean isNewUser = false; + private UserChangeFieldsImpl modChanges = null; private MutableProperty groupIdProperty = new LongProperty(); @@ -69,8 +70,17 @@ private MutableProperty homeDirProperty = new StringProperty(); - private MutableProperty isAdminProperty = - new BooleanProperty(); + private MutableProperty rightsProperty = + new StringProperty(); + + private MutableProperty rolesProperty = + new StringProperty(); + + private MutableProperty groupsProperty = + new StringProperty(); + + private MutableProperty authsProperty = + new StringProperty(); private MutableProperty shellProperty = new StringProperty(); @@ -84,12 +94,16 @@ private MutableProperty userNameProperty = new StringProperty(); + private MutableProperty accountStatusProperty = + new StringProperty(); + private MutableProperty passProperty = new BasicMutableProperty(); { ChangeableAggregator aggregator = getChangeableAggregator(); aggregator.addChangeables(groupIdProperty, homeDirProperty, - isAdminProperty, passProperty, shellProperty, + passProperty, shellProperty, + rolesProperty, rightsProperty, authsProperty, groupsProperty, userDescProperty, userIdProperty, userNameProperty); } @@ -98,7 +112,7 @@ // UserManagedObject(UserMgrPanelDescriptor descriptor, - User user, UserType type, boolean isAdministrator, + User user, UserType type, char[] password, boolean bNewUser) { this.descriptor = descriptor; @@ -111,13 +125,22 @@ groupIdProperty.update(user.getGroupID(), true); homeDirProperty.update(user.getHomeDirectory(), true); shellProperty.update(user.getDefaultShell(), true); - passProperty.update(password, true); - isAdminProperty.update(isAdministrator, true); + + rolesProperty.update(listToString(user.getRoles()), true); + rightsProperty.update(listToString(user.getProfiles()), true); + authsProperty.update(listToString(user.getAuths()), true); + groupsProperty.update(listToString(user.getGroups()), true); + accountStatusProperty.update(user.getAccountStatus() == null ? "" + : user.getAccountStatus(), true); + + if (password != null) { + passProperty.update(password, true); + } } UserManagedObject(UserMgrPanelDescriptor descriptor, User user, char[] password) { - this(descriptor, user, UserType.NORMAL, false, password, true); + this(descriptor, user, UserType.NORMAL, password, true); } // @@ -148,19 +171,34 @@ @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("\n\tuser name: ").append(getUsername()) - .append("\n\tuserID: ").append(getUserId()) - .append("\n\tgroupID: ").append(getGroupId()) + sb.append("\n\tname: ").append(getUsername()) + .append("\n\tuid: ").append(getUserId()) + .append("\n\tgid: ").append(getGroupId()) .append("\n\tdescription: ").append(getUserDescription()) .append("\n\thome dir: ").append(getHomedir()) - .append("\n\tdefault shell: ").append(getShell()) - .append("\n\tuser type: ") - .append(type == UserType.NORMAL ? "normal" : "role") - .append("\n\tadmin: ") - .append(isAdministrator() ? "true" : "false"); + .append("\n\tshell: ").append(getShell()) + .append("\n\ttype: ") + .append(type == UserType.NORMAL ? "user" : "role") + .append("\n\trights: ").append(getRights()) + .append("\n\tauths: ").append(getAuths()) + .append("\n\tgroups: ").append(getGroups()) + .append("\n\troles: ").append(getRoles()) + .append("\n\tstatus: ").append(getAccountStatus()); return sb.toString(); } + public void setUser(User user, char[] password) { + + userNameProperty.update(user.getUsername(), true); + userDescProperty.update(user.getDescription(), true); + userIdProperty.update(user.getUserID(), true); + groupIdProperty.update(user.getGroupID(), true); + homeDirProperty.update(user.getHomeDirectory(), true); + shellProperty.update(user.getDefaultShell(), true); + + passProperty.update(password, true); + } + // // UserManagedObject methods // @@ -173,8 +211,21 @@ return homeDirProperty; } - public MutableProperty getIsAdminProperty() { - return isAdminProperty; + + public MutableProperty getRightsProperty() { + return rightsProperty; + } + + public MutableProperty getRolesProperty() { + return rolesProperty; + } + + public MutableProperty getGroupsProperty() { + return groupsProperty; + } + + public MutableProperty getAuthsProperty() { + return authsProperty; } public MutableProperty getUserDescProperty() { @@ -209,10 +260,6 @@ return userDescProperty.getValue(); } - public boolean isAdministrator() { - return isAdminProperty.getValue(); - } - public long getUserId() { return userIdProperty.getValue(); } @@ -237,11 +284,31 @@ return type; } + public String getRights() { + return rightsProperty.getValue(); + } + + public String getRoles() { + return rolesProperty.getValue(); + } + + public String getGroups() { + return groupsProperty.getValue(); + } + + public String getAuths() { + return authsProperty.getValue(); + } + + public String getAccountStatus() { + return accountStatusProperty.getValue(); + } + public boolean isUserNormal() { return type == UserType.NORMAL; } - public boolean isUserRole() { + public boolean isRole() { return type == UserType.ROLE; } @@ -249,6 +316,14 @@ return isNewUser; } + public boolean hasPassword() { + if (getAccountStatus().equals(PASSWORD)) { + return (true); + } + + return (false); + } + // Update the "auto-generated" properties for the newly created user public void updateUser(User user) { userIdProperty.update(user.getUserID(), true); @@ -258,6 +333,7 @@ // Construct a new User object from the defined properties public User getNewUser() { + UserImpl newUser = new UserImpl(); newUser.setUsername(getUsername()); newUser.setUserID(getUserId()); @@ -267,7 +343,27 @@ newUser.setHomeDirectory(getHomedir()); else // must be null newUser.setHomeDirectory(null); + newUser.setDefaultShell(getShell()); + + if (getRights() != null) { + // System.out.println("new user rights:" + getRights()); + newUser.setProfiles(stringToList(getRights())); + } + + if (getRoles() != null) { + // System.out.println("new user roles:" + getRoles()); + newUser.setRoles(stringToList(getRoles())); + } + + if (getAuths() != null) { + newUser.setAuths(stringToList(getAuths())); + } + + if (getGroups() != null) { + newUser.setGroups(stringToList(getGroups())); + } + return newUser; } @@ -275,6 +371,8 @@ public User getModifiedUser() { boolean bChanged = false; UserImpl modUser = new UserImpl(); + modChanges = new UserChangeFieldsImpl(); + // check each property for changes if (userDescProperty.isChanged()) { modUser.setDescription(getUserDescription()); @@ -291,7 +389,35 @@ if (passProperty.isChanged()) { bChanged = true; } - // If *only* the admin property is changed, the User object is not used. + + if (rightsProperty.isChanged()) { + // System.out.println("mod user rights " + getRights()); + modUser.setProfiles(stringToList(getRights())); + modChanges.setProfilesChanged(true); + bChanged = true; + } + + if (rolesProperty.isChanged()) { + // System.out.println("mod user roles " + getRoles()); + modUser.setRoles(stringToList(getRoles())); + modChanges.setRolesChanged(true); + bChanged = true; + } + + if (authsProperty.isChanged()) { + // System.out.println("mod user auths " + getAuths()); + modUser.setAuths(stringToList(getAuths())); + modChanges.setAuthsChanged(true); + bChanged = true; + } + + if (groupsProperty.isChanged()) { + // System.out.println("mod user groups " + getGroups()); + modUser.setGroups(stringToList(getGroups())); + modChanges.setGroupsChanged(true); + bChanged = true; + } + if (bChanged) { modUser.setUsername(getUsername()); } else { @@ -300,4 +426,40 @@ return modUser; } + + public String listToString(List list) { + String str; + + if (list == null) { + return (""); + } + + if (list.size() > 0) { + str = list.get(0); + } else { + str = ""; + } + + for (int i = 1; i < list.size(); i++) { + str = str.concat(","); + str = str.concat(list.get(i)); + } + + return (str); + } + + public List stringToList(String str) { + List list = new ArrayList(); + String[] strings = str.split(","); + + for (String s : strings) { + list.add(s); + } + + return (list); + } + + public UserChangeFieldsImpl getModifiedChanges() { + return (modChanges); + } } diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrAdvancedControl.java --- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrAdvancedControl.java Thu Apr 26 00:14:30 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,142 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. - */ - -package com.oracle.solaris.vp.panels.usermgr.client.swing; - -import java.util.List; -import com.oracle.solaris.vp.panel.common.action.*; -import com.oracle.solaris.vp.panel.common.control.Control; -import com.oracle.solaris.vp.panel.swing.control.SettingsControl; -import com.oracle.solaris.vp.panels.usermgr.Group; -import com.oracle.solaris.vp.util.misc.finder.Finder; - -public class UserMgrAdvancedControl - extends SettingsControl { - - // - // Static data - // - public static final String ID = "advanced"; - public static final String NAME = Finder.getString("usermgr.advanced.name"); - - // - // Instance data - // - - private UserMgrControl parent; - - // - // Constructor - // - public UserMgrAdvancedControl(UserMgrControl parent) { - super(ID, NAME, parent.getPanelDescriptor()); - this.parent = parent; - - } - - // - // Control methods - // - - @Override - protected UnsavedChangesAction getUnsavedChangesAction() { - // Always save changes on the client - return UnsavedChangesAction.SAVE; - } - - @Override - protected boolean isChanged() { - // Save unconditionally for now - return true; - } - - @Override - protected void save() throws ActionAbortedException, - ActionFailedException, ActionUnauthorizedException { - - UserMgrAdvancedPanel panel = getComponent(); - UserManagedObject umo = parent.getUserManagedObject(); - - setPropertyChangeIgnore(true); - // Set changed values from the panel - if (panel.getGroupNameProperty().isChanged()) { - umo.getGroupIdProperty().setValue(toGid( - panel.getGroupNameProperty().getValue())); - } - - if (panel.getShellProperty().isChanged()) { - umo.getShellProperty().setValue( - panel.getShellProperty().getValue()); - } - - try { - if (umo.isNewUser()) { - if (panel.getUserIdProperty().isChanged()) { - Long luid = panel.getUserIdProperty().getValue(); - UserMgrUtils.validateUID(luid); - umo.getUserIdProperty().setValue(luid); - } - if (panel.getHomeDirProperty().isChanged()) { - String homeDir = panel.getHomeDirProperty().getValue(); - UserMgrUtils.validateHomeDir(homeDir); - umo.getHomeDirProperty().setValue(homeDir); - } - } - } catch (NumberFormatException nfe) { - throw new ActionFailedException( - Finder.getString("usermgr.advanced.error.uid.bad")); - } finally { - setPropertyChangeIgnore(false); - } - } - - // - // SwingControl Methods - // - - @Override - protected UserMgrAdvancedPanel createComponent() { - return new UserMgrAdvancedPanel(); - } - - @Override - protected void initComponent() { - UserMgrAdvancedPanel panel = getComponent(); - // Initialize the fields - panel.init(parent.getPanelDescriptor(), parent.getUserManagedObject()); - } - - // - // Private Methods - // - private long toGid(String gName) { - List groups = parent.getPanelDescriptor().getGroups(); - for (Group g : groups) { - if (gName.equals(g.getGroupName())) - return (g.getGroupID()); - } - return 1L; - } -} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrAdvancedPanel.java --- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrAdvancedPanel.java Thu Apr 26 00:14:30 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,275 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. - */ - -package com.oracle.solaris.vp.panels.usermgr.client.swing; - -import java.awt.EventQueue; -import javax.swing.*; -import com.oracle.solaris.vp.panel.swing.view.ChangeIndicator; -import com.oracle.solaris.vp.panels.usermgr.Group; -import com.oracle.solaris.vp.util.misc.ChangeableAggregator; -import com.oracle.solaris.vp.util.misc.finder.Finder; -import com.oracle.solaris.vp.util.misc.property.*; -import com.oracle.solaris.vp.util.swing.*; -import com.oracle.solaris.vp.util.swing.layout.*; -import com.oracle.solaris.vp.util.swing.property.ComboBoxPropertySynchronizer; - -@SuppressWarnings({"serial"}) -public class UserMgrAdvancedPanel extends SettingsPanel { - // - // Instance data - // - private JLabel userIdLabel; - private HintTextField userIdField; - private ChangeIndicator userIdChange; - private JLabel userIdROLabel; - private JLabel userIdROField; - private JLabel userIdROSpacer; - private JLabel homeDirLabel; - private HintTextField homeDirField; - private ChangeIndicator homeDirChange; - private JLabel homeDirROLabel; - private JLabel homeDirROField; - private JLabel homeDirROSpacer; - private JComboBox groupNameCombo; - private JComboBox shellCombo; - private MutableProperty groupNameProperty = new StringProperty(); - private MutableProperty userIdProperty = new LongProperty(); - private MutableProperty homeDirProperty = new StringProperty(); - private MutableProperty shellProperty = new StringProperty(); - - { - ChangeableAggregator aggregator = getChangeableAggregator(); - aggregator.addChangeables(userIdProperty, groupNameProperty, - homeDirProperty, shellProperty); - } - - // - // Constructors - // - - public UserMgrAdvancedPanel() { - JPanel form = createForm(); - setContent(form, false, false); - } - - // - // Advanced panel methods - // - public MutableProperty getUserIdProperty() { - return userIdProperty; - } - - public MutableProperty getHomeDirProperty() { - return homeDirProperty; - } - - public MutableProperty getGroupNameProperty() { - return groupNameProperty; - } - - public MutableProperty getShellProperty() { - return shellProperty; - } - - public void init(UserMgrPanelDescriptor descriptor, UserManagedObject umo) { - // Sanity check -- the UI should be updated only on the event thread - assert EventQueue.isDispatchThread(); - - // Show editable vs. non-editable fields, init labels - showFields(umo.isNewUser()); - initLabels(umo.isUserNormal()); - - // user id - if (!umo.isNewUser()) { - userIdROField.setText(Long.toString(umo.getUserId())); - } - userIdProperty.update(umo.getUserIdProperty().getSavedValue(), false); - - // homedir - if (!umo.isNewUser()) { - homeDirROField.setText(umo.getHomedir()); - } - homeDirProperty.update(umo.getHomeDirProperty().getSavedValue(), false); - - // group - long gid = umo.getGroupId(); - String gname = null; - long savedGid = umo.getGroupIdProperty().getSavedValue(); - String savedGname = null; - if (groupNameCombo.getItemCount() > 0) - groupNameCombo.removeAllItems(); - for (Group g : descriptor.getGroups()) { - groupNameCombo.addItem(g.getGroupName()); - if (gid == g.getGroupID()) - gname = g.getGroupName(); - if (savedGid == g.getGroupID()) - savedGname = g.getGroupName(); - } - groupNameProperty.update(savedGname, false); - groupNameCombo.setSelectedItem(gname); - - // shell - if (shellCombo.getItemCount() > 0) - shellCombo.removeAllItems(); - for (String s : descriptor.getShells()) - shellCombo.addItem(s); - shellProperty.update(umo.getShellProperty().getSavedValue(), false); - shellCombo.setSelectedItem(umo.getShell()); - } - - // - // Private methods - // - - private JPanel createForm() { - // Create the form elements - int hGap = GUIUtil.getHalfGap(); - int width = GUIUtil.getTextFieldWidth(); - - // User Id - userIdLabel = new JLabel(); - userIdField = new HintTextField(width); - userIdField.setHintText( - Finder.getString("usermgr.advanced.value.auto")); - userIdField.setDocument(new NumericDocument()); - new HintTextPropertySynchronizer(userIdProperty, - userIdField, 0L); - userIdChange = new ChangeIndicator(); - userIdProperty.addChangeListener(userIdChange); - userIdProperty.save(); - - // Readonly fields - userIdROLabel = new JLabel(); - userIdROField = new JLabel(); - userIdROSpacer = new JLabel(); - - // Group Name - JLabel groupNameLabel = new JLabel( - Finder.getString("usermgr.advanced.label.group")); - groupNameCombo = new JComboBox(); - new ComboBoxPropertySynchronizer - (groupNameProperty, groupNameCombo); - ChangeIndicator groupNameChange = new ChangeIndicator(); - groupNameProperty.addChangeListener(groupNameChange); - - // Home Directory - homeDirLabel = new JLabel( - Finder.getString("usermgr.advanced.label.homedir")); - homeDirField = new HintTextField(width); - homeDirField.setHintText( - Finder.getString("usermgr.advanced.value.auto")); - new HintTextPropertySynchronizer(homeDirProperty, - homeDirField, ""); - homeDirChange = new ChangeIndicator(); - homeDirProperty.addChangeListener(homeDirChange); - - // Readonly fields - homeDirROLabel = new JLabel( - Finder.getString("usermgr.advanced.label.homedir")); - homeDirROField = new JLabel(); - homeDirROSpacer = new JLabel(); - - // Login Shell - JLabel shellLabel = new JLabel( - Finder.getString("usermgr.advanced.label.shell")); - shellCombo = new JComboBox(); - new ComboBoxPropertySynchronizer(shellProperty, shellCombo); - ChangeIndicator shellChange = new ChangeIndicator(); - shellProperty.addChangeListener(shellChange); - - showFields(false); - - // Create the form and add the form elements - JPanel formPanel = new JPanel(); - formPanel.setOpaque(false); - Form form = new Form(formPanel, VerticalAnchor.TOP); - - ColumnLayoutConstraint col = new ColumnLayoutConstraint( - HorizontalAnchor.FILL, hGap); - HasAnchors a = new SimpleHasAnchors( - HorizontalAnchor.LEFT, VerticalAnchor.CENTER); - - form.addTable(3, hGap, hGap, HorizontalAnchor.LEFT, col); - form.add(userIdLabel, a); - form.add(userIdField, a); - form.add(userIdChange, a); - - form.add(userIdROLabel, a); - form.add(userIdROField, a); - form.add(userIdROSpacer, a); - - form.add(groupNameLabel, a); - form.add(groupNameCombo, a); - form.add(groupNameChange, a); - - form.add(homeDirLabel, a); - form.add(homeDirField, a); - form.add(homeDirChange, a); - - form.add(homeDirROLabel, a); - form.add(homeDirROField, a); - form.add(homeDirROSpacer, a); - - form.add(shellLabel, a); - form.add(shellCombo, a); - form.add(shellChange, a); - - return formPanel; - } - - private void showFields(boolean bNewUser) { - // Editable - userIdLabel.setVisible(bNewUser); - userIdField.setVisible(bNewUser); - userIdChange.setVisible(bNewUser); - homeDirLabel.setVisible(bNewUser); - homeDirField.setVisible(bNewUser); - homeDirChange.setVisible(bNewUser); - // Readonly - userIdROLabel.setVisible(!bNewUser); - userIdROField.setVisible(!bNewUser); - userIdROSpacer.setVisible(!bNewUser); - homeDirROLabel.setVisible(!bNewUser); - homeDirROField.setVisible(!bNewUser); - homeDirROSpacer.setVisible(!bNewUser); - } - - private void initLabels(boolean bNormalUser) { - if (bNormalUser) { - // Normal user - userIdLabel.setText( - Finder.getString("usermgr.advanced.label.uid")); - userIdROLabel.setText( - Finder.getString("usermgr.advanced.label.uid")); - } else { - // Role - userIdLabel.setText( - Finder.getString("usermgr.advanced.label.roleid")); - userIdROLabel.setText( - Finder.getString("usermgr.advanced.label.roleid")); - } - } -} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrBasicControl.java --- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrBasicControl.java Thu Apr 26 00:14:30 2012 -0400 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrBasicControl.java Fri Apr 27 00:52:26 2012 -0400 @@ -25,9 +25,13 @@ package com.oracle.solaris.vp.panels.usermgr.client.swing; + +import java.util.List; +import java.util.Map; +import com.oracle.solaris.rad.usermgr.*; import com.oracle.solaris.vp.panel.common.action.*; -import com.oracle.solaris.vp.panel.common.control.Control; -import com.oracle.solaris.vp.panel.swing.control.SettingsControl; +import com.oracle.solaris.vp.panel.common.control.*; +import com.oracle.solaris.vp.panel.swing.control.*; import com.oracle.solaris.vp.util.misc.finder.Finder; public class UserMgrBasicControl @@ -36,21 +40,19 @@ // // Static data // - public static final String ID = "basic"; - public static final String NAME = Finder.getString("usermgr.basic.name"); + public static final String ID = "usermgr"; + public static final String PARAM_USER = "user"; + private UserMgrPanelDescriptor descriptor; // // Instance data // - private UserMgrControl parent; + private UserManagedObject userMO; - // - // Constructor - // - public UserMgrBasicControl(UserMgrControl parent) { - super(ID, NAME, parent.getPanelDescriptor()); - this.parent = parent; + public UserMgrBasicControl(UserMgrPanelDescriptor descriptor) { + super(ID, PARAM_USER, descriptor); + this.descriptor = descriptor; } // @@ -58,11 +60,17 @@ // @Override + public boolean isBrowsable() { + // This control requires init parameters + return false; + } + + @Override protected boolean isChanged() { - // Save unconditionally for now return true; } + @Override protected UnsavedChangesAction getUnsavedChangesAction() { // Always save changes on the client @@ -74,32 +82,41 @@ ActionFailedException, ActionUnauthorizedException { UserMgrBasicPanel panel = getComponent(); - UserManagedObject umo = parent.getUserManagedObject(); + UserManagedObject umo = getUserManagedObject(); setPropertyChangeIgnore(true); - try { - // Set the values from the panel - if (panel.getUserDescProperty().isChanged()) { - String userdesc = panel.getUserDescProperty().getValue(); - UserMgrUtils.validateUserDesc(userdesc); - umo.getUserDescProperty().setValue(userdesc); - } + + // Set changed values from the panel + if (panel.getGroupProperty().isChanged()) { + umo.getGroupIdProperty().setValue(toGid( + panel.getGroupProperty().getValue())); + } + + if (panel.getShellProperty().isChanged()) { + umo.getShellProperty().setValue( + panel.getShellProperty().getValue()); + } - if (panel.getIsAdminProperty().isChanged()) { - boolean admin = panel.getIsAdminProperty().getValue(); - umo.getIsAdminProperty().setValue(admin); - } + // Set the values from the panel + if (panel.getDescProperty().isChanged()) { + String userdesc = panel.getDescProperty().getValue(); + UserMgrUtils.validateUserDesc(userdesc); + umo.getUserDescProperty().setValue(userdesc); + } - if (panel.getPassProperty().isChanged() || - panel.getPassConfirmProperty().isChanged()) { - char[] pass1 = panel.getPassProperty().getValue(); - char[] pass2 = panel.getPassConfirmProperty().getValue(); - UserMgrUtils.validatePassword(umo.isNewUser(), pass1, pass2); - umo.getPassProperty().setValue(pass1); - } - } finally { - setPropertyChangeIgnore(false); - } + if (panel.getHomeProperty().isChanged()) { + String homeDir = panel.getHomeProperty().getValue(); + UserMgrUtils.validateHomeDir(homeDir); + umo.getHomeDirProperty().setValue(homeDir); + } + + if (panel.getPassProperty().isChanged() || + panel.getPassConfirmProperty().isChanged()) { + char[] pass1 = panel.getPassProperty().getValue(); + char[] pass2 = panel.getPassConfirmProperty().getValue(); + UserMgrUtils.validatePassword(umo.isNewUser(), pass1, pass2); + umo.getPassProperty().setValue(pass1); + } } // @@ -108,16 +125,72 @@ @Override protected UserMgrBasicPanel createComponent() { - UserMgrBasicPanel panel = new UserMgrBasicPanel(); + UserMgrBasicPanel panel = new UserMgrBasicPanel(descriptor); return panel; } @Override protected void initComponent() { UserMgrBasicPanel panel = getComponent(); - UserManagedObject umo = parent.getUserManagedObject(); + UserManagedObject umo = getUserManagedObject(); // Initialize the panel - panel.init(umo); + panel.init(getPanelDescriptor(), umo); + } + + private long toGid(String gName) { + List groups = getPanelDescriptor().getGroups(); + for (Group g : groups) { + if (gName.equals(g.getGroupName())) + return (g.getGroupID()); + } + return 1L; + } + + @Override + public void start(Navigator navigator, Map parameters) + throws NavigationAbortedException, InvalidParameterException, + NavigationFailedException { + + String param = getParameter(parameters, PARAM_USER); + UserManagedObject umo = + getPanelDescriptor().getUserManagedObject(param); + if (umo == null) { + throw new InvalidParameterException(getId(), PARAM_USER, param); + } + + setUserManagedObject(umo); + + super.start(navigator, parameters); + } + + @Override + public void stop(boolean isCancel) throws NavigationAbortedException { + super.stop(isCancel); + setUserManagedObject(null); + } + + // + // UserMgrControl methods + // + + public UserManagedObject getUserManagedObject() { + return userMO; + } + + // + // Private methods + // + + private void setUserManagedObject(UserManagedObject umo) { + this.userMO = umo; + setName(umo == null ? null : umo.getName()); + } + + /** + * Clear the advanced settings change state. + */ + public void clearChanges() { + getComponent().clearChanges(); } } diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrBasicPanel.java --- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrBasicPanel.java Thu Apr 26 00:14:30 2012 -0400 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrBasicPanel.java Fri Apr 27 00:52:26 2012 -0400 @@ -25,23 +25,48 @@ package com.oracle.solaris.vp.panels.usermgr.client.swing; -import java.awt.EventQueue; +import java.awt.*; +import java.awt.event.*; import javax.swing.*; +import javax.swing.border.Border; import com.oracle.solaris.vp.panel.swing.view.ChangeIndicator; import com.oracle.solaris.vp.util.misc.ChangeableAggregator; import com.oracle.solaris.vp.util.misc.finder.Finder; import com.oracle.solaris.vp.util.misc.property.*; +import com.oracle.solaris.rad.usermgr.*; import com.oracle.solaris.vp.util.swing.*; import com.oracle.solaris.vp.util.swing.layout.*; import com.oracle.solaris.vp.util.swing.property.*; +/** + * User Manager Basic panel + */ @SuppressWarnings({"serial"}) -public class UserMgrBasicPanel extends SettingsPanel { +public class UserMgrBasicPanel extends SettingsPanel + implements ActionListener { + private static final String ACTION_ADV_SETTINGS = "settings"; + // // Inner class // + private JLabel nameLabel; + private JLabel nameField; + private JLabel uidLabel; + private JLabel uidField; + private JLabel descLabel; + private JTextField findField; + private JTextField descField; + private JComboBox groupCombo; + private HintTextField homeField; + private JComboBox shellCombo; + private UserManagedObject umo; + private AdvancedSettingsDialog advDialog = null; + private ActionString actString = null; + ChangeIndicator settingsChange; + String changepassStr; public class PasswordPanel extends LinkCollapsiblePane { + // // Instance data // @@ -63,23 +88,31 @@ public PasswordPanel() { super(GUIUtil.getHalfGap()); - int width = GUIUtil.getTextFieldWidth(); + changepassStr = Finder.getString("usermgr.basic.label.changepass"); - passLabel = new JLabel( - Finder.getString("usermgr.basic.label.pass")); + int width = GUIUtil.getTextFieldWidth(); + actString = new ActionString("usermgr.basic.label.pass"); + passLabel = new JLabel(actString.getString()); + passLabel.setDisplayedMnemonic(actString.getMnemonic()); + passField = new JPasswordField(width); new PasswordFieldPropertySynchronizer(passProperty, passField); ChangeIndicator passChange = new ChangeIndicator(); passProperty.addChangeListener(passChange); + passLabel.setLabelFor(passField); - passConfirmLabel = new JLabel( - Finder.getString("usermgr.basic.label.passconfirm")); + actString = new ActionString("usermgr.basic.label.passconfirm"); + passConfirmLabel = new JLabel(actString.getString()); + passConfirmLabel.setDisplayedMnemonic(actString.getMnemonic()); + passConfirmField = new JPasswordField(width); new PasswordFieldPropertySynchronizer( passConfirmProperty, passConfirmField); ChangeIndicator passConfirmChange = new ChangeIndicator(); passConfirmProperty.addChangeListener(passConfirmChange); + passConfirmLabel.setLabelFor(passConfirmField); + // Create the form and the form elements JPanel formPanel = new JPanel(); formPanel.setOpaque(false); @@ -119,7 +152,7 @@ @Override public String getLinkText(boolean collapsed) { - return Finder.getString("usermgr.basic.label.changepass"); + return (changepassStr); } // @@ -141,40 +174,55 @@ private ChangeableAggregator aggregator; private PasswordPanel passPanel; - private JLabel userNameLabel; - private JLabel userNameValue; - private JLabel userDescLabel; + private MutableProperty descProperty = new StringProperty(); + private MutableProperty groupProperty = new StringProperty(); + private MutableProperty homeProperty = new StringProperty(); + private MutableProperty shellProperty = new StringProperty(); + private MutableProperty settingsProperty = new BooleanProperty(); - private MutableProperty userDescProperty = - new StringProperty(); - private MutableProperty isAdminProperty = - new BooleanProperty(); + private UserMgrPanelDescriptor descriptor; // // Constructors // - public UserMgrBasicPanel() { + public UserMgrBasicPanel(UserMgrPanelDescriptor descriptor) { + this.descriptor = descriptor; JPanel form = createForm(); setContent(form, false, false); aggregator = getChangeableAggregator(); - aggregator.addChangeables(userDescProperty); - aggregator.addChangeables(isAdminProperty); + aggregator.addChangeables(descProperty); + aggregator.addChangeables(groupProperty); + aggregator.addChangeables(homeProperty); + aggregator.addChangeables(shellProperty); + aggregator.addChangeables(settingsProperty); aggregator.addChangeables(getPassProperty()); aggregator.addChangeables(getPassConfirmProperty()); } // - // BasicUserMgrPanel methods + // UserMgrBasicPanel methods // - public MutableProperty getUserDescProperty() { - return userDescProperty; + public MutableProperty getDescProperty() { + return descProperty; + } + + public MutableProperty getGroupProperty() { + return groupProperty; } - public MutableProperty getIsAdminProperty() { - return isAdminProperty; + public MutableProperty getHomeProperty() { + return homeProperty; + } + + public MutableProperty getShellProperty() { + return shellProperty; + } + + public MutableProperty getSettingsProperty() { + return settingsProperty; } public MutableProperty getPassProperty() { @@ -185,24 +233,67 @@ return passPanel.passConfirmProperty; } - public void init(UserManagedObject umo) { + public void init(UserMgrPanelDescriptor paneldesc, UserManagedObject umo) { // Sanity check -- the UI should be updated only on the event thread assert EventQueue.isDispatchThread(); - // Toggle the labels for roles - initLabels(umo.isUserNormal()); + + this.umo = umo; + descriptor = paneldesc; // Set the current and saved values for each property - userNameValue.setText(umo.getName()); + nameField.setText(umo.getName()); + Long uidValue = new Long(umo.getUserId()); + uidField.setText(uidValue.toString()); + + descProperty.update(umo.getUserDescProperty().getSavedValue(), false); + descField.setText(umo.getUserDescription()); - userDescProperty.update( - umo.getUserDescProperty().getSavedValue(), false); - isAdminProperty.update(umo.getIsAdminProperty().getSavedValue(), false); + // group + long gid = umo.getGroupId(); + String gname = null; + long savedGid = umo.getGroupIdProperty().getSavedValue(); + String savedGname = null; + if (groupCombo.getItemCount() > 0) + groupCombo.removeAllItems(); + for (Group g : descriptor.getGroups()) { + groupCombo.addItem(g.getGroupName()); + if (gid == g.getGroupID()) + gname = g.getGroupName(); + if (savedGid == g.getGroupID()) + savedGname = g.getGroupName(); + } + groupProperty.update(savedGname, false); + groupCombo.setSelectedItem(gname); + + // homedir + if (!umo.isNewUser()) { + homeField.setText(umo.getHomedir()); + } + homeProperty.update(umo.getHomeDirProperty().getSavedValue(), false); + + // shell + if (shellCombo.getItemCount() > 0) + shellCombo.removeAllItems(); + for (String s : descriptor.getShells()) + shellCombo.addItem(s); + shellProperty.update(umo.getShellProperty().getSavedValue(), false); + shellCombo.setSelectedItem(umo.getShell()); + + // Password getPassProperty().update(umo.getPassProperty().getSavedValue(), false); getPassConfirmProperty().update( umo.getPassProperty().getSavedValue(), false); - passPanel.setCollapsed(!getPassProperty().isChanged()); + if (umo.hasPassword()) { + changepassStr = Finder.getString("usermgr.basic.label.changepass"); + } else { + changepassStr = Finder.getString("usermgr.basic.label.initialpass"); + } + + passPanel.setCollapsed(true); + + settingsProperty.update(false, true); } // @@ -210,76 +301,191 @@ // private JPanel createForm() { - // Create the form elements - // User name - Readonly - userNameLabel = new JLabel(); - userNameValue = new JLabel(); + JPanel form = new JPanel(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + int width = GUIUtil.getTextFieldWidth(); + int hGap = GUIUtil.getHalfGap(); + + gbc.weightx = 1.0; + gbc.anchor = GridBagConstraints.LINE_START; + gbc.fill = GridBagConstraints.NONE; + gbc.insets = new Insets(0, 0, hGap, hGap); + + // User name + actString = new ActionString("usermgr.basic.name." + + descriptor.getTypeString()); + nameLabel = new JLabel(actString.getString()); + + nameField = new JLabel(); + + // Add to the layout + gbc.gridx = 0; + gbc.gridy = 0; + form.add(nameLabel, gbc); + gbc.gridx = GridBagConstraints.RELATIVE; + form.add(nameField, gbc); + form.add(new Spacer(), gbc); - // User Description - userDescLabel = new JLabel(); - JTextField userDescField = GUIUtil.createTextField(); + // Description + actString = new ActionString("usermgr.basic.desc." + + descriptor.getTypeString()); + descLabel = new JLabel(actString.getString()); + descLabel.setDisplayedMnemonic(actString.getMnemonic()); + descField = GUIUtil.createTextField(); new TextComponentPropertySynchronizer( - userDescProperty, userDescField); - ChangeIndicator userDescChange = new ChangeIndicator(); - userDescProperty.addChangeListener(userDescChange); + descProperty, descField); + ChangeIndicator descChange = new ChangeIndicator(); + descProperty.addChangeListener(descChange); + + // Connect the label to the field + descLabel.setLabelFor(descField); + + // Add to the layout + gbc.gridx = 0; + gbc.gridy++; // next row + form.add(descLabel, gbc); + gbc.gridx = GridBagConstraints.RELATIVE; + form.add(descField, gbc); + form.add(descChange, gbc); + + // User ID + actString = new ActionString("usermgr.basic.uid." + + descriptor.getTypeString()); + uidLabel = new JLabel(actString.getString()); + uidField = new JLabel(); + + // Add to the layout + gbc.gridx = 0; + gbc.gridy++; // next row + form.add(uidLabel, gbc); + gbc.gridx = GridBagConstraints.RELATIVE; + form.add(uidField, gbc); + form.add(new Spacer(), gbc); - // Is Administrator - JCheckBox isAdminCheckBox = new JCheckBox( - Finder.getString("usermgr.basic.label.enableadmin")); - new CheckBoxPropertySynchronizer( - isAdminProperty, isAdminCheckBox); - ChangeIndicator isAdminChange = new ChangeIndicator(); - isAdminProperty.addChangeListener(isAdminChange); - isAdminCheckBox.setSelected(false); + // Group Name + actString = new ActionString("usermgr.basic.label.group"); + JLabel groupLabel = new JLabel(actString.getString()); + groupLabel.setDisplayedMnemonic(actString.getMnemonic()); + groupCombo = new JComboBox(); + new ComboBoxPropertySynchronizer(groupProperty, groupCombo); + + for (Group g : descriptor.getGroups()) { + groupCombo.addItem(g.getGroupName()); + } + ChangeIndicator groupChange = new ChangeIndicator(); + groupProperty.addChangeListener(groupChange); + + // Connect the label to the field + groupLabel.setLabelFor(groupCombo); + + gbc.gridx = 0; + gbc.gridy++; // next row + form.add(groupLabel, gbc); + gbc.gridx = GridBagConstraints.RELATIVE; + form.add(groupCombo, gbc); + form.add(groupChange, gbc); + + // Home Directory + actString = new ActionString("usermgr.basic.label.home"); + JLabel homeLabel = new JLabel(actString.getString()); + homeLabel.setDisplayedMnemonic(actString.getMnemonic()); + + homeField = new HintTextField(width); + homeField.setHintText(Finder.getString("usermgr.new.value.auto")); + new HintTextPropertySynchronizer(homeProperty, homeField, ""); + + ChangeIndicator homeChange = new ChangeIndicator(); + homeProperty.addChangeListener(homeChange); - // Create the form and add the form elements - JPanel formPanel = new JPanel(); - formPanel.setOpaque(false); - Form form = new Form(formPanel, VerticalAnchor.TOP); + // Connect the label to the field + homeLabel.setLabelFor(homeField); + + // Add to the layout + gbc.gridx = 0; + gbc.gridy++; // next row + form.add(homeLabel, gbc); + gbc.gridx = GridBagConstraints.RELATIVE; + form.add(homeField, gbc); + form.add(homeChange, gbc); + // Login Shell + actString = new ActionString("usermgr.basic.label.shell"); + JLabel shellLabel = new JLabel(actString.getString()); + shellLabel.setDisplayedMnemonic(actString.getMnemonic()); + shellCombo = new JComboBox(); + new ComboBoxPropertySynchronizer(shellProperty, shellCombo); + for (String s : descriptor.getShells()) + shellCombo.addItem(s); + ChangeIndicator shellChange = new ChangeIndicator(); + shellProperty.addChangeListener(shellChange); + + // Connect the label to the field + shellLabel.setLabelFor(shellCombo); + + gbc.gridx = 0; + gbc.gridy++; // next row + form.add(shellLabel, gbc); + gbc.gridx = GridBagConstraints.RELATIVE; + form.add(shellCombo, gbc); + form.add(shellChange, gbc); + + // Change Password + gbc.gridx = 0; + gbc.gridy++; // next row + gbc.weightx = 0.0; + gbc.gridwidth = GridBagConstraints.REMAINDER; passPanel = new PasswordPanel(); + form.add(passPanel, gbc); - int hGap = GUIUtil.getHalfGap(); - ColumnLayoutConstraint col = new ColumnLayoutConstraint( - HorizontalAnchor.FILL, hGap); - RowLayoutConstraint row = new RowLayoutConstraint( - VerticalAnchor.CENTER, hGap); - HasAnchors a = new SimpleHasAnchors( - HorizontalAnchor.LEFT, VerticalAnchor.CENTER); - - form.addTable(3, hGap, hGap*2, HorizontalAnchor.LEFT, col); + // Advanced Settings + actString = new ActionString("usermgr.advanced.settings"); + JButton advSettings = new JButton(actString.getString()); + advSettings.setActionCommand(ACTION_ADV_SETTINGS); + advSettings.addActionListener(this); + advSettings.setMnemonic(actString.getMnemonic()); + settingsChange = new ChangeIndicator(); + settingsProperty.addChangeListener(settingsChange); - form.add(userNameLabel, a); - form.add(userNameValue, a); - form.add(new Spacer(), a); - - form.add(userDescLabel, a); - form.add(userDescField, a); - form.add(userDescChange, a); + // Add to the layout + gbc.gridx = 0; + gbc.gridy++; + gbc.gridwidth = 1; // GridBagConstraints.RELATIVE; + gbc.weighty = 1.0; + gbc.anchor = GridBagConstraints.LAST_LINE_START; + form.add(advSettings, gbc); + gbc.gridx = GridBagConstraints.RELATIVE; + gbc.gridwidth = 0; + form.add(settingsChange, gbc); - form.addRow(HorizontalAnchor.LEFT, col); - form.add(isAdminCheckBox, row); - form.add(isAdminChange, row); - - form.addRow(HorizontalAnchor.LEFT, col); - form.add(passPanel); - - return formPanel; + return form; } - private void initLabels(boolean bNormalUser) { - if (bNormalUser) { - // Normal user - userNameLabel.setText( - Finder.getString("usermgr.basic.label.username")); - userDescLabel.setText( - Finder.getString("usermgr.basic.label.userdesc")); - } else { - // Role - userNameLabel.setText( - Finder.getString("usermgr.basic.label.rolename")); - userDescLabel.setText( - Finder.getString("usermgr.basic.label.roledesc")); + /** + * ActionListener for Advanced Settings + */ + @Override + public void actionPerformed(ActionEvent e) { + String actionCmd = e.getActionCommand(); + if (actionCmd == ACTION_ADV_SETTINGS) { + if (advDialog == null || + descriptor.isTypeRole() != advDialog.isTypeRole()) { + advDialog = new AdvancedSettingsDialog(this, + descriptor, umo); + } else { + advDialog.setUser(umo); + } + advDialog.show(); + if (advDialog.getValue() == JOptionPane.OK_OPTION) { + advDialog.update(); + settingsProperty.setValue(advDialog.isChanged()); + } } } + + /** + * Clear the advanced settings change state. + */ + public void clearChanges() { + settingsProperty.update(false, true); + } } diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrControl.java --- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrControl.java Thu Apr 26 00:14:30 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,120 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. - */ - -package com.oracle.solaris.vp.panels.usermgr.client.swing; - -import java.util.Map; -import com.oracle.solaris.vp.panel.common.control.*; -import com.oracle.solaris.vp.panel.swing.control.TabbedControl; - -public class UserMgrControl extends TabbedControl { - - // - // Static data - // - public static final String ID = "usermgr"; - public static final String PARAM_USER = "user"; - - // - // Instance data - // - - private UserManagedObject userMO; - - // - // Constructor - // - - public UserMgrControl(UserMgrPanelDescriptor descriptor) { - super(ID, null, descriptor); - } - - // - // Control methods - // - - @Override - public boolean isBrowsable() { - // This control requires init parameters - return false; - } - - // - // DefaultControl Methods - // - - @Override - protected void ensureChildrenCreated() { - // Add the basic and advanced tab controls - if (children.size() == 0) { - addChildren(new UserMgrBasicControl(this)); - addChildren(new UserMgrAdvancedControl(this)); - } - } - - // - // SwingControl Methods - // - - @Override - public void start(Navigator navigator, Map parameters) - throws NavigationAbortedException, InvalidParameterException, - NavigationFailedException { - - String param = getParameter(parameters, PARAM_USER); - UserManagedObject umo = - getPanelDescriptor().getUserManagedObject(param); - if (umo == null) { - throw new InvalidParameterException(getId(), PARAM_USER, param); - } - - setUserManagedObject(umo); - - super.start(navigator, parameters); - } - - @Override - public void stop(boolean isCancel) throws NavigationAbortedException { - super.stop(isCancel); - setUserManagedObject(null); - } - - // - // UserMgrControl methods - // - - public UserManagedObject getUserManagedObject() { - return userMO; - } - - // - // Private methods - // - - private void setUserManagedObject(UserManagedObject umo) { - this.userMO = umo; - setName(umo == null ? null : umo.getName()); - } -} diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrEmptyPanel.java --- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrEmptyPanel.java Thu Apr 26 00:14:30 2012 -0400 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrEmptyPanel.java Fri Apr 27 00:52:26 2012 -0400 @@ -30,6 +30,10 @@ import com.oracle.solaris.vp.util.misc.finder.Finder; import com.oracle.solaris.vp.util.swing.GUIUtil; +/** + * This panel provides preliminary information on what button + * does what. Details are available from the Help button. + */ @SuppressWarnings({"serial"}) public class UserMgrEmptyPanel extends JPanel { // diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrPanelDescriptor.java --- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrPanelDescriptor.java Thu Apr 26 00:14:30 2012 -0400 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrPanelDescriptor.java Fri Apr 27 00:52:26 2012 -0400 @@ -38,7 +38,7 @@ import com.oracle.solaris.vp.panel.common.model.*; import com.oracle.solaris.vp.panel.swing.control.PanelFrameControl; import com.oracle.solaris.vp.panel.swing.model.SwingPanelDescriptor; -import com.oracle.solaris.vp.panels.usermgr.*; +import com.oracle.solaris.rad.usermgr.*; import com.oracle.solaris.vp.util.misc.*; import com.oracle.solaris.vp.util.misc.finder.Finder; import com.oracle.solaris.vp.util.misc.property.*; @@ -53,17 +53,27 @@ // // Constants needed for registering the MBean - public static final String DOMAIN = - MBeanUtil.VP_PANEL_DOMAIN + ".usermgr"; + public static final String INTERFACE_NAME = + "com.oracle.solaris.rad.usermgr"; public static final ObjectName OBJECT_NAME = - MBeanUtil.makeObjectName(DOMAIN, "UserMgr"); + MBeanUtil.makeObjectName(INTERFACE_NAME, "UserMgr"); + + public static final String USER_TYPE_NORMAL = "normal"; + public static final String SCOPE_FILES = "files"; + public static final String MATCH_ALL = "*"; // // Instance data // + private MainControl mc; private DefaultControl control; private MXBeanTracker beanTracker; + private UserType uType; + + private String scopeStr = SCOPE_FILES; + private String typeStr = USER_TYPE_NORMAL; + private String matchStr = MATCH_ALL; private List deleteList = new ArrayList (); @@ -104,14 +114,14 @@ setComparator(SimpleHasId.COMPARATOR); // Initialize list of users - initUsers(); + initUsers(SCOPE_FILES, USER_TYPE_NORMAL, MATCH_ALL); // Keep track of users added/deleted addedProperty.update(0, true); deletedProperty.update(0, true); control = new PanelFrameControl(this); - MainControl mc = new MainControl(this); + mc = new MainControl(this); control.addChildren(mc); } @@ -174,35 +184,23 @@ } } - @Override - public void removeChildren(UserManagedObject... toRemove) { + // + // UserMgrPanelDescriptor methods + // + + public void removeChildren(UserManagedObject toRemove) { super.removeChildren(toRemove); ChangeableAggregator aggregator = getChangeableAggregator(); - for (UserManagedObject umo : toRemove) { - aggregator.removeChangeable(umo.getChangeableAggregator()); - } + aggregator.removeChangeable(toRemove.getChangeableAggregator()); } - @Override - protected String getCalculatedStatusText() { - int nUsers = 0; - int nRoles = 0; - ListumoList = getChildren(); - for (UserManagedObject umo : umoList) { - if (umo.isUserNormal()) - nUsers++; - else if (umo.isUserRole()) - nRoles++; - } - - return Finder.getString("user.status", nUsers, nRoles); + public void removeAllChildren() { + super.clearChildren(); + ChangeableAggregator aggregator = getChangeableAggregator(); + aggregator.reset(); } - // - // UserMgrPanelDescriptor methods - // - public UserMgrMXBean getUserMgrBean() { return beanTracker.getBean(); } @@ -225,16 +223,22 @@ public void deleteUserManagedObject(UserManagedObject toRemove) { removeChildren(toRemove); - deletedProperty.setValue(deletedProperty.getValue() + 1); - deleteList.add(toRemove); } public void addUserManagedObject(UserManagedObject toAdd) { addChildren(toAdd); + } + + public void addToAddList(UserManagedObject toAdd) { addedProperty.setValue(addedProperty.getValue() + 1); addList.add(toAdd); } + public void addToDeleteList(UserManagedObject toRemove) { + deletedProperty.setValue(deletedProperty.getValue() + 1); + deleteList.add(toRemove); + } + public void saveDeletedUsers() throws ActionAbortedException, ActionFailedException, ActionUnauthorizedException { @@ -243,26 +247,23 @@ UserManagedObject umo = it.next(); try { getUserMgrBean().deleteUser(umo.getName()); + deleteUserManagedObject(umo); it.remove(); deletedProperty.setValue(deletedProperty.getValue() - 1); } catch (SecurityException se) { throw new ActionUnauthorizedException(se); } catch (ObjectException e) { UserMgrError ume = e.getPayload(UserMgrError.class); - String msg; - UserMgrErrorType error = (ume != null) ? - ume.getErrorCode() : UserMgrErrorType.INVALIDDATA; - switch (error) { - case LASTADMIN: - msg = Finder.getString( - "usermgr.delete.lastAdmin.error"); - break; - default: // Invalid Data - msg = Finder.getString("usermgr.error.invalidData"); - break; - } + String msg = Finder.getString("usermgr.error.invalidData"); String err = Finder.getString( - "usermgr.delete.general.error", umo.getUsername()); + "usermgr.error.delete", umo.getUsername()); + getLog().log(Level.SEVERE, err + msg, e); + throw new ActionFailedException(err + msg); + // Any other remaining exceptions + } catch (Exception e) { + String msg = Finder.getString("usermgr.error.system"); + String err = Finder.getString( + "usermgr.error.delete", umo.getUsername()); getLog().log(Level.SEVERE, err + msg, e); throw new ActionFailedException(err + msg); } @@ -279,18 +280,16 @@ char[] password = umo.getPassword(); User user = getUserMgrBean().addUser( umo.getNewUser(), password); + addUserManagedObject(umo); Arrays.fill(password, (char)0); - if (umo.isAdministrator()) { - getUserMgrBean(). - setAdministrator(user.getUsername(), true); - } it.remove(); addedProperty.setValue(addedProperty.getValue() - 1); umo.updateUser(user); } catch (SecurityException se) { throw new ActionUnauthorizedException(se); } catch (ObjectException e) { + e.printStackTrace(); UserMgrError ume = e.getPayload(UserMgrError.class); String msg; UserMgrErrorType error = (ume != null) ? @@ -306,9 +305,17 @@ msg = Finder.getString("usermgr.error.invalidData"); break; } - String err = Finder.getString("usermgr.add.general.error", + String err = Finder.getString("usermgr.error.add", umo.getUsername()); getLog().log(Level.SEVERE, err + msg, e); + deleteUserManagedObject(umo); + throw new ActionFailedException(err + msg); + // Any other remaining exceptions + } catch (Exception e) { + String msg = Finder.getString("usermgr.error.system"); + String err = Finder.getString( + "usermgr.error.add", umo.getUsername()); + getLog().log(Level.SEVERE, err + msg, e); throw new ActionFailedException(err + msg); } umo.getChangeableAggregator().save(); @@ -322,19 +329,16 @@ for (UserManagedObject umo : kids) { if (umo.getChangeableAggregator().isChanged()) { User user = umo.getModifiedUser(); + UserChangeFields changes = umo.getModifiedChanges(); try { if (user != null) { char[] password = null; if (umo.getPassProperty().isChanged()) password = umo.getPassword(); - getUserMgrBean().modifyUser(user, password); + getUserMgrBean().modifyUser(user, password, changes); if (password != null) Arrays.fill(password, (char)0); } - if (umo.getIsAdminProperty().isChanged()) { - getUserMgrBean().setAdministrator(umo.getUsername(), - umo.isAdministrator()); - } } catch (SecurityException se) { throw new ActionUnauthorizedException(se); } catch (ObjectException e) { @@ -346,23 +350,21 @@ case PASSERROR: msg = Finder.getString("usermgr.error.passError"); break; - case LASTADMIN: - msg = Finder.getString( - "usermgr.modify.lastAdmin.error"); - break; default: msg = Finder.getString("usermgr.error.invalidData"); break; } String err = Finder.getString( - "usermgr.modify.general.error", umo.getUsername()); + "usermgr.error.modify", umo.getUsername()); getLog().log(Level.SEVERE, err + msg, e); throw new ActionFailedException(err + msg); - } catch (Exception e) { // debug only!!! + // Any other remaining exceptions + } catch (Exception e) { + String msg = Finder.getString("usermgr.error.system"); String err = Finder.getString( - "usermgr.modify.general.error", umo.getUsername()); - getLog().log(Level.SEVERE, err, e); - throw new ActionFailedException("Error modifying user!!!!"); + "usermgr.error.modify", umo.getUsername()); + getLog().log(Level.SEVERE, err + msg, e); + throw new ActionFailedException(err + msg); } umo.getChangeableAggregator().save(); } @@ -378,6 +380,16 @@ return null; } + public List getSupplGroups() { + try { + return getUserMgrBean().getsupplGroups(); + } catch (ObjectException e) { + getLog().log(Level.SEVERE, + "Error getting supplementary group list.", e); + } + return null; + } + public List getShells() { try { return getUserMgrBean().getshells(); @@ -387,18 +399,144 @@ return null; } - public UserImpl getDefaultUser() throws ActionFailedException, - ActionUnauthorizedException { + public List getScopes() { + try { + return getUserMgrBean().getscopes(); + } catch (ObjectException e) { + getLog().log(Level.SEVERE, "Error getting scopes list.", e); + } + return null; + } + + public List getProfiles() { + try { + return getUserMgrBean().getprofiles(); + } catch (ObjectException e) { + getLog().log(Level.SEVERE, "Error getting profiles list.", e); + } + return null; + } + + public List getAuths() { + try { + return getUserMgrBean().getauths(); + } catch (ObjectException e) { + getLog().log(Level.SEVERE, "Error getting authorizations list.", e); + } + return null; + } + + public List getRoles() { + try { + return getUserMgrBean().getroles(); + } catch (ObjectException e) { + getLog().log(Level.SEVERE, "Error getting roles list.", e); + } + return null; + } + + public void setScope(String scope) { + ScopeType sType; + if (scope.equals(SCOPE_FILES)) { + sType = ScopeType.FILES; + } else { + sType = ScopeType.LDAP; + } + + try { + getUserMgrBean().setScope(sType); + } catch (Exception e) { + getLog().log(Level.SEVERE, "Error setting scope.", e); + } + } + + public UserImpl getDefaultUser() { try { User defUser = getUserMgrBean().getdefaultUser(); - return new UserImpl("", 0L, defUser.getGroupID(), "", "", - defUser.getDefaultShell()); - } catch (SecurityException se) { - throw new ActionUnauthorizedException(se); + return new UserImpl( + "", 0L, defUser.getGroupID(), + "", "", defUser.getDefaultShell(), + 0, 0, 0, 0, + "", "", "", "", "", "", + "", "", "", "", "", "", + null, null, null, null, null, null); } catch (ObjectException e) { getLog().log(Level.SEVERE, "Error getting default user.", e); - throw new ActionFailedException(e); + } + + return null; + } + + public void initUsers(String scopeStr, + String typeStr, String matchStr) { + int count = 0; + String statusStr; + String listTitle; + + this.scopeStr = scopeStr; + this.typeStr = typeStr; + this.matchStr = matchStr; + + setScope(scopeStr); + + statusStr = Finder.getString("usermgr.status.scope") + + " " + scopeStr; + if (typeStr.equals(USER_TYPE_NORMAL)) { + uType = UserType.NORMAL; + listTitle = Finder.getString("usermgr.list.title.user"); + } else { + uType = UserType.ROLE; + listTitle = Finder.getString("usermgr.list.title.role"); } + + setFilter(uType, matchStr); + List users = getUsers(); + + removeAllChildren(); + try { + boolean uTypeSet = false; + for (User user : users) { + String username = user.getUsername(); + UserMgrMXBean bean = getUserMgrBean(); + if (uTypeSet == false) { + uType = bean.getUserType(username); + uTypeSet = true; + } + + UserManagedObject umo = new UserManagedObject(this, + user, uType, null, false); + addChildren(umo); + } + + } catch (ObjectException e) { + getLog().log(Level.SEVERE, "Error creating user list.", e); + } finally { + setStatusText(statusStr); + if (mc != null) { + mc.setListTitle(listTitle); + } + } + } + + public boolean isTypeRole() { + return (uType == UserType.ROLE ? true : false); + } + + public String getTypeString() { + return (uType == UserType.ROLE ? "role" : "user"); + } + + public String getScope() { + return (scopeStr); + } + + public String getType() { + return (typeStr); + } + + + public String getMatch() { + return (matchStr); } // @@ -415,32 +553,11 @@ return users; } - private void initUsers() { - int nUsers = 0; - int nRoles = 0; - - List users = getUsers(); - + private void setFilter(UserType utype, String search) { try { - for (User user : users) { - String username = user.getUsername(); - UserMgrMXBean bean = getUserMgrBean(); - boolean isAdmin = bean.isAdministrator(username); - UserType uType = bean.getUserType(username); - UserManagedObject umo = new UserManagedObject(this, - user, uType, isAdmin, null, false); - - if (uType == UserType.NORMAL) - nUsers++; - else - nRoles++; - - addChildren(umo); - } - } catch (ObjectException e) { - getLog().log(Level.SEVERE, "Error creating user list.", e); - } finally { - setStatusText(Finder.getString("user.status", nUsers, nRoles)); + getUserMgrBean().setFilter(utype, search); + } catch (Exception e) { + getLog().log(Level.SEVERE, "Error setting filter.", e); } } } diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrUtils.java --- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrUtils.java Thu Apr 26 00:14:30 2012 -0400 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/UserMgrUtils.java Fri Apr 27 00:52:26 2012 -0400 @@ -25,7 +25,9 @@ package com.oracle.solaris.vp.panels.usermgr.client.swing; +import java.awt.*; import java.util.Arrays; +import javax.swing.*; import com.oracle.solaris.vp.panel.common.action.ActionFailedException; import com.oracle.solaris.vp.util.misc.finder.Finder; @@ -53,19 +55,19 @@ // User name must be specified if (username.length() == 0) { throw new ActionFailedException( - Finder.getString("usermgr.basic.error.username.none")); + Finder.getString("usermgr.error.username.none")); } // Ensure that the username is valid if (!isValidLogin(username)) { throw new ActionFailedException( - Finder.getString("usermgr.basic.error.username.bad")); + Finder.getString("usermgr.error.username.bad")); } // Ensure that username does not already exist if (descriptor.getUserManagedObject(username) != null) { throw new ActionFailedException( - Finder.getString("usermgr.basic.error.username.exists", + Finder.getString("usermgr.error.username.exists", username)); } } @@ -75,21 +77,17 @@ // Ensure that the user description, if specified, is valid. if (!isValidUserDesc(userdesc)) { throw new ActionFailedException( - Finder.getString("usermgr.basic.error.userdesc.bad")); + Finder.getString("usermgr.error.userdesc.bad")); } } public static void validatePassword(boolean bNewUser, char[] pass1, char[] pass2) throws ActionFailedException { - // Password must be specified for a new user - if (pass1.length == 0 && bNewUser) - throw new ActionFailedException( - Finder.getString("usermgr.basic.error.pass.none")); // Ensure that the passwords match if (!Arrays.equals(pass1, pass2)) { throw new ActionFailedException( - Finder.getString("usermgr.basic.error.pass.nomatch")); + Finder.getString("usermgr.error.pass.nomatch")); } } @@ -98,7 +96,7 @@ // Ensure that the UID is valid if (uid < VALID_UID) { throw new ActionFailedException( - Finder.getString("usermgr.advanced.error.uid.bad")); + Finder.getString("usermgr.error.uid.bad")); } } @@ -107,7 +105,7 @@ // Ensure that the homedir is valid if (!isValidHomeDir(homedir)) { throw new ActionFailedException( - Finder.getString("usermgr.advanced.error.homedir.bad")); + Finder.getString("usermgr.error.homedir.bad")); } } @@ -162,4 +160,20 @@ return (homedir.length() >= VALID_HOMEDIRLEN && homedir.matches("^\\/[\\-\\p{Alnum}\\._\\/]+$")); } + + public static void removeIcons(JOptionPane pane) { + Component[] comps = pane.getComponents(); + + for (int i = 0; i < comps.length; i++) { + Component comp = comps[i]; + if (comp instanceof JPanel) { + Component[] buttons = ((JPanel)comp).getComponents(); + for (int j = 0; j < buttons.length; j++) { + if (buttons[j] instanceof JButton) { + ((JButton)buttons[j]).setIcon(null); + } + } + } + } + } } diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/DOCS Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/DOCS has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/DOCS.TAB --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/DOCS.TAB Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,7 @@ +e_uu_u@9J*0 +£ + + +** +ꪪ4 0ң|"J0J040 +jҪꪪ*0º ̊2ꪪ \ No newline at end of file diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/OFFSETS --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/OFFSETS Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,1 @@ +>d*g``P¢1U{lmKxk2y \ No newline at end of file diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/POSITIONS Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/POSITIONS has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/SCHEMA --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/SCHEMA Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,2 @@ +JavaSearch 1.0 +TMAP bs=2048 rt=1 fl=-1 id1=399 id2=1 diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/TMAP Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/JavaHelpSearch/TMAP has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/app.hs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/app.hs Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,29 @@ + + + + + +User Manager Online Help + + + + + + TOC + + javax.help.TOCView + toc.xml + + + Index + + javax.help.IndexView + index.xml + + + Search + + javax.help.SearchView + JavaHelpSearch + + diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/docinfo.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/docinfo.html Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + +

Copyright 2012

This +software and related documentation are provided under a license agreement containing restrictions on +use and disclosure and are protected by intellectual property laws. Except as expressly +permitted in your license agreement or allowed by law, you may not use, +copy, reproduce, translate, broadcast, modify, license, transmit, distribute, exhibit, perform, publish, or display +any part, in any form, or by any means. Reverse engineering, disassembly, or +decompilation of this software, unless required by law for interoperability, is prohibited.

+ +

The information +contained herein is subject to change without notice and is not warranted to +be error-free. If you find any errors, please report them to us in +writing.

+ +

If this is software or related documentation that is delivered to the U.S. +Government or anyone licensing it on behalf of the U.S. Government, the following +notice is applicable:

+ +

U.S. GOVERNMENT END USERS. Oracle programs, including any operating system, integrated software, +any programs installed on the hardware, and/or documentation, delivered to U.S. Government end +users are "commercial computer software" pursuant to the applicable Federal Acquisition Regulation and +agency-specific supplemental regulations. As such, use, duplication, disclosure, modification, and adaptation of the programs, +including any operating system, integrated software, any programs installed on the hardware, and/or +documentation, shall be subject to license terms and license restrictions applicable to the +programs. No other rights are granted to the U.S. Government.

+ +

This software or hardware is +developed for general use in a variety of information management applications. It is +not developed or intended for use in any inherently dangerous applications, including applications +that may create a risk of personal injury. If you use this software +or hardware in dangerous applications, then you shall be responsible to take +all appropriate fail-safe, backup, redundancy, and other measures to ensure its safe use. +Oracle Corporation and its affiliates disclaim any liability for any damages caused by +use of this software or hardware in dangerous applications.

+ +

Oracle and Java are registered +trademarks of Oracle and/or its affiliates. Other names may be trademarks of their +respective owners.

+ +

Intel and Intel Xeon are trademarks or registered trademarks of Intel Corporation. +All SPARC trademarks are used under license and are trademarks or registered trademarks +of SPARC International, Inc. AMD, Opteron, the AMD logo, and the AMD Opteron +logo are trademarks or registered trademarks of Advanced Micro Devices. UNIX is a +registered trademark of The Open Group.

+ +

This software or hardware and documentation may +provide access to or information on content, products, and services from third parties. +Oracle Corporation and its affiliates are not responsible for and expressly disclaim all +warranties of any kind with respect to third-party content, products, and services. Oracle Corporation +and its affiliates will not be responsible for any loss, costs, or damages +incurred due to your access to or use of third-party content, products, or +services.

+ + +
+ + +Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Legal Notices + + + diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/index.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/index.xml Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,5 @@ + + + + + diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/map.jhm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/map.jhm Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/target.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/target.xml Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,55 @@ + +
+ User Manager Online Help + “User Manager Online Help” +
+
+
+ User Manager Panel + “User Manager Panel” +
+
+ Selecting a Name-Service Scope and Type + “Selecting a Name-Service Scope and Type” +
+
+ Creating a New User or Role + “Creating a New User or Role” +
+
+ Modifying a User or Role + “Modifying a User or Role” +
+
+ Deleting a User or Role + “Deleting a User or Role” +
+
+ Advanced Settings + “Advanced Settings” +
+
+ Administering Groups + “Administering Groups” +
+
+ Administering Roles + “Administering Roles” +
+
+ Administering Rights + “Administering Rights” +
+
+ Administering Authorizations + “Administering Authorizations” +
+
+ Changing User Credentials + “Changing User Credentials” +
+
+ To Change a User's Credentials + “To Change a User's Credentials” +
+
diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/toc.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/toc.xml Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/umolh.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/umolh.html Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + +

User Manager Online Help

+ +
+ + +Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Legal Notices + + + diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-admauths.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-admauths.html Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + +

Administering Authorizations

+

To administer authorizations, select a user in the main User Manager panel, then +click the Advanced Settings... button, which opens the Advanced Settings panel. Click the Authorization +attribute on the left side of the panel to display a list of +the available roles and a list of the authorizations that are granted to +the current user.

+ +

To assign an authorization, or multiple authorizations, to a user, select the authorization +(or authorizations) from the Available Authorizations list, then click Add to add the +authorization. The authorization is displayed in the Granted Authorizations list. To remove an +authorization from the Granted Authorizations list, click Remove. Clicking the Add All or the Remove All +button adds or removes all of the authorizations that are granted to the +current user.

+ +

Click OK to save the settings. Note that the changes are not +applied to the current user until you click Apply or OK in the +main User Manager panel.

+ + +
+ + +Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Legal Notices + + + diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-admgrp.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-admgrp.html Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + +

Administering Groups

+

To administer groups, select a user or role in the main User +Manager panel, then click the Advanced Settings... button, which opens the Advanced Settings panel. Click +the Groups attribute on the left side of the panel to display a +list of the available groups and a list of the groups that are +assigned to the current user or role.

+ +

To assign a group, or multiple groups, to a user or role, +select the group (or groups) from the Available Groups list, then click Add. The +group is displayed in the Assigned Groups list. To remove a group +from the Assigned Groups list, select the group and click Remove. Clicking the Add All +or the Remove All button adds or removes all of the groups that are +assigned to the current user.

+ +

Click OK to save the settings. Note that the changes are not +applied to the current user until you click Apply or OK in the +main User Manager panel.

+ + +
+ + +Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Legal Notices + + + diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-admrights.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-admrights.html Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + +

Administering Rights

+

To administer rights profiles, select a user in the main User Manager panel, +then click the Advanced Settings... button, which opens the Advanced Settings panel. Click the +Rights Profiles attribute on the left side of the panel to display a +list of the available rights and a list of the rights that are +granted to the current user.

+ +

To assign a right, or multiple rights, to a user, select the +right (or rights) from the Available Rights list, then click Addr. The granted right +is displayed in the Granted Rights list.

+ +

The assignment of rights have an order precedence. Use the Move Up and +Move Down buttons to change the order of the rights that are granted to +the current user, as desired.

+ +

To remove a right from the Granted Rights list, click Remove. Clicking the +Add All or the Remove All button adds or removes all of the rights that +are granted to the current user.

+ +

Click OK to save the settings. Note that the changes are not +applied to the current user until you click Apply or OK in the +main User Manager panel.

+ + +
+ + +Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Legal Notices + + + diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-advtab.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-advtab.html Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + +

Advanced Settings

+

You can use the Advanced Settings... dialog to assign additional security attributes to +a user or role, for example, rights profiles, roles, and authorizations.

+ +

To administer advanced settings for a new user or role, click the Advanced +Settings... button in the New User... dialog, which opens the Advanced Settings panel +for the new user or role.

+ +

To administer advanced attributes for an existing user or role, select the user +or role in the main User Manager panel, then click the Advanced Settings... button, +which opens the Advanced Settings panel for the current user or role. The +selected user's name is displayed in parentheses at the top of the panel.

+ +

In the Advanced Settings panel, the following settings are listed:

+ + +
  • Groups

    + +
  • +
  • Roles

    + +
  • +
  • Rights Profiles

    + +
  • +
  • Authorizations

    + +
+ +

Note - If you are creating a new user or role, the user or +role is not created until you click the OK button.

+ + +
+ +
+ + +Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Legal Notices + + + diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-assumerole.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-assumerole.html Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + +

Changing User Credentials

+

Any user with the User Management rights profile can create new users, provided that +the advanced attributes of the user or role to be created is a +subset of those of the user who is performing the administration. If the +user who is performing the administration does not have sufficient authorizations, but has +an administrative role with sufficient authorizations, the user can assume that role to +perform the necessary administration by clicking the Lock button in the main User +Manager panel.

+ + +

Note - The authorizations and rights that are required to manage users and roles with +User Manager are assigned through the application. The application both uses and provides +authorizations.

+ + +
+ +
+ + +Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Legal Notices + + + diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-chgcred.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-chgcred.html Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + +

To Change a User's Credentials

+

Click the Lock icon to open a submenu that includes the following +options:

+ + +
  • Change Role...

    + +
  • +
  • Change User...

    + +
  • +
  • Administer New Host...

    + +
  • +
  • Clear History...

    + +
+

When you select the Change Role... option, an authentication dialog is displayed. The authentication +dialog contains a drop-down menu that lists the available roles for the specified +user. Select the appropriate role, then click Log In to change the role. +After assuming the role, you can perform the required administrative tasks. Click the +Cancel button to cancel the operation or the Back button to go to +the previous panel.

+ +

For information about using the Administer New Host... and Clear History... menu options, refer to +the Visual Panels documentation.

+ + +
+ + +Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Legal Notices + + + diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-createuser.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-createuser.html Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + +

Creating a New User or Role

+

To create a new user or role within the scope of the +filter that is currently being used by the tool, click the New button in +the main User Manager panel. The New User... dialog is displayed.

+ +

In the New User... dialog, complete the following fields:

+ + +
  • User Name

    + +
  • +
  • Full Name

    + +
  • +
  • User ID

    + +

    This field is optional. If the administrator does not provide any information, the system automatically assigns a default value.

    + +
  • +
  • Group

    + +

    For example, staff.

    + +

    The choices that are available vary, depending on the system's configuration.

    + +
  • +
  • Home Directory

    + +

    This field is optional. If the administrator does not provide any information, the system automatically assigns a default value.

    + +

    If you want the user's home directory to be automounted, precede the path name with a host name or a local host. For example, localhost:/export/home/test1.

    + +
  • +
  • Login Shell

    + +

    For example, /usr/bin/sh.

    + +

    The choices that are available vary, depending on the system's configuration.

    + +
  • +
  • Password

    + +

    Assign a temporary password to the user.

    + +
  • +
  • Confirm

    + +

    Confirm the temporary password that you assigned to the user.

    + +
+ +

Note - All fields, with the exception of optional fields, must be completed by the +administrator.

+ + +
+

To create the new user or role, and add the user or +role to the list of users that is displayed in the main User +Manager panel, click OK. To cancel the operation, click Cancel.

+ + +
+ + +Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Legal Notices + + + diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-deluser.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-deluser.html Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + +

Deleting a User or Role

+

To delete a user or role within the scope of the filter +that is currently being used by the tool, select the user or role +in the main User Manager panel, then click the Delete button. Click OK +when the confirmation dialog is displayed. To cancel the operation, click Cancel.

+ + +
+ + +Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Legal Notices + + + diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-mainpanel.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-mainpanel.html Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + +

User Manager Panel

+

When you launch the User Manager GUI, the User Manager panel is +displayed. The User Manager panel is used to administer users and roles. On +the top left side of the panel is a Status field that displays +the status of the services that are currently running on the local host. +On the top right side of the panel is a User field. The +User field displays the credential that is currently being used by the tool. +To change credentials, click the Lock button on the far right of the panel. +See Changing User Credentials.

+ +

The User Manager panel includes the following main components:

+ + +
  • Users and Roles list – Contains a list of users from which you can select to administer.

    + +
  • +
  • Basic Settings – Displays the basic settings for a user, such as user name, full name.

    + +
+

To view or modify information for an existing user: Select the user from the list of users. The user's information is +displayed on the right side of the panel.

+ +

To create a new user: Click the New... button. See Creating a New User or Role.

+ +

To delete a user: Click the Delete button. See Deleting a User or Role.

+ +

To filter users based on scope type (files or ldap), or by user or role: Click the Filter... button.

+ +

To administer advanced settings for a user, for example, roles or rights profiles: Click the Advanced button. See Advanced Settings.

+ + +
+ + +Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Legal Notices + + + diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-moduser.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-moduser.html Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + +

Modifying a User or Role

+

To modify an existing user or role, select the user or role +that you want to modify from the list that is displayed in the +main User Manager panel. After selecting a user or role, the focus of +the panel switches to the Modify mode.

+ +

After selecting the user, the right side of the panel is populated +with the user's information. In this dialog you can modify any or all +the information for a user or role. To save the changes, click Apply. +As with the New User... dialog, click the Advanced Settings... button to modify additional security +attributes for the user or role. See Advanced Settings.

+ +

Clicking OK saves the changes and closes the User Manager panel. Click Cancel +to discard any unsaved changes and close the panel.

+ + +

Note - If a field is modified, an indicator is displayed adjacent to the +field that has been modified.

+ + +
+ +
+ + +Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Legal Notices + + + diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-namesvcscope.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usermgr-namesvcscope.html Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + +

Selecting a Name-Service Scope and Type

+

The default name-service scope and type for User Manager is files and +User. To administer the tool within a different scope, for example ldap +and roles, click the Filter... button. Clicking the Filter... button launches a dialog +that enables you to change the default scope and, or, type. Choices for +Scope include files and ldap. Choices for Type include User and Role. +Click OK to save the changes or click Cancel to cancel the operation.

+ + +

Note - If the system is not configured as an ldap client, only the files +scope is available.

+ + +
+ +

Tip - To filter certain criteria, for example, all of the users or roles that +start with the letter “a”, enter a search string in the Matches +field.

+ + +
+ +
+ + +Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Legal Notices + + + diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usrmgr-admrole.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/help/usrmgr-admrole.html Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + +

Administering Roles

+ +

Note - The roles attribute is available only for a user, not for a role, +because roles can only be assigned to users.

+ + +
+

To administer roles, select a user in the main User Manager panel, +then click the Advanced Settings... button, which opens the Advanced Settings panel. Click the Roles +attribute on the left side of the panel to display a list of +the available roles and a list of the roles that are assigned to +the current user.

+ +

To assign a role, or multiple roles, to a user, select the +role (or roles) from the Available Roles list, then click Add. The role is +displayed in the Assigned Roles list. To remove a role from the Assigned +Roles list, select the group, then click Remove. Clicking the Add All or the +Remove All button adds or removes all of the roles that are assigned to +the current user.

+ +

Click OK to save the settings. Note that the changes are not +applied to the current user until you click Apply or OK in the +main User Manager panel.

+ + +
+ + +Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Legal Notices + + + diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/add.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/add.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/add_all.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/add_all.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-roles-16.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-roles-16.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-roles-22.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-roles-22.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-roles-24.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-roles-24.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-roles-32.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-roles-32.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-users-16.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-users-16.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-users-22.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-users-22.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-users-24.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-users-24.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-users-32.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/config-users-32.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/group-16.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/group-16.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/group-24.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/group-24.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/move_dn.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/move_dn.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/move_up.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/move_up.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/remove.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/remove.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/remove_all.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/remove_all.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/rights-16.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/rights-16.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/rights-24.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/rights-24.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/role-24.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/role-24.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/roles-16.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/roles-16.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/roles-24.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/roles-24.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/user-24.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/user-24.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/usermgr-16.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/usermgr-16.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/usermgr-24.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/usermgr-24.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/usermgr-32.png Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/usermgr-32.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/warning.gif Binary file usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/images/warning.gif has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/resources/Resources.properties --- a/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/resources/Resources.properties Thu Apr 26 00:14:30 2012 -0400 +++ b/usr/src/java/vpanels/app/usermgr/com/oracle/solaris/vp/panels/usermgr/client/swing/resources/Resources.properties Fri Apr 27 00:52:26 2012 -0400 @@ -20,80 +20,123 @@ # # -# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. # # -# Main +# User Manager Panel resource strings # -user.status = {0} users, {1} roles found. +# Following messages can be localized. Some strings +# contain an ampersand (&). Ampersand preceding the character +# can be used as the accelerator or the hot-key (Alt+key). +# -panel.usermgr.name = User Manager # -# Users +# Main Panel # -usermgr.list.title = Users: -usermgr.action.add.button = New... -usermgr.action.delete.button = Delete -usermgr.action.delete.confirm = Delete user "{0}"? +panel.usermgr.name = User Manager +usermgr.status.scope = Connected; Scope: +usermgr.list.title.user = Users: +usermgr.list.title.role = Roles: +usermgr.action.add.button = &New... +usermgr.action.delete.button = &Delete +usermgr.action.filter.button = &Filter... + +# +# Info Panel +# +usermgr.empty.message =

This panel administers Users and Roles.

To view or modify an existing user, select the user from the list.
To create a user, click on the New... button.
To delete a user, click on the Delete button.
To filter users based on scope (files|ldap), type (user|role),
click on the Filter... button.<

# -# Empty Panel +# Delete Dialog # -usermgr.empty.message =

This panel administers local users only.

To view or modify an existing user, select the user from the list.
To create a user, click on the New... button.
To delete a user, click on the Delete button.

+usermgr.action.delete.title.user = Delete user... +usermgr.action.delete.title.role = Delete role... +usermgr.action.delete.confirm.user = Delete user "{0}"? +usermgr.action.delete.confirm.role = Delete role "{0}"? # -# Advanced Tab +# Filter Dialog # -usermgr.advanced.name = Advanced -usermgr.advanced.label.uid = User ID: -usermgr.advanced.label.roleid = Role ID: -usermgr.advanced.label.group = Group: -usermgr.advanced.label.homedir = Home Directory: -usermgr.advanced.label.shell = Login Shell: -usermgr.advanced.value.auto = (automatic) +usermgr.filter.title = User Manager - Filter Users... +usermgr.filter.label = Filter Users +usermgr.filter.scope = Scope: +usermgr.filter.type = Type: +usermgr.filter.type.user = &User +usermgr.filter.type.role = &Role +usermgr.filter.match = &Matches: + +# +# New User/Role Dialog +# +usermgr.new.title.user = New User... +usermgr.new.label.user = Create a new user +usermgr.new.title.role = New Role... +usermgr.new.label.role = Create a new role +usermgr.new.value.auto = (automatic) # -# Basic Tab +# Basic Panel. Some of the items are shared +# with New dialog # -usermgr.basic.name = Basic -usermgr.basic.label.username = User Name: -usermgr.basic.label.rolename = Role Name: -usermgr.basic.label.userdesc = Full Name: -usermgr.basic.label.roledesc = Description: +usermgr.basic.name.user = User &Name: +usermgr.basic.uid.user = &User ID: +usermgr.basic.desc.user = &Full Name: + +usermgr.basic.name.role = Role &Name: +usermgr.basic.uid.role = &Role ID: +usermgr.basic.desc.role = &Description: + +usermgr.basic.label.group = &Group: +usermgr.basic.label.home = &Home Directory: +usermgr.basic.label.shell = Login &Shell: usermgr.basic.label.changepass = Change Password -usermgr.basic.label.pass = Password: -usermgr.basic.label.passconfirm = Confirm: -usermgr.basic.label.enableadmin = User is Administrator +usermgr.basic.label.initialpass = Set Initial Password +usermgr.basic.label.pass = &Password: +usermgr.basic.label.passconfirm = C&onfirm: # -# Basic/Advanced Tab Errors +# Advanced Settings Dialog # -usermgr.advanced.error.uid.bad = User ID must be an integer greater than 99 -usermgr.advanced.error.homedir.bad = Home directory must be a valid pathname. -usermgr.basic.error.username.none = User name must be specified. -usermgr.basic.error.username.bad = User name must begin with a letter, must be 8 characters or less, and may contain letters, numbers, unserscores, periods, and hyphens. -usermgr.basic.error.username.exists = User "{0}" already exists. -usermgr.basic.error.userdesc.bad = User description must not include colons, newlines or ampersands. -usermgr.basic.error.pass.none = Password must be specified. -usermgr.basic.error.pass.nomatch = Passwords do not match. +usermgr.advanced.title = User Manager - Advanced Settings +usermgr.advanced.settings = &Advanced Settings... +usermgr.advanced.add_all_btn=Add A&ll +usermgr.advanced.remove_all_btn=Re&move All +usermgr.advanced.move_down_btn=Move &Down +usermgr.advanced.move_up_btn=&Move Up +usermgr.advanced.add_btn=&Add +usermgr.advanced.remove_btn=&Remove +usermgr.advanced.rights = Rights Profiles +usermgr.advanced.rights.available = Available Rights: +usermgr.advanced.rights.granted = Granted Rights: +usermgr.advanced.roles = Roles +usermgr.advanced.roles.available = Available Roles: +usermgr.advanced.roles.assigned = Assigned Roles: +usermgr.advanced.groups = Groups +usermgr.advanced.groups.available = Available Groups: +usermgr.advanced.groups.assigned = Assigned Groups: +usermgr.advanced.auths = Authorizations +usermgr.advanced.auths.available = Available Authorizations: +usermgr.advanced.auths.granted = Granted Authorizations: # -# New User Dialog -# -usermgr.adduser.label.intro = Create a new user -usermgr.adduser.title = New User... - +# Error messages # -# Add/Modify/Delete Errors -# -usermgr.add.general.error = Error adding user "{0}": -usermgr.delete.general.error = Error deleting user "{0}": -usermgr.delete.lastAdmin.error = Last Administrator cannot be deleted -usermgr.modify.general.error = Error modifying user "{0}": -usermgr.modify.lastAdmin.error = At least one local user must be Administrator +usermgr.error.uid.bad = User ID must be an integer greater than 99 +usermgr.error.homedir.bad = Home directory must be a valid pathname. +usermgr.error.username.none = User name must be specified. +usermgr.error.username.bad = User name must begin with a letter, must be 8 characters or less, and may contain letters, numbers, underscores, periods, and hyphens. +usermgr.error.username.exists = "{0}" already exists. +usermgr.error.userdesc.bad = User description must not include colons, newlines or ampersands. +usermgr.error.pass.none = Password must be specified. +usermgr.error.pass.nomatch = Passwords do not match. +usermgr.error.add = Error adding "{0}": +usermgr.error.delete = Error deleting "{0}": +usermgr.error.modify = Error modifying "{0}": usermgr.error.invalidData = Invalid data usermgr.error.permDenied = Permission denied usermgr.error.passError = Password cannot be set usermgr.error.userExists = User exists +usermgr.error.system = System Error + diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/disabled-16.png Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/disabled-16.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/disabled-24.png Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/disabled-24.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/disabled-32.png Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/disabled-32.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/error-16.png Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/error-16.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/error-24.png Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/error-24.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/error-32.png Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/error-32.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/healthy-16.png Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/healthy-16.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/healthy-24.png Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/healthy-24.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/healthy-32.png Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/healthy-32.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/warning-16.png Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/warning-16.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/warning-24.png Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/warning-24.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/warning-32.png Binary file usr/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/view/images/health/warning-32.png has changed diff -r 0a2af4721353 -r a8e124b894b8 usr/src/pkg/manifests/system-management-rad-module-rad-usermgr.p5m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/pkg/manifests/system-management-rad-module-rad-usermgr.p5m Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,40 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. +# + +license cr_Oracle license=cr_Oracle +set name=pkg.fmri value=pkg:/system/management/rad/module/rad-usermgr@$(PKGVERS) +set name=pkg.summary value="rad UserMgr module" +set name=pkg.description value="rad UserMgr module" +set name=info.classification value="org.opensolaris.category.2008:Applications/Configuration and Preferences" +set name=variant.arch value=$(ARCH) +dir path=usr group=sys +dir path=usr/lib +dir path=usr/lib/rad +dir path=usr/lib/rad/java +dir path=usr/lib/rad/module +file path=usr/lib/rad/module/mod_usermgr.so +dir path=usr/share group=sys +#file path=usr/lib/rad/apis/usermgr.xml +depend fmri=pkg:/system/management/rad@$(PKGVERS) type=require diff -r 0a2af4721353 -r a8e124b894b8 usr/src/pkg/manifests/system-management-visual-panels-panel-usermgr.p5m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/pkg/manifests/system-management-visual-panels-panel-usermgr.p5m Fri Apr 27 00:52:26 2012 -0400 @@ -0,0 +1,43 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. +# + +license cr_Oracle license=cr_Oracle +set name=pkg.fmri value=pkg:/system/management/visual-panels/panel-usermgr@$(PKGVERS) +set name=pkg.summary value="User Manager GUI" +set name=pkg.description value="User Manager GUI" +set name=info.classification value="org.opensolaris.category.2008:Applications/Configuration and Preferences" +set name=variant.arch value=$(ARCH) +dir path=usr group=sys +dir path=usr/share group=sys +#dir path=usr/share/applications group=other +#file path=usr/share/applications/vp-usermgr.desktop +dir path=usr/share/vpanels +dir path=usr/share/vpanels/app +file path=usr/share/vpanels/app/vpanels-panels-usermgr.jar +dir path=usr/share/vpanels/conf +#file path=usr/share/vpanels/conf/usermgr.xml +dir path=usr/share/vpanels/pixmaps +file path=usr/share/vpanels/pixmaps/usermgr.png +depend fmri=pkg:/system/management/visual-panels-core@$(PKGVERS) type=require diff -r 0a2af4721353 -r a8e124b894b8 usr/src/pkg/manifests_dev/system-management-visual-panels-panel-usermgr.p5m --- a/usr/src/pkg/manifests_dev/system-management-visual-panels-panel-usermgr.p5m Thu Apr 26 00:14:30 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. -# - -license cr_Oracle license=cr_Oracle -set name=pkg.fmri value=pkg:/system/management/visual-panels/panel-usermgr@$(PKGVERS) -set name=pkg.summary value="User Administration GUI" -set name=pkg.description value="User Administration GUI" -set name=info.classification value="org.opensolaris.category.2008:Applications/Configuration and Preferences" -set name=variant.arch value=$(ARCH) -dir path=usr group=sys -dir path=usr/lib -dir path=usr/lib/rad -dir path=usr/lib/rad/module -file path=usr/lib/rad/module/mod_usermgr.so -dir path=usr/share group=sys -dir path=usr/share/applications group=other -file path=usr/share/applications/vp-usermgr.desktop -dir path=usr/share/vpanels -dir path=usr/share/vpanels/app -file path=usr/share/vpanels/app/vpanels-panels-usermgr.jar -dir path=usr/share/vpanels/conf -file path=usr/share/vpanels/conf/usermgr.xml -dir path=usr/share/vpanels/pixmaps -file path=usr/share/vpanels/pixmaps/usermgr.png -depend fmri=pkg:/system/management/visual-panels-core@$(PKGVERS) type=require