Imported Upstream version 4.6.2
This commit is contained in:
13
install/ui/src/Makefile.am
Normal file
13
install/ui/src/Makefile.am
Normal file
@@ -0,0 +1,13 @@
|
||||
AUTOMAKE_OPTIONS = 1.7
|
||||
|
||||
NULL =
|
||||
|
||||
SUBDIRS = \
|
||||
libs \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DIST = \
|
||||
build.profile.js \
|
||||
dojo.profile.js \
|
||||
freeipa \
|
||||
webui.profile.js
|
||||
739
install/ui/src/Makefile.in
Normal file
739
install/ui/src/Makefile.in
Normal file
@@ -0,0 +1,739 @@
|
||||
# Makefile.in generated by automake 1.15.1 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2017 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
VPATH = @srcdir@
|
||||
am__is_gnu_make = { \
|
||||
if test -z '$(MAKELEVEL)'; then \
|
||||
false; \
|
||||
elif test -n '$(MAKE_HOST)'; then \
|
||||
true; \
|
||||
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
||||
true; \
|
||||
else \
|
||||
false; \
|
||||
fi; \
|
||||
}
|
||||
am__make_running_with_option = \
|
||||
case $${target_option-} in \
|
||||
?) ;; \
|
||||
*) echo "am__make_running_with_option: internal error: invalid" \
|
||||
"target option '$${target_option-}' specified" >&2; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
has_opt=no; \
|
||||
sane_makeflags=$$MAKEFLAGS; \
|
||||
if $(am__is_gnu_make); then \
|
||||
sane_makeflags=$$MFLAGS; \
|
||||
else \
|
||||
case $$MAKEFLAGS in \
|
||||
*\\[\ \ ]*) \
|
||||
bs=\\; \
|
||||
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
||||
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
||||
esac; \
|
||||
fi; \
|
||||
skip_next=no; \
|
||||
strip_trailopt () \
|
||||
{ \
|
||||
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
||||
}; \
|
||||
for flg in $$sane_makeflags; do \
|
||||
test $$skip_next = yes && { skip_next=no; continue; }; \
|
||||
case $$flg in \
|
||||
*=*|--*) continue;; \
|
||||
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
||||
-*I?*) strip_trailopt 'I';; \
|
||||
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
||||
-*O?*) strip_trailopt 'O';; \
|
||||
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
||||
-*l?*) strip_trailopt 'l';; \
|
||||
-[dEDm]) skip_next=yes;; \
|
||||
-[JT]) skip_next=yes;; \
|
||||
esac; \
|
||||
case $$flg in \
|
||||
*$$target_option*) has_opt=yes; break;; \
|
||||
esac; \
|
||||
done; \
|
||||
test $$has_opt = yes
|
||||
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
||||
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
subdir = install/ui/src
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \
|
||||
$(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
|
||||
$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
|
||||
$(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \
|
||||
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
|
||||
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
|
||||
$(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
|
||||
$(top_srcdir)/m4/progtest.m4 $(top_srcdir)/VERSION.m4 \
|
||||
$(top_srcdir)/server.m4 $(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = $(top_builddir)/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
AM_V_P = $(am__v_P_@AM_V@)
|
||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
||||
am__v_P_0 = false
|
||||
am__v_P_1 = :
|
||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
am__v_GEN_1 =
|
||||
AM_V_at = $(am__v_at_@AM_V@)
|
||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
||||
am__v_at_0 = @
|
||||
am__v_at_1 =
|
||||
SOURCES =
|
||||
DIST_SOURCES =
|
||||
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
|
||||
ctags-recursive dvi-recursive html-recursive info-recursive \
|
||||
install-data-recursive install-dvi-recursive \
|
||||
install-exec-recursive install-html-recursive \
|
||||
install-info-recursive install-pdf-recursive \
|
||||
install-ps-recursive install-recursive installcheck-recursive \
|
||||
installdirs-recursive pdf-recursive ps-recursive \
|
||||
tags-recursive uninstall-recursive
|
||||
am__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
n|no|NO) false;; \
|
||||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
|
||||
distclean-recursive maintainer-clean-recursive
|
||||
am__recursive_targets = \
|
||||
$(RECURSIVE_TARGETS) \
|
||||
$(RECURSIVE_CLEAN_TARGETS) \
|
||||
$(am__extra_recursive_targets)
|
||||
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
|
||||
distdir
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||
# Read a list of newline-separated strings from the standard input,
|
||||
# and print each of them once, without duplicates. Input order is
|
||||
# *not* preserved.
|
||||
am__uniquify_input = $(AWK) '\
|
||||
BEGIN { nonempty = 0; } \
|
||||
{ items[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in items) print i; }; } \
|
||||
'
|
||||
# Make sure the list of sources is unique. This is necessary because,
|
||||
# e.g., the same source file might be shared among _SOURCES variables
|
||||
# for different programs/libraries.
|
||||
am__define_uniq_tagged_files = \
|
||||
list='$(am__tagged_files)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | $(am__uniquify_input)`
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DIST_SUBDIRS = $(SUBDIRS)
|
||||
am__DIST_COMMON = $(srcdir)/Makefile.in
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
am__relativize = \
|
||||
dir0=`pwd`; \
|
||||
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
|
||||
sed_rest='s,^[^/]*/*,,'; \
|
||||
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
|
||||
sed_butlast='s,/*[^/]*$$,,'; \
|
||||
while test -n "$$dir1"; do \
|
||||
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
|
||||
if test "$$first" != "."; then \
|
||||
if test "$$first" = ".."; then \
|
||||
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
|
||||
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
|
||||
else \
|
||||
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
|
||||
if test "$$first2" = "$$first"; then \
|
||||
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
|
||||
else \
|
||||
dir2="../$$dir2"; \
|
||||
fi; \
|
||||
dir0="$$dir0"/"$$first"; \
|
||||
fi; \
|
||||
fi; \
|
||||
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
|
||||
done; \
|
||||
reldir="$$dir2"
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
API_VERSION = @API_VERSION@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CMOCKA_CFLAGS = @CMOCKA_CFLAGS@
|
||||
CMOCKA_LIBS = @CMOCKA_LIBS@
|
||||
CONFIG_STATUS = @CONFIG_STATUS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CRYPTO_CFLAGS = @CRYPTO_CFLAGS@
|
||||
CRYPTO_LIBS = @CRYPTO_LIBS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DATA_VERSION = @DATA_VERSION@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DIRSRV_CFLAGS = @DIRSRV_CFLAGS@
|
||||
DIRSRV_LIBS = @DIRSRV_LIBS@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
GETTEXT_DOMAIN = @GETTEXT_DOMAIN@
|
||||
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
|
||||
GIT_BRANCH = @GIT_BRANCH@
|
||||
GIT_VERSION = @GIT_VERSION@
|
||||
GMSGFMT = @GMSGFMT@
|
||||
GMSGFMT_015 = @GMSGFMT_015@
|
||||
GREP = @GREP@
|
||||
INI_CFLAGS = @INI_CFLAGS@
|
||||
INI_LIBS = @INI_LIBS@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
INTLLIBS = @INTLLIBS@
|
||||
INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
|
||||
IPAPLATFORM = @IPAPLATFORM@
|
||||
IPA_DATA_DIR = @IPA_DATA_DIR@
|
||||
IPA_SYSCONF_DIR = @IPA_SYSCONF_DIR@
|
||||
JSLINT = @JSLINT@
|
||||
KRAD_LIBS = @KRAD_LIBS@
|
||||
KRB5KDC_SERVICE = @KRB5KDC_SERVICE@
|
||||
KRB5_CFLAGS = @KRB5_CFLAGS@
|
||||
KRB5_LIBS = @KRB5_LIBS@
|
||||
LD = @LD@
|
||||
LDAP_CFLAGS = @LDAP_CFLAGS@
|
||||
LDAP_LIBS = @LDAP_LIBS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBICONV = @LIBICONV@
|
||||
LIBINTL = @LIBINTL@
|
||||
LIBINTL_LIBS = @LIBINTL_LIBS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBPDB_NAME = @LIBPDB_NAME@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIBVERTO_CFLAGS = @LIBVERTO_CFLAGS@
|
||||
LIBVERTO_LIBS = @LIBVERTO_LIBS@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBICONV = @LTLIBICONV@
|
||||
LTLIBINTL = @LTLIBINTL@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
MK_ASSIGN = @MK_ASSIGN@
|
||||
MK_ELSE = @MK_ELSE@
|
||||
MK_ENDIF = @MK_ENDIF@
|
||||
MK_IFEQ = @MK_IFEQ@
|
||||
MSGATTRIB = @MSGATTRIB@
|
||||
MSGFMT = @MSGFMT@
|
||||
MSGFMT_015 = @MSGFMT_015@
|
||||
MSGMERGE = @MSGMERGE@
|
||||
NAMED_GROUP = @NAMED_GROUP@
|
||||
NDRNBT_CFLAGS = @NDRNBT_CFLAGS@
|
||||
NDRNBT_LIBS = @NDRNBT_LIBS@
|
||||
NDRPAC_CFLAGS = @NDRPAC_CFLAGS@
|
||||
NDRPAC_LIBS = @NDRPAC_LIBS@
|
||||
NDR_CFLAGS = @NDR_CFLAGS@
|
||||
NDR_LIBS = @NDR_LIBS@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
NSPR_CFLAGS = @NSPR_CFLAGS@
|
||||
NSPR_LIBS = @NSPR_LIBS@
|
||||
NSS_CFLAGS = @NSS_CFLAGS@
|
||||
NSS_LIBS = @NSS_LIBS@
|
||||
NUM_VERSION = @NUM_VERSION@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
ODS_USER = @ODS_USER@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_URL = @PACKAGE_URL@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PKG_CONFIG = @PKG_CONFIG@
|
||||
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
|
||||
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
||||
POPT_CFLAGS = @POPT_CFLAGS@
|
||||
POPT_LIBS = @POPT_LIBS@
|
||||
POSUB = @POSUB@
|
||||
PYLINT = @PYLINT@
|
||||
PYTHON = @PYTHON@
|
||||
PYTHON2 = @PYTHON2@
|
||||
PYTHON3 = @PYTHON3@
|
||||
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
|
||||
PYTHON_INSTALL_EXTRA_OPTIONS = @PYTHON_INSTALL_EXTRA_OPTIONS@
|
||||
PYTHON_PLATFORM = @PYTHON_PLATFORM@
|
||||
PYTHON_PREFIX = @PYTHON_PREFIX@
|
||||
PYTHON_VERSION = @PYTHON_VERSION@
|
||||
RANLIB = @RANLIB@
|
||||
SAMBA40EXTRA_LIBPATH = @SAMBA40EXTRA_LIBPATH@
|
||||
SAMBAUTIL_CFLAGS = @SAMBAUTIL_CFLAGS@
|
||||
SAMBAUTIL_LIBS = @SAMBAUTIL_LIBS@
|
||||
SASL_CFLAGS = @SASL_CFLAGS@
|
||||
SASL_LIBS = @SASL_LIBS@
|
||||
SED = @SED@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
SSSCERTMAP_CFLAGS = @SSSCERTMAP_CFLAGS@
|
||||
SSSCERTMAP_LIBS = @SSSCERTMAP_LIBS@
|
||||
SSSIDMAP_CFLAGS = @SSSIDMAP_CFLAGS@
|
||||
SSSIDMAP_LIBS = @SSSIDMAP_LIBS@
|
||||
SSSNSSIDMAP_CFLAGS = @SSSNSSIDMAP_CFLAGS@
|
||||
SSSNSSIDMAP_LIBS = @SSSNSSIDMAP_LIBS@
|
||||
STRIP = @STRIP@
|
||||
TALLOC_CFLAGS = @TALLOC_CFLAGS@
|
||||
TALLOC_LIBS = @TALLOC_LIBS@
|
||||
TEVENT_CFLAGS = @TEVENT_CFLAGS@
|
||||
TEVENT_LIBS = @TEVENT_LIBS@
|
||||
UNISTRING_LIBS = @UNISTRING_LIBS@
|
||||
UNLINK = @UNLINK@
|
||||
USE_NLS = @USE_NLS@
|
||||
UUID_CFLAGS = @UUID_CFLAGS@
|
||||
UUID_LIBS = @UUID_LIBS@
|
||||
VENDOR_SUFFIX = @VENDOR_SUFFIX@
|
||||
VERSION = @VERSION@
|
||||
XGETTEXT = @XGETTEXT@
|
||||
XGETTEXT_015 = @XGETTEXT_015@
|
||||
XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
|
||||
XMLRPC_CFLAGS = @XMLRPC_CFLAGS@
|
||||
XMLRPC_LIBS = @XMLRPC_LIBS@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
i18ntests = @i18ntests@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
krb5rundir = @krb5rundir@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
pkgpyexecdir = @pkgpyexecdir@
|
||||
pkgpythondir = @pkgpythondir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
pyexecdir = @pyexecdir@
|
||||
pythondir = @pythondir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
sysconfenvdir = @sysconfenvdir@
|
||||
systemdsystemunitdir = @systemdsystemunitdir@
|
||||
systemdtmpfilesdir = @systemdtmpfilesdir@
|
||||
target_alias = @target_alias@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
AUTOMAKE_OPTIONS = 1.7
|
||||
NULL =
|
||||
SUBDIRS = \
|
||||
libs \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DIST = \
|
||||
build.profile.js \
|
||||
dojo.profile.js \
|
||||
freeipa \
|
||||
webui.profile.js
|
||||
|
||||
all: all-recursive
|
||||
|
||||
.SUFFIXES:
|
||||
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign install/ui/src/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --foreign install/ui/src/Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
|
||||
# This directory's subdirectories are mostly independent; you can cd
|
||||
# into them and run 'make' without going through this Makefile.
|
||||
# To change the values of 'make' variables: instead of editing Makefiles,
|
||||
# (1) if the variable is set in 'config.status', edit 'config.status'
|
||||
# (which will cause the Makefiles to be regenerated when you run 'make');
|
||||
# (2) otherwise, pass the desired values on the 'make' command line.
|
||||
$(am__recursive_targets):
|
||||
@fail=; \
|
||||
if $(am__make_keepgoing); then \
|
||||
failcom='fail=yes'; \
|
||||
else \
|
||||
failcom='exit 1'; \
|
||||
fi; \
|
||||
dot_seen=no; \
|
||||
target=`echo $@ | sed s/-recursive//`; \
|
||||
case "$@" in \
|
||||
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
|
||||
*) list='$(SUBDIRS)' ;; \
|
||||
esac; \
|
||||
for subdir in $$list; do \
|
||||
echo "Making $$target in $$subdir"; \
|
||||
if test "$$subdir" = "."; then \
|
||||
dot_seen=yes; \
|
||||
local_target="$$target-am"; \
|
||||
else \
|
||||
local_target="$$target"; \
|
||||
fi; \
|
||||
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||
|| eval $$failcom; \
|
||||
done; \
|
||||
if test "$$dot_seen" = "no"; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
|
||||
fi; test -z "$$fail"
|
||||
|
||||
ID: $(am__tagged_files)
|
||||
$(am__define_uniq_tagged_files); mkid -fID $$unique
|
||||
tags: tags-recursive
|
||||
TAGS: tags
|
||||
|
||||
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||
set x; \
|
||||
here=`pwd`; \
|
||||
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
|
||||
include_option=--etags-include; \
|
||||
empty_fix=.; \
|
||||
else \
|
||||
include_option=--include; \
|
||||
empty_fix=; \
|
||||
fi; \
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
if test "$$subdir" = .; then :; else \
|
||||
test ! -f $$subdir/TAGS || \
|
||||
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
|
||||
fi; \
|
||||
done; \
|
||||
$(am__define_uniq_tagged_files); \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
if test $$# -gt 0; then \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
"$$@" $$unique; \
|
||||
else \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: ctags-recursive
|
||||
|
||||
CTAGS: ctags
|
||||
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||
$(am__define_uniq_tagged_files); \
|
||||
test -z "$(CTAGS_ARGS)$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
cscopelist: cscopelist-recursive
|
||||
|
||||
cscopelist-am: $(am__tagged_files)
|
||||
list='$(am__tagged_files)'; \
|
||||
case "$(srcdir)" in \
|
||||
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
|
||||
*) sdir=$(subdir)/$(srcdir) ;; \
|
||||
esac; \
|
||||
for i in $$list; do \
|
||||
if test -f "$$i"; then \
|
||||
echo "$(subdir)/$$i"; \
|
||||
else \
|
||||
echo "$$sdir/$$i"; \
|
||||
fi; \
|
||||
done >> $(top_builddir)/cscope.files
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
|
||||
if test "$$subdir" = .; then :; else \
|
||||
$(am__make_dryrun) \
|
||||
|| test -d "$(distdir)/$$subdir" \
|
||||
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|
||||
|| exit 1; \
|
||||
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
|
||||
$(am__relativize); \
|
||||
new_distdir=$$reldir; \
|
||||
dir1=$$subdir; dir2="$(top_distdir)"; \
|
||||
$(am__relativize); \
|
||||
new_top_distdir=$$reldir; \
|
||||
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
|
||||
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
|
||||
($(am__cd) $$subdir && \
|
||||
$(MAKE) $(AM_MAKEFLAGS) \
|
||||
top_distdir="$$new_top_distdir" \
|
||||
distdir="$$new_distdir" \
|
||||
am__remove_distdir=: \
|
||||
am__skip_length_check=: \
|
||||
am__skip_mode_fix=: \
|
||||
distdir) \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-recursive
|
||||
all-am: Makefile
|
||||
installdirs: installdirs-recursive
|
||||
installdirs-am:
|
||||
install: install-recursive
|
||||
install-exec: install-exec-recursive
|
||||
install-data: install-data-recursive
|
||||
uninstall: uninstall-recursive
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-recursive
|
||||
install-strip:
|
||||
if test -z '$(STRIP)'; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
install; \
|
||||
else \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-recursive
|
||||
|
||||
clean-am: clean-generic clean-libtool mostlyclean-am
|
||||
|
||||
distclean: distclean-recursive
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-generic distclean-tags
|
||||
|
||||
dvi: dvi-recursive
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-recursive
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-recursive
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am:
|
||||
|
||||
install-dvi: install-dvi-recursive
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-html: install-html-recursive
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-recursive
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-recursive
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-recursive
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-recursive
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-recursive
|
||||
|
||||
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
|
||||
|
||||
pdf: pdf-recursive
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-recursive
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am:
|
||||
|
||||
.MAKE: $(am__recursive_targets) install-am install-strip
|
||||
|
||||
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
|
||||
check-am clean clean-generic clean-libtool cscopelist-am ctags \
|
||||
ctags-am distclean distclean-generic distclean-libtool \
|
||||
distclean-tags distdir dvi dvi-am html html-am info info-am \
|
||||
install install-am install-data install-data-am install-dvi \
|
||||
install-dvi-am install-exec install-exec-am install-html \
|
||||
install-html-am install-info install-info-am install-man \
|
||||
install-pdf install-pdf-am install-ps install-ps-am \
|
||||
install-strip installcheck installcheck-am installdirs \
|
||||
installdirs-am maintainer-clean maintainer-clean-generic \
|
||||
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
|
||||
ps ps-am tags tags-am uninstall uninstall-am
|
||||
|
||||
.PRECIOUS: Makefile
|
||||
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
108
install/ui/src/build.profile.js
Normal file
108
install/ui/src/build.profile.js
Normal file
@@ -0,0 +1,108 @@
|
||||
//
|
||||
// BUILDER profile
|
||||
//
|
||||
|
||||
var profile = (function(){
|
||||
return {
|
||||
basePath: ".",
|
||||
releaseDir: "../release",
|
||||
releaseName: "build",
|
||||
action: "release",
|
||||
|
||||
layerOptimize: false,
|
||||
optimize: false,
|
||||
cssOptimize: false,
|
||||
mini: true,
|
||||
stripConsole: "warn",
|
||||
selectorEngine: "lite",
|
||||
|
||||
staticHasFeatures: {
|
||||
"host-rhino":1,
|
||||
"host-browser":0,
|
||||
"host-node":0,
|
||||
"dom":0,
|
||||
"dojo-has-api":1,
|
||||
"dojo-xhr-factory":0,
|
||||
"dojo-inject-api":1,
|
||||
"dojo-timeout-api":0,
|
||||
"dojo-trace-api":1,
|
||||
"dojo-loader-catches":0,
|
||||
"dojo-dom-ready-api":0,
|
||||
"dojo-dom-ready-plugin":0,
|
||||
"dojo-ready-api":1,
|
||||
"dojo-error-api":1,
|
||||
"dojo-publish-privates":1,
|
||||
"dojo-gettext-api":1,
|
||||
"dojo-sniff":0,
|
||||
"dojo-loader":1,
|
||||
"dojo-test-xd":0,
|
||||
"dojo-test-sniff":0
|
||||
},
|
||||
|
||||
packages:[{
|
||||
name: "dojo",
|
||||
location: "dojo"
|
||||
},{
|
||||
name: "build",
|
||||
location: "build"
|
||||
}],
|
||||
|
||||
layers: {
|
||||
"build/build": {
|
||||
include: [
|
||||
'dojo/dojo',
|
||||
'build/buildControlBase',
|
||||
'build/argv',
|
||||
'build/build.profile',
|
||||
'build/discover',
|
||||
'build/messages',
|
||||
'build/removeComments',
|
||||
'build/fs',
|
||||
'build/main',
|
||||
'build/fileUtils',
|
||||
'build/process',
|
||||
'build/v1xProfiles',
|
||||
'build/replace',
|
||||
'build/fileHandleThrottle',
|
||||
'build/buildControl',
|
||||
'build/commandLineArgs',
|
||||
'build/stringify',
|
||||
'build/buildControlDefault',
|
||||
'build/version',
|
||||
'build/plugins/querySelector',
|
||||
'build/plugins/domReady',
|
||||
'build/plugins/has',
|
||||
'build/plugins/text',
|
||||
'build/plugins/loadInit',
|
||||
'build/plugins/require',
|
||||
'build/plugins/i18n',
|
||||
'build/transforms/depsDump',
|
||||
'build/transforms/copy',
|
||||
'build/transforms/trace',
|
||||
'build/transforms/read',
|
||||
'build/transforms/writeAmd',
|
||||
'build/transforms/dojoPragmas',
|
||||
'build/transforms/report',
|
||||
'build/transforms/hasFindAll',
|
||||
'build/transforms/hasFixup',
|
||||
'build/transforms/writeDojo',
|
||||
'build/transforms/depsScan',
|
||||
'build/transforms/write',
|
||||
'build/transforms/dojoReport',
|
||||
'build/transforms/writeOptimized',
|
||||
'build/transforms/insertSymbols',
|
||||
'build/transforms/hasReport',
|
||||
'build/transforms/writeCss',
|
||||
'build/transforms/depsDeclarative',
|
||||
'build/transforms/optimizeCss',
|
||||
'build/node/fs',
|
||||
'build/node/process',
|
||||
'build/rhino/fs',
|
||||
'build/rhino/process'
|
||||
],
|
||||
customBase: true,
|
||||
boot: true
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
||||
102
install/ui/src/dojo.profile.js
Normal file
102
install/ui/src/dojo.profile.js
Normal file
@@ -0,0 +1,102 @@
|
||||
//
|
||||
// DOJO profile
|
||||
//
|
||||
|
||||
var profile = (function(){
|
||||
return {
|
||||
basePath: ".",
|
||||
releaseDir: "../release",
|
||||
releaseName: "dojo",
|
||||
action: "release",
|
||||
|
||||
layerOptimize: false,
|
||||
optimize: false,
|
||||
cssOptimize: false,
|
||||
mini: true,
|
||||
stripConsole: "warn",
|
||||
selectorEngine: "lite",
|
||||
|
||||
defaultConfig: {
|
||||
hasCache:{
|
||||
"config-deferredInstrumentation": 0,
|
||||
"config-dojo-loader-catches": 0,
|
||||
"config-tlmSiblingOfDojo": 0,
|
||||
"dojo-amd-factory-scan": 0,
|
||||
"dojo-combo-api": 0,
|
||||
"dojo-config-api": 1,
|
||||
"dojo-config-require": 0,
|
||||
"dojo-debug-messages": 0,
|
||||
"dojo-dom-ready-api": 1,
|
||||
"dojo-firebug": 0,
|
||||
"dojo-guarantee-console": 1,
|
||||
"dojo-has-api": 1,
|
||||
"dojo-inject-api": 1,
|
||||
"dojo-loader": 1,
|
||||
"dojo-log-api": 0,
|
||||
"dojo-modulePaths": 0,
|
||||
"dojo-moduleUrl": 0,
|
||||
"dojo-publish-privates": 0,
|
||||
"dojo-requirejs-api": 0,
|
||||
"dojo-sniff": 0,
|
||||
"dojo-sync-loader": 0,
|
||||
"dojo-test-sniff": 0,
|
||||
"dojo-timeout-api": 0,
|
||||
"dojo-trace-api": 0,
|
||||
"dojo-undef-api": 0,
|
||||
"dojo-v1x-i18n-Api": 1,
|
||||
"dom": 1,
|
||||
"host-browser": 1,
|
||||
"extend-dojo": 1
|
||||
},
|
||||
async: 1
|
||||
},
|
||||
|
||||
|
||||
packages:[
|
||||
{
|
||||
name: "dojo",
|
||||
location: "dojo"
|
||||
}
|
||||
],
|
||||
|
||||
layers: {
|
||||
"dojo/dojo": {
|
||||
// explicitly include all modules which we want in our build
|
||||
include: [
|
||||
"dojo/dojo",
|
||||
"dojo/domReady",
|
||||
"dojo/_base/declare",
|
||||
// ^ core is about 20KB
|
||||
"dojo/_base/lang",
|
||||
"dojo/_base/array",
|
||||
"dojo/string",
|
||||
// ^ adds 10KB
|
||||
"dojo/dom",
|
||||
"dojo/dom-construct",
|
||||
"dojo/dom-class",
|
||||
"dojo/dom-style",
|
||||
"dojo/dom-prop",
|
||||
// ^ adds 20KB, with router only 5KB
|
||||
"dojo/Stateful",
|
||||
"dojo/Evented",
|
||||
"dojo/on",
|
||||
"dojo/io-query",
|
||||
//
|
||||
"dojo/keys",
|
||||
"dojo/router",
|
||||
"dojo/hash", //used by router
|
||||
"dojo/topic", //used by router
|
||||
// ^ adds 20 KB, most of it is dojo/dom*
|
||||
"dojo/store/Observable",
|
||||
"dojo/store/Memory",
|
||||
"dojo/query",
|
||||
"dojo/NodeList-dom",
|
||||
"dojo/promise/all"
|
||||
// Total size: 75KB
|
||||
],
|
||||
customBase: true,
|
||||
boot: true
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
||||
613
install/ui/src/freeipa/Application_controller.js
Normal file
613
install/ui/src/freeipa/Application_controller.js
Normal file
@@ -0,0 +1,613 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'dojo/_base/declare',
|
||||
'dojo/_base/array',
|
||||
'dojo/Deferred',
|
||||
'dojo/on',
|
||||
'dojo/topic',
|
||||
'dojo/query',
|
||||
'dojo/dom-class',
|
||||
'./auth',
|
||||
'./json2',
|
||||
'./widgets/App',
|
||||
'./widgets/FacetContainer',
|
||||
'./ipa',
|
||||
'./rpc',
|
||||
'./reg',
|
||||
'./config',
|
||||
'./widget',
|
||||
'./navigation/Menu',
|
||||
'./navigation/Router',
|
||||
'./navigation/routing',
|
||||
'./navigation/menu_spec',
|
||||
'./plugins/load_page'
|
||||
],
|
||||
function(declare, array, Deferred, on, topic, query, dom_class, auth,
|
||||
JSON, App_widget, FacetContainer, IPA, rpc, reg, config, widget_mod,
|
||||
Menu, Router, routing, menu_spec) {
|
||||
|
||||
/**
|
||||
* Application controller
|
||||
*
|
||||
* Controls interaction between navigation, menu and facets.
|
||||
*
|
||||
* @class Application_controller
|
||||
*/
|
||||
var App = declare(null, {
|
||||
|
||||
/**
|
||||
* Facet container map
|
||||
*/
|
||||
containers: null,
|
||||
|
||||
app_widget: null,
|
||||
|
||||
router: null,
|
||||
|
||||
menu: null,
|
||||
|
||||
initialized: false,
|
||||
|
||||
facet_changing: false,
|
||||
|
||||
/**
|
||||
* Listeners for user menu items
|
||||
*/
|
||||
on_profile_listener: null,
|
||||
on_passwd_reset_listener: null,
|
||||
on_logout_listener: null,
|
||||
on_item_select_listener: null,
|
||||
on_configuration_listerer: null,
|
||||
on_about_listener: null,
|
||||
|
||||
/**
|
||||
* Currently displayed facet
|
||||
*
|
||||
*/
|
||||
current_facet: null,
|
||||
|
||||
/**
|
||||
* Currently displayed facet container
|
||||
*/
|
||||
current_container: null,
|
||||
|
||||
init: function() {
|
||||
this.menu = new Menu();
|
||||
this.router = new Router();
|
||||
routing.init(this.router);
|
||||
|
||||
var body_node = query('body')[0];
|
||||
this.app_widget = new App_widget();
|
||||
this.app_widget.container_node = body_node;
|
||||
this.app_widget.menu_widget.set_menu(this.menu);
|
||||
|
||||
var simple_container = new FacetContainer();
|
||||
simple_container.container_node = body_node;
|
||||
|
||||
var notification_container = new FacetContainer({
|
||||
container_node: body_node,
|
||||
id: "notification",
|
||||
'class': ''
|
||||
});
|
||||
|
||||
this.containers = {
|
||||
// Default view
|
||||
main: {
|
||||
widget: this.app_widget
|
||||
},
|
||||
// Mainly for standalone facets
|
||||
simple: {
|
||||
widget: simple_container
|
||||
}
|
||||
};
|
||||
|
||||
this.register_user_menu_listeners();
|
||||
|
||||
on(this.router, 'facet-show', this.on_facet_show.bind(this));
|
||||
on(this.router, 'facet-change', this.on_facet_change.bind(this));
|
||||
on(this.router, 'facet-change-canceled', this.on_facet_canceled.bind(this));
|
||||
on(this.router, 'error', this.on_router_error.bind(this));
|
||||
topic.subscribe('phase-error', this.on_phase_error.bind(this));
|
||||
topic.subscribe('authenticate', this.on_authenticate.bind(this));
|
||||
|
||||
this.app_widget.render();
|
||||
this.app_widget.hide();
|
||||
simple_container.render();
|
||||
simple_container.hide();
|
||||
notification_container.render();
|
||||
var load_facet = reg.facet.get('load');
|
||||
this.show_facet(load_facet);
|
||||
IPA.opened_dialogs.start_handling(this);
|
||||
},
|
||||
|
||||
register_user_menu_listeners: function() {
|
||||
this.on_profile_listener = on(this.app_widget, 'profile-click',
|
||||
this.on_profile.bind(this));
|
||||
this.on_passwd_reset_listener = on(this.app_widget,
|
||||
'password-reset-click', this.on_password_reset.bind(this));
|
||||
this.on_logout_listener = on(this.app_widget, 'logout-click',
|
||||
this.on_logout.bind(this));
|
||||
this.on_item_select_listener = on(this.app_widget.menu_widget,
|
||||
'item-select', this.on_menu_click.bind(this));
|
||||
this.on_configuration_listerer = on(this.app_widget,
|
||||
'configuration-click', this.on_configuration.bind(this));
|
||||
this.on_about_listener = on(this.app_widget,
|
||||
'about-click', this.on_about.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Turns off one item in user dropdown menu and remove its listener.
|
||||
* @param {string} name of the user menu item which should be disabled
|
||||
* @param {Object} listener disable di
|
||||
*/
|
||||
disable_user_menu_item: function(name, listener) {
|
||||
this.app_widget.disable_user_menu_item(name);
|
||||
listener.remove();
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets:
|
||||
* * metadata
|
||||
* * server configuration
|
||||
* * user information
|
||||
*/
|
||||
get_configuration: function(success_handler, error_handler) {
|
||||
IPA.init({ on_success: success_handler, on_error: error_handler});
|
||||
},
|
||||
|
||||
/**
|
||||
* Deduces current application profile - administraion or self-service.
|
||||
* Initializes profiles's menu.
|
||||
*/
|
||||
choose_profile: function() {
|
||||
|
||||
this.update_logged_in(true);
|
||||
var selfservice = this.is_selfservice();
|
||||
|
||||
|
||||
this.app_widget.menu_widget.ignore_changes = true;
|
||||
|
||||
if (selfservice) {
|
||||
if (this.is_aduser_selfservice()) {
|
||||
this.menu.name = menu_spec.ad_self_service.name;
|
||||
this.menu.add_items(menu_spec.ad_self_service.items);
|
||||
this.disable_user_menu_item('password_reset',
|
||||
this.on_passwd_reset_listener);
|
||||
} else {
|
||||
this.menu.name = menu_spec.self_service.name;
|
||||
this.menu.add_items(menu_spec.self_service.items);
|
||||
}
|
||||
} else {
|
||||
this.menu.name = menu_spec.admin.name;
|
||||
this.menu.add_items(menu_spec.admin.items);
|
||||
}
|
||||
|
||||
this.app_widget.menu_widget.ignore_changes = false;
|
||||
this.app_widget.menu_widget.render();
|
||||
this.app_widget.menu_widget.select(this.menu.selected);
|
||||
},
|
||||
|
||||
start_runtime: function() {
|
||||
this.run_time = new Deferred();
|
||||
|
||||
// hide load or login facets
|
||||
this.hide_facet();
|
||||
|
||||
IPA.update_password_expiration();
|
||||
|
||||
// now we are ready for displaying a facet,
|
||||
// it can match a facet if hash is set
|
||||
this.router.startup();
|
||||
|
||||
// choose default facet if not defined by route
|
||||
if (!this.current_facet) {
|
||||
this.navigate_to_default();
|
||||
}
|
||||
|
||||
return this.run_time.promise;
|
||||
},
|
||||
|
||||
navigate_to_default: function() {
|
||||
if (IPA.is_selfservice) {
|
||||
this.on_profile();
|
||||
} else {
|
||||
routing.navigate(routing.default_path);
|
||||
}
|
||||
},
|
||||
|
||||
start_logout: function() {
|
||||
IPA.logout();
|
||||
},
|
||||
|
||||
is_selfservice: function() {
|
||||
var whoami = IPA.whoami.data;
|
||||
var self_service = true;
|
||||
|
||||
if (whoami.hasOwnProperty('memberof_group') &&
|
||||
whoami.memberof_group.indexOf('admins') !== -1) {
|
||||
self_service = false;
|
||||
} else if (whoami.hasOwnProperty('memberofindirect_group')&&
|
||||
whoami.memberofindirect_group.indexOf('admins') !== -1) {
|
||||
self_service = false;
|
||||
} else if (whoami.hasOwnProperty('memberof_role') &&
|
||||
whoami.memberof_role.length > 0) {
|
||||
self_service = false;
|
||||
} else if (whoami.hasOwnProperty('memberofindirect_role') &&
|
||||
whoami.memberofindirect_role.length > 0) {
|
||||
self_service = false;
|
||||
}
|
||||
|
||||
IPA.is_selfservice = self_service; // quite ugly, needed for users
|
||||
|
||||
return self_service;
|
||||
},
|
||||
|
||||
is_aduser_selfservice: function() {
|
||||
var selfservice = IPA.whoami.metadata.object === 'idoverrideuser';
|
||||
// quite ugly, needed for users and iduseroverride to hide breadcrumb
|
||||
IPA.is_aduser_selfservice = selfservice;
|
||||
|
||||
return selfservice;
|
||||
},
|
||||
|
||||
update_logged_in: function(logged_in) {
|
||||
this.app_widget.set('logged', logged_in);
|
||||
|
||||
var whoami = IPA.whoami;
|
||||
var fullname = '';
|
||||
var entity = whoami.metadata.object;
|
||||
|
||||
if (whoami.data.cn) {
|
||||
fullname = whoami.data.cn[0];
|
||||
} else if (whoami.data.displayname) {
|
||||
fullname = whoami.data.displayname[0];
|
||||
} else if (whoami.data.gecos) {
|
||||
fullname = whoami.data.gecos[0];
|
||||
} else if (whoami.data.krbprincipalname) {
|
||||
fullname = whoami.data.krbprincipalname[0];
|
||||
} else if (whoami.data.ipaoriginaluid) {
|
||||
fullname = whoami.data.ipaoriginaluid[0];
|
||||
}
|
||||
|
||||
this.app_widget.set('fullname', fullname);
|
||||
},
|
||||
|
||||
on_profile: function() {
|
||||
routing.navigate(['entity', IPA.whoami.metadata.object, 'details',
|
||||
IPA.whoami.metadata.arguments]);
|
||||
},
|
||||
|
||||
on_logout: function(event) {
|
||||
this.run_time.resolve();
|
||||
},
|
||||
|
||||
on_password_reset: function() {
|
||||
IPA.password_selfservice();
|
||||
},
|
||||
|
||||
on_configuration: function() {
|
||||
var dialog = IPA.dialog({
|
||||
title: '@i18n:customization.customization',
|
||||
fields: [
|
||||
{
|
||||
$type: 'text',
|
||||
name: 'pagination_size',
|
||||
label: '@i18n:customization.table_pagination',
|
||||
validators: ['positive_integer']
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
dialog.create_button({
|
||||
name: 'save',
|
||||
label: '@i18n:buttons.save',
|
||||
click: function () {
|
||||
if (!dialog.validate()) {
|
||||
widget_mod.focus_invalid(dialog);
|
||||
return;
|
||||
}
|
||||
var widget = dialog.get_field('pagination_size').widget;
|
||||
var new_value = widget.get_value()[0];
|
||||
config.set('table_page_size', new_value, true);
|
||||
topic.publish('change-pagination');
|
||||
dialog.close();
|
||||
}
|
||||
});
|
||||
|
||||
dialog.create_button({
|
||||
name: 'cancel',
|
||||
label: '@i18n:buttons.cancel',
|
||||
click: function () {
|
||||
dialog.close();
|
||||
}
|
||||
});
|
||||
|
||||
dialog.open();
|
||||
|
||||
var size = config.get('table_page_size').toString();
|
||||
dialog.get_field('pagination_size').set_value([size]);
|
||||
},
|
||||
|
||||
on_about: function() {
|
||||
var dialog = IPA.about_dialog();
|
||||
dialog.open();
|
||||
},
|
||||
|
||||
on_phase_error: function(error) {
|
||||
|
||||
error = error || {};
|
||||
var name = error.name || 'Runtime error';
|
||||
var error_container = $('<div/>', {
|
||||
'class': 'container facet-content facet-error'
|
||||
}).appendTo($('.app-container .content').empty());
|
||||
error_container.append($('<h1/>', { text: name }));
|
||||
var details = $('<div/>', {
|
||||
'class': 'error-details'
|
||||
}).appendTo(error_container);
|
||||
|
||||
details.append($('<p/>', { text: 'Web UI got in unrecoverable state during "' + error.phase + '" phase.' }));
|
||||
if (error.name) window.console.error(error.name);
|
||||
if (error.results) {
|
||||
details.append('<h3>Technical details:</h3>');
|
||||
var msg = error.results.message;
|
||||
if (msg) {
|
||||
window.console.error(msg);
|
||||
details.append($('<div/>', { text: msg }));
|
||||
}
|
||||
if (error.results.stack) {
|
||||
var stack = error.results.stack.toString();
|
||||
window.console.error(stack);
|
||||
details.append($('<div/>').append($('<code/>', { text: stack })));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
on_facet_change: function(event) {
|
||||
//this.facet_changing = true;
|
||||
var new_facet = event.facet;
|
||||
var current_facet = this.current_facet;
|
||||
|
||||
if (current_facet === new_facet) return;
|
||||
|
||||
if (current_facet && !current_facet.can_leave()) {
|
||||
var permit_clb = function() {
|
||||
// Some facet's might not call reset before this call but after
|
||||
// so they are still dirty. Calling reset prevent's opening of
|
||||
// dirty dialog again.
|
||||
if (current_facet.is_dirty()) current_facet.reset(); //TODO change
|
||||
this.router.navigate_to_hash(event.hash, event.facet);
|
||||
}.bind(this);
|
||||
|
||||
var dialog = current_facet.show_leave_dialog(permit_clb);
|
||||
this.router.canceled = true;
|
||||
dialog.open();
|
||||
}
|
||||
},
|
||||
|
||||
on_facet_canceled: function(event) {
|
||||
},
|
||||
|
||||
on_facet_state_changed: function(event) {
|
||||
if (event.facet === this.current_facet) {
|
||||
routing.update_hash(event.facet, event.state);
|
||||
}
|
||||
},
|
||||
|
||||
on_facet_show: function(event) {
|
||||
this.show_facet(event.facet);
|
||||
},
|
||||
|
||||
show_facet: function(facet) {
|
||||
|
||||
// prevent changing facet when authenticating
|
||||
if (this.current_facet && this.current_facet.name === 'login' &&
|
||||
!auth.current.authenticated && facet.requires_auth) {
|
||||
return;
|
||||
}
|
||||
|
||||
// choose container
|
||||
var container = this.containers[facet.preferred_container];
|
||||
if (!container) container = this.containers.main;
|
||||
|
||||
if (this.current_container !== container) {
|
||||
|
||||
if (this.current_container) {
|
||||
this.current_container.widget.hide();
|
||||
}
|
||||
|
||||
this.current_container = container;
|
||||
this.current_container.widget.show();
|
||||
}
|
||||
|
||||
// update menu
|
||||
var menu_item = this._find_menu_item(facet);
|
||||
if (menu_item) this.menu.select(menu_item);
|
||||
|
||||
// show facet
|
||||
if (!facet.container_node) {
|
||||
facet.container_node = container.widget.content_node;
|
||||
on(facet, 'facet-state-change', this.on_facet_state_changed.bind(this));
|
||||
}
|
||||
|
||||
if (this.current_facet !== facet) {
|
||||
IPA.opened_dialogs.hide();
|
||||
}
|
||||
|
||||
this.hide_facet();
|
||||
this.current_facet = facet;
|
||||
facet.show();
|
||||
IPA.opened_dialogs.focus_top();
|
||||
},
|
||||
|
||||
hide_facet: function() {
|
||||
|
||||
if (this.current_facet) {
|
||||
this.current_facet.hide();
|
||||
}
|
||||
this.current_facet = null;
|
||||
},
|
||||
|
||||
|
||||
_find_menu_item: function(facet) {
|
||||
|
||||
var items = [];
|
||||
|
||||
// entity facets
|
||||
if (facet.entity) {
|
||||
items = this.menu.query({ entity: facet.entity.name, facet: facet.name });
|
||||
}
|
||||
|
||||
// entity fallback
|
||||
if (!items.total && facet.entity) {
|
||||
items = this.menu.query({ entity: facet.entity.name });
|
||||
}
|
||||
|
||||
// normal facets
|
||||
if (!items.total) {
|
||||
items = this.menu.query({ facet: facet.name });
|
||||
}
|
||||
|
||||
// fallback: Top level item
|
||||
if (!items.total) {
|
||||
items = this.menu.query({ parent: null });
|
||||
}
|
||||
|
||||
if (items.total) {
|
||||
if (items.total === 1) return items[0];
|
||||
|
||||
// select the menu item with the most similar state as the facet
|
||||
var best = items[0];
|
||||
var best_score = 0;
|
||||
var item, i, j, l, score;
|
||||
var state = facet.state;
|
||||
for (i=0, l=items.total; i<l; i++) {
|
||||
item = items[i];
|
||||
score = 0;
|
||||
if (item.pkeys && facet.get_pkeys) {
|
||||
var pkeys = facet.get_pkeys();
|
||||
for (j=0, j=item.pkeys.length; j<l; j++) {
|
||||
if (pkeys.indexOf(item.pkeys[j]) > -1) score++;
|
||||
}
|
||||
}
|
||||
if (item.args) {
|
||||
for (var name in item.args) {
|
||||
if (!item.args.hasOwnProperty(name)) continue;
|
||||
if (state[name] == item.args[name]) score++;
|
||||
}
|
||||
}
|
||||
if (score > best_score) {
|
||||
best_score = score;
|
||||
best = item;
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
},
|
||||
|
||||
on_router_error: function(error) {
|
||||
|
||||
if (error.type === 'route') {
|
||||
this.navigate_to_default();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Tries to find menu item with assigned facet and navigate to it.
|
||||
*/
|
||||
on_menu_click: function(menu_item) {
|
||||
this._navigate_to_menu_item(menu_item);
|
||||
},
|
||||
|
||||
_navigate_to_menu_item: function(menu_item) {
|
||||
|
||||
if (menu_item.entity) {
|
||||
// entity pages
|
||||
routing.navigate([
|
||||
'entity',
|
||||
menu_item.entity,
|
||||
menu_item.facet,
|
||||
menu_item.pkeys,
|
||||
menu_item.args]);
|
||||
} else if (menu_item.facet) {
|
||||
// concrete facets
|
||||
routing.navigate(['generic', menu_item.facet, menu_item.args]);
|
||||
} else {
|
||||
// categories, select first posible child, it may be the last
|
||||
var children = this.menu.query({parent: menu_item.name });
|
||||
if (children.total) {
|
||||
var success = false;
|
||||
for (var i=0; i<children.total;i++) {
|
||||
success = this._navigate_to_menu_item(children[i]);
|
||||
if (success) break;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Starts authentication process in authentication UI
|
||||
* @returns {undefined}
|
||||
*/
|
||||
on_authenticate: function() {
|
||||
|
||||
var self = this;
|
||||
if (this.auth_ui === 'dialog') {
|
||||
var dummy_command = {
|
||||
execute: function() {
|
||||
topic.publish('auth-successful');
|
||||
}
|
||||
};
|
||||
|
||||
var dialog = IPA.unauthorized_dialog({
|
||||
close_on_escape: false,
|
||||
error_thrown: { name: '', message: ''},
|
||||
command: dummy_command
|
||||
});
|
||||
|
||||
dialog.open();
|
||||
} else {
|
||||
var facet = this.current_facet;
|
||||
|
||||
// we don't want the load facet to be displayed after successful auth
|
||||
if (facet && facet.name === 'load') {
|
||||
facet = null;
|
||||
}
|
||||
var login_facet = reg.facet.get('login');
|
||||
|
||||
on.once(login_facet, "logged_in", function() {
|
||||
if (facet) {
|
||||
self.show_facet(facet);
|
||||
}
|
||||
topic.publish('auth-successful');
|
||||
});
|
||||
this.show_facet(login_facet);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return App;
|
||||
});
|
||||
349
install/ui/src/freeipa/FieldBinder.js
Normal file
349
install/ui/src/freeipa/FieldBinder.js
Normal file
@@ -0,0 +1,349 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define(['dojo/_base/declare',
|
||||
'dojo/_base/lang',
|
||||
'dojo/on',
|
||||
'./util'
|
||||
],
|
||||
function(declare, lang, on, util) {
|
||||
|
||||
/**
|
||||
* Field binder
|
||||
*
|
||||
* Binds input widget with field - defines standard communication logic
|
||||
* between widget and a field.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* var binder = new FieldBinder(widget, field).bind();
|
||||
*
|
||||
* // or
|
||||
* var binder = new FieldBinder({
|
||||
* field: field,
|
||||
* widget: widget
|
||||
* });
|
||||
* binder.bind()
|
||||
*
|
||||
* @class FieldBinder
|
||||
*/
|
||||
var FieldBinder = declare([], {
|
||||
|
||||
/**
|
||||
* Field
|
||||
* @property {IPA.field}
|
||||
*/
|
||||
field: null,
|
||||
|
||||
/**
|
||||
* Widget
|
||||
* @property {IPA.input_widget}
|
||||
*/
|
||||
widget: null,
|
||||
|
||||
/**
|
||||
* Binder is enabled
|
||||
*
|
||||
* Handlers are not be called when set to false.
|
||||
*
|
||||
* @property {boolean}
|
||||
*/
|
||||
enabled: true,
|
||||
|
||||
/**
|
||||
* Handlers
|
||||
* @protected
|
||||
* @property {Function[]}
|
||||
*/
|
||||
handlers: null,
|
||||
|
||||
/**
|
||||
* Value update is in progress
|
||||
*
|
||||
* When set, binder should not react to field's nor widget's value-change
|
||||
* event.
|
||||
*
|
||||
* @property {boolean}
|
||||
*/
|
||||
updating: false,
|
||||
|
||||
/**
|
||||
* Bind widget with field
|
||||
*
|
||||
* Listens for field's:
|
||||
*
|
||||
* - enable-change
|
||||
* - valid-change
|
||||
* - value-change
|
||||
* - dirty-change
|
||||
* - require-change
|
||||
* - writable-change
|
||||
* - readonly-change
|
||||
* - reset
|
||||
*
|
||||
* Listens for widget's:
|
||||
*
|
||||
* - value-change
|
||||
* - undo-click
|
||||
*
|
||||
* @param {boolean} hard
|
||||
* Hard binding. Sets `field.widget` to `this.widget`.
|
||||
* This option is for backward compatibility.
|
||||
*/
|
||||
bind: function(hard) {
|
||||
|
||||
var field = this.field;
|
||||
var widget = this.widget;
|
||||
|
||||
if (hard) field.widget = widget;
|
||||
|
||||
this.handle(field, 'enable-change', this.on_field_enable_change);
|
||||
this.handle(field, 'valid-change', this.on_field_valid_change);
|
||||
this.handle(field, 'value-change', this.on_field_value_change);
|
||||
this.handle(field, 'dirty-change', this.on_field_dirty_change);
|
||||
this.handle(field, 'require-change', this.on_field_require_change);
|
||||
this.handle(field, 'writable-change', this.on_field_writable_change);
|
||||
this.handle(field, 'readonly-change', this.on_field_readonly_change);
|
||||
this.handle(field, 'acl-rights-change', this.on_field_acl_rights_change);
|
||||
this.handle(field, 'reset', this.on_field_reset);
|
||||
|
||||
this.handle(widget, 'value-change', this.on_widget_value_change);
|
||||
this.handle(widget, 'undo-click', this.on_widget_undo_click);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Unbind all handlers
|
||||
*/
|
||||
unbind: function() {
|
||||
|
||||
var handler;
|
||||
while ((handler = this.handlers.pop())) {
|
||||
handler.remove();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates and registers the handler.
|
||||
* Handler will be called in binder context and only if
|
||||
* `this.enabled === true`.
|
||||
*
|
||||
* Do not use `on(target, type, handler)` directly.
|
||||
*
|
||||
* @param {Function} handler
|
||||
* @return {Function} context bound handler
|
||||
* @protected
|
||||
*/
|
||||
handle: function(target, type, handler) {
|
||||
|
||||
var _this = this;
|
||||
|
||||
var hndlr = function() {
|
||||
if (_this.enabled !== true) return;
|
||||
else {
|
||||
handler.apply(_this, Array.prototype.slice.call(arguments, 0));
|
||||
}
|
||||
};
|
||||
|
||||
var reg_hndl = on(target, type, hndlr);
|
||||
this.handlers.push(reg_hndl);
|
||||
|
||||
return hndlr;
|
||||
},
|
||||
|
||||
/**
|
||||
* Field enable change handler
|
||||
*
|
||||
* Reflect enabled state to widget
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
on_field_enable_change: function(event) {
|
||||
this.widget.set_enabled(event.enabled);
|
||||
},
|
||||
|
||||
/**
|
||||
* Field valid change handler
|
||||
* @protected
|
||||
*/
|
||||
on_field_valid_change: function(event) {
|
||||
this.widget.set_valid(event.result);
|
||||
},
|
||||
|
||||
/**
|
||||
* Field dirty change handler
|
||||
*
|
||||
* Controls showing of widget's undo button
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
on_field_dirty_change: function(event) {
|
||||
|
||||
if (!this.field.undo) return;
|
||||
if (event.dirty) {
|
||||
this.widget.show_undo();
|
||||
} else {
|
||||
this.widget.hide_undo();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Field require change handler
|
||||
*
|
||||
* Updates widget's require state
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
on_field_require_change: function(event) {
|
||||
|
||||
this.widget.set_required(event.required);
|
||||
},
|
||||
|
||||
/**
|
||||
* Field require change handler
|
||||
*
|
||||
* Updates widget's require state
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
on_field_writable_change: function(event) {
|
||||
|
||||
this.widget.set_writable(event.writable);
|
||||
},
|
||||
|
||||
/**
|
||||
* Field require change handler
|
||||
*
|
||||
* Updates widget's require state
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
on_field_readonly_change: function(event) {
|
||||
|
||||
this.widget.set_read_only(event.read_only);
|
||||
},
|
||||
|
||||
/**
|
||||
* Field acl rights change handler
|
||||
* @protected
|
||||
*/
|
||||
on_field_acl_rights_change: function(event) {
|
||||
|
||||
var readable= event.rights.indexOf('r') > -1;
|
||||
if (this.widget.set_readable) {
|
||||
this.widget.set_readable(readable);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Field reset handler
|
||||
*
|
||||
* @param {Object} event
|
||||
* @protected
|
||||
*/
|
||||
on_field_reset: function(event) {
|
||||
this.copy_properties();
|
||||
},
|
||||
|
||||
/**
|
||||
* Field value change handler
|
||||
* @protected
|
||||
*/
|
||||
on_field_value_change: function(event) {
|
||||
|
||||
if (this.updating) return;
|
||||
|
||||
var format_result = util.format(this.field.ui_formatter, event.value);
|
||||
if (format_result.ok) {
|
||||
this.updating = true;
|
||||
this.widget.update(format_result.value);
|
||||
this.updating = false;
|
||||
} else {
|
||||
// this should not happen in ideal world
|
||||
window.console.warn('field format error: '+this.field.name);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Widget value change handler
|
||||
* @protected
|
||||
*/
|
||||
on_widget_value_change: function(event) {
|
||||
|
||||
if (this.updating) return;
|
||||
|
||||
var val = this.widget.save();
|
||||
var format_result = util.parse(this.field.ui_parser, val);
|
||||
if (format_result.ok) {
|
||||
this.updating = true;
|
||||
this.field.set_value(format_result.value);
|
||||
this.updating = false;
|
||||
} else {
|
||||
this.field.set_valid(format_result);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Widget undo click handler
|
||||
* @protected
|
||||
*/
|
||||
on_widget_undo_click: function(event) {
|
||||
|
||||
this.field.reset();
|
||||
},
|
||||
|
||||
/**
|
||||
* Copies `label`, `tooltip`, `measurement_unit`, `undo`, `writable`,
|
||||
* `read_only` from field to widget
|
||||
*/
|
||||
copy_properties: function() {
|
||||
|
||||
var field = this.field;
|
||||
var widget = this.widget;
|
||||
|
||||
if (field.label) widget.label = field.label;
|
||||
if (field.tooltip) widget.tooltip = field.tooltip;
|
||||
if (field.measurement_unit) widget.measurement_unit = field.measurement_unit;
|
||||
widget.undo = field.undo;
|
||||
widget.set_writable(field.writable);
|
||||
widget.set_read_only(field.read_only);
|
||||
widget.set_required(field.is_required());
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
constructor: function(arg1, arg2) {
|
||||
|
||||
this.handlers = [];
|
||||
|
||||
if (arg2) {
|
||||
this.field = arg1;
|
||||
this.widget = arg2;
|
||||
} else {
|
||||
arg1 = arg1 || {};
|
||||
this.field = arg1.field;
|
||||
this.widget = arg1.widget;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return FieldBinder;
|
||||
});
|
||||
203
install/ui/src/freeipa/FormMixin.js
Normal file
203
install/ui/src/freeipa/FormMixin.js
Normal file
@@ -0,0 +1,203 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define(['dojo/_base/declare',
|
||||
'dojo/on',
|
||||
'./builder',
|
||||
'./field',
|
||||
'./ordered-map'
|
||||
],
|
||||
function(declare, on, builder, field_mod, ordered_map) {
|
||||
|
||||
/**
|
||||
* Form mixin
|
||||
*
|
||||
* Manages fields and related logic.
|
||||
*
|
||||
* Expects that this mixin will be mixed in a class which will implement
|
||||
* `Stateful`.
|
||||
*
|
||||
* @class FormMixin
|
||||
*/
|
||||
var FormMixin = declare([], {
|
||||
|
||||
/**
|
||||
* Some field is dirty
|
||||
* @property {boolean}
|
||||
*/
|
||||
dirty: null,
|
||||
|
||||
/**
|
||||
* Fields
|
||||
* @property {ordered_map}
|
||||
*/
|
||||
fields: null,
|
||||
|
||||
/**
|
||||
* Builds fields on add if not already built
|
||||
*
|
||||
* @property {field.field_builder}
|
||||
*/
|
||||
field_builder: null,
|
||||
|
||||
/**
|
||||
* Raised when `dirty` state changes
|
||||
* @event dirty-change
|
||||
*/
|
||||
|
||||
/**
|
||||
* Raised after fields reset
|
||||
* @event reset
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get field by name
|
||||
* @param {string} name
|
||||
*/
|
||||
get_field: function(name) {
|
||||
return this.fields.get(name);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get all fields
|
||||
* @return {Array.<IPA.field>}
|
||||
*/
|
||||
get_fields: function() {
|
||||
return this.fields.values;
|
||||
},
|
||||
|
||||
/**
|
||||
* Add field
|
||||
* @param {IPA.field|Object|String} field
|
||||
* Field or field spec
|
||||
*/
|
||||
add_field: function(field) {
|
||||
field.container = this;
|
||||
var built = this.field_builder.build_field(field);
|
||||
this.register_field_listeners(built);
|
||||
this.fields.put(field.name, built);
|
||||
return built;
|
||||
},
|
||||
|
||||
/**
|
||||
* Add multiple fields
|
||||
* @param {Array} fields
|
||||
*/
|
||||
add_fields: function(fields) {
|
||||
|
||||
if (!fields) return [];
|
||||
|
||||
var built = [];
|
||||
for (var i=0; i<fields.length; i++) {
|
||||
var f = this.add_field(fields[i]);
|
||||
built.push(f);
|
||||
}
|
||||
return built;
|
||||
},
|
||||
|
||||
/**
|
||||
* Registers listeners for field events
|
||||
* @param {IPA.field} field
|
||||
* @protected
|
||||
*/
|
||||
register_field_listeners: function(field) {
|
||||
|
||||
on(field, 'dirty-change', this.on_field_dirty_change.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Field's dirty-change handler
|
||||
* @param {Object} event
|
||||
* @protected
|
||||
* @fires dirty-change
|
||||
*/
|
||||
on_field_dirty_change: function(event) {
|
||||
|
||||
var old = this.dirty;
|
||||
|
||||
if (event.dirty) {
|
||||
this.dirty = true;
|
||||
} else {
|
||||
this.dirty = this.is_dirty();
|
||||
}
|
||||
|
||||
if (old !== this.dirty) {
|
||||
this.emit('dirty-change', { source: this, dirty: this.dirty });
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Perform check if any field is dirty
|
||||
*
|
||||
* @return {boolean}
|
||||
* - true: some field is dirty
|
||||
* - false: all field's aren't dirty
|
||||
*/
|
||||
is_dirty: function() {
|
||||
var fields = this.get_fields();
|
||||
for (var i=0; i<fields.length; i++) {
|
||||
if (fields[i].enabled && fields[i].dirty) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Reset all fields
|
||||
* @fires reset
|
||||
*/
|
||||
reset: function() {
|
||||
|
||||
var fields = this.get_fields();
|
||||
for (var i=0; i<fields.length; i++) {
|
||||
var field = fields[i];
|
||||
field.reset();
|
||||
}
|
||||
|
||||
this.emit('reset', { source: this });
|
||||
},
|
||||
|
||||
/**
|
||||
* Validate all fields
|
||||
* @return {boolean} true when all fields are valid
|
||||
*/
|
||||
validate: function() {
|
||||
var valid = true;
|
||||
var fields = this.get_fields();
|
||||
for (var i=0; i<fields.length; i++) {
|
||||
var field = fields[i];
|
||||
valid = field.validate() && field.validate_required() && valid;
|
||||
}
|
||||
return valid;
|
||||
},
|
||||
|
||||
/** Constructor */
|
||||
constructor: function(spec) {
|
||||
|
||||
this.fields = ordered_map();
|
||||
var builder_spec = spec.field_builder || field_mod.field_builder;
|
||||
this.field_builder = builder.build(null, builder_spec);
|
||||
this.dirty = false;
|
||||
}
|
||||
});
|
||||
|
||||
return FormMixin;
|
||||
});
|
||||
426
install/ui/src/freeipa/_base/Builder.js
Normal file
426
install/ui/src/freeipa/_base/Builder.js
Normal file
@@ -0,0 +1,426 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define(['dojo/_base/declare',
|
||||
'dojo/_base/array',
|
||||
'dojo/_base/lang',
|
||||
'./construct',
|
||||
'./Construct_registry',
|
||||
'./Spec_mod'
|
||||
], function(declare, array, lang, construct, Construct_registry, Spec_mod) {
|
||||
|
||||
var undefined;
|
||||
|
||||
/**
|
||||
* Builder
|
||||
*
|
||||
* Builds objects based on their specification.
|
||||
* @class _base.Builder
|
||||
*/
|
||||
var Builder = declare(null, {
|
||||
/**
|
||||
* Construct registry
|
||||
* @property {_base.Construct_registry}
|
||||
*/
|
||||
registry: null,
|
||||
|
||||
/**
|
||||
* Specification modifier
|
||||
* @property {_base.Spec_mod}
|
||||
*/
|
||||
spec_mod: null,
|
||||
|
||||
/**
|
||||
* Default factory
|
||||
* @property {Function|null}
|
||||
*/
|
||||
factory: null,
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
* @property {Function|null}
|
||||
*/
|
||||
ctor: null,
|
||||
|
||||
/**
|
||||
* Array of spec modifiers.
|
||||
*
|
||||
* Are applied before build on spec object.
|
||||
*
|
||||
* Spec modifier can be:
|
||||
*
|
||||
* - a function which is called before build
|
||||
* - takes params: spec, context
|
||||
* - returns spec
|
||||
* - an object which is mixed in into spec
|
||||
* - an object with properties for Spec_mod
|
||||
*
|
||||
* @property {Array|null}
|
||||
*/
|
||||
pre_ops: null,
|
||||
|
||||
/**
|
||||
* Array of object modifiers.
|
||||
*
|
||||
* Object modifier is a function which is after build.
|
||||
*
|
||||
* - takes params: built object, spec, context
|
||||
* - returns object
|
||||
* @property {Array|null}
|
||||
*/
|
||||
post_ops: null,
|
||||
|
||||
/**
|
||||
* Controls what builder do when spec is a string. Possible values:
|
||||
*
|
||||
* - 'type'
|
||||
* - 'property'
|
||||
*
|
||||
* ##Type
|
||||
* Spec is type. Queries registry for obtaining construction spec.
|
||||
*
|
||||
* ##Property
|
||||
* Spec is a property of spec, name of property is set in
|
||||
* `string_property`. This mode should be combined with default
|
||||
* factory or ctor otherwise the build will fail.
|
||||
*
|
||||
* @property {string}
|
||||
*/
|
||||
string_mode: 'type',
|
||||
|
||||
/**
|
||||
* Property name for `string_mode` == `property`
|
||||
* @property {string}
|
||||
*/
|
||||
string_property: '',
|
||||
|
||||
/**
|
||||
* Build object based on spec.
|
||||
*
|
||||
* @param {string|Function|Object|Array} spec Build spec
|
||||
*
|
||||
* - **String**: type name, queries registry
|
||||
* - **Function**: factory or ctor
|
||||
* - **Object**: spec object
|
||||
* - **Array**: array of spec objects
|
||||
*
|
||||
* Build control properties of spec object:
|
||||
*
|
||||
* - $ctor: Function
|
||||
* - $factory: Function
|
||||
* - $mixim_spec: boolean
|
||||
* - $type: string
|
||||
* - $pre_ops: []
|
||||
* - $post_ops: []
|
||||
*
|
||||
* All other properties will be passed to object construction method.
|
||||
* @param {Object} context build context
|
||||
* @param {Object} overrides
|
||||
* Builder default factory and ctor is overridden by those specified
|
||||
* in overrides when overrides are set.
|
||||
*/
|
||||
build: function(spec, context, overrides) {
|
||||
|
||||
var f,c, pre, post;
|
||||
|
||||
if (spec === undefined || spec === null) return null;
|
||||
if (!construct.is_spec(spec)) return spec;
|
||||
|
||||
context = context || {};
|
||||
|
||||
// save
|
||||
if (overrides) {
|
||||
f = this.factory;
|
||||
c = this.ctor;
|
||||
pre = this.pre_ops;
|
||||
post = this.post_ops;
|
||||
if (typeof overrides === 'function') {
|
||||
if (construct.is_ctor(overrides)) {
|
||||
overrides = { $ctor: overrides };
|
||||
} else {
|
||||
overrides = { $factory: overrides };
|
||||
}
|
||||
}
|
||||
this.factory = overrides.$factory;
|
||||
this.ctor = overrides.$ctor;
|
||||
if (overrides.$pre_ops) this.pre_ops = overrides.$pre_ops;
|
||||
if (overrides.$post_ops) this.post_ops = overrides.$post_ops;
|
||||
}
|
||||
|
||||
// build
|
||||
var objects;
|
||||
if (lang.isArray(spec)) {
|
||||
objects = [];
|
||||
for (var i=0; i<spec.length; i++) {
|
||||
var obj = this._build(spec[i], context);
|
||||
objects.push(obj);
|
||||
}
|
||||
} else {
|
||||
objects = this._build(spec, context);
|
||||
}
|
||||
|
||||
// restore
|
||||
if (overrides) {
|
||||
this.factory = f;
|
||||
this.ctor = c;
|
||||
this.pre_ops = pre;
|
||||
this.post_ops = post;
|
||||
}
|
||||
|
||||
return objects;
|
||||
},
|
||||
|
||||
/**
|
||||
* Create new construction spec from an existing one based on object
|
||||
* specification object and save the new construction spec
|
||||
*
|
||||
* @param {Object} spec Specification object
|
||||
* @return {Object} Construction specification
|
||||
*/
|
||||
merge_spec: function(spec, force_mixin) {
|
||||
var cs = {};
|
||||
|
||||
if (typeof spec === 'function') {
|
||||
// spec ctor or factory
|
||||
|
||||
if (construct.is_ctor(spec)) {
|
||||
cs.ctor = spec;
|
||||
} else {
|
||||
cs.factory = spec;
|
||||
}
|
||||
} else if (typeof spec === 'string') {
|
||||
// spec is type name or spec property
|
||||
cs = this._get_cs_string(spec);
|
||||
} else if (typeof spec === 'object') {
|
||||
var c = spec.$ctor,
|
||||
f = spec.$factory,
|
||||
m = spec.$mixim_spec || force_mixin,
|
||||
t = spec.$type,
|
||||
pre = spec.$pre_ops,
|
||||
post = spec.$post_ops;
|
||||
|
||||
var s = lang.mixin({},spec);
|
||||
delete s.$ctor;
|
||||
delete s.$factory;
|
||||
delete s.$mixim_spec;
|
||||
delete s.$type;
|
||||
delete s.$pre_ops;
|
||||
delete s.$post_ops;
|
||||
|
||||
if (t) {
|
||||
cs = this._query_registry(t);
|
||||
if (cs.spec && m) {
|
||||
lang.mixin(cs.spec, s);
|
||||
} else {
|
||||
cs.spec = s;
|
||||
}
|
||||
} else {
|
||||
cs.spec = s;
|
||||
}
|
||||
|
||||
if (c) cs.ctor = c;
|
||||
if (f) cs.factory = f;
|
||||
|
||||
cs.pre_ops = cs.pre_ops || [];
|
||||
cs.post_ops = cs.post_ops || [];
|
||||
if (pre) cs.pre_ops.push.apply(cs.pre_ops, pre);
|
||||
if (post) cs.post_ops.push.apply(cs.post_ops, post);
|
||||
}
|
||||
return cs;
|
||||
},
|
||||
|
||||
/**
|
||||
* Build single object
|
||||
* @protected
|
||||
*/
|
||||
_build: function(spec, context) {
|
||||
var cs = this._get_construction_spec(spec);
|
||||
var obj = this._build_core(cs, context);
|
||||
return obj;
|
||||
},
|
||||
|
||||
/**
|
||||
* Normalizes construction specification
|
||||
* @protected
|
||||
*/
|
||||
_get_construction_spec: function(spec) {
|
||||
|
||||
var cs = this.merge_spec(spec);
|
||||
cs.spec = cs.spec || {};
|
||||
if (!cs.factory && !cs.ctor) {
|
||||
if (this.ctor) cs.ctor = this.ctor;
|
||||
else if (this.factory) cs.factory = this.factory;
|
||||
}
|
||||
|
||||
return cs;
|
||||
},
|
||||
|
||||
/**
|
||||
* Queries registry and returns copy of construction specification
|
||||
* @protected
|
||||
*/
|
||||
_query_registry: function(type) {
|
||||
|
||||
if (this.registry) {
|
||||
var cs = this.registry.get(type);
|
||||
if (!cs) cs = {};
|
||||
cs = construct.clone(cs);
|
||||
return cs;
|
||||
} else {
|
||||
throw {
|
||||
error: 'Build error: construct registry required',
|
||||
builder: this
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get cs from string according to string mode
|
||||
* @protected
|
||||
*/
|
||||
_get_cs_string: function(spec) {
|
||||
|
||||
var cs;
|
||||
if (this.string_mode === 'type') {
|
||||
cs = this._query_registry(spec);
|
||||
} else {
|
||||
var sp = {};
|
||||
sp[this.string_property] = spec;
|
||||
cs = { spec: sp };
|
||||
}
|
||||
return cs;
|
||||
},
|
||||
|
||||
/**
|
||||
* Core build method
|
||||
* @protected
|
||||
*/
|
||||
_build_core: function(construction_spec, context) {
|
||||
|
||||
var cs = construction_spec,
|
||||
obj = null;
|
||||
|
||||
if (!(cs.factory && typeof cs.factory === 'function') &&
|
||||
!(cs.ctor && typeof cs.ctor === 'function')) {
|
||||
throw {
|
||||
error: 'Build error: missing or invalid ctor or factory',
|
||||
code: 'no-ctor-fac',
|
||||
spec: cs
|
||||
};
|
||||
}
|
||||
|
||||
// deep clone to prevent modification of original spec by preops
|
||||
cs.spec = construct.clone(cs.spec);
|
||||
|
||||
cs.spec = this._run_preops(this.pre_ops, cs.spec, context);
|
||||
if (cs.pre_ops) {
|
||||
cs.spec = this._run_preops(cs.pre_ops, cs.spec, context);
|
||||
}
|
||||
cs.spec = cs.spec || {};
|
||||
|
||||
// do we want following?, remove?
|
||||
this.spec_mod.mod(cs.spec, cs.spec);
|
||||
this.spec_mod.del_rules(cs.spec);
|
||||
|
||||
try {
|
||||
if (cs.factory) {
|
||||
obj = cs.factory(cs.spec);
|
||||
} else {
|
||||
obj = new cs.ctor(cs.spec);
|
||||
}
|
||||
|
||||
obj = this._run_post_ops(this.post_ops, obj, cs.spec, context);
|
||||
if (cs.post_ops) {
|
||||
obj = this._run_post_ops(cs.post_ops, obj, cs.spec, context);
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.expected) {
|
||||
// expected exceptions thrown by builder just mean that
|
||||
// object is not to be built
|
||||
obj = null;
|
||||
} else {
|
||||
window.console.error(e.stack);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
},
|
||||
|
||||
/**
|
||||
* Apply pre_ops
|
||||
* @protected
|
||||
*/
|
||||
_run_preops: function(pre_ops, spec, context) {
|
||||
for (var i=0; i<pre_ops.length; i++) {
|
||||
var preop = pre_ops[i];
|
||||
var preop_t = typeof preop;
|
||||
if (preop_t === 'function') {
|
||||
spec = preop(spec, context);
|
||||
} else if (preop_t === 'object') {
|
||||
var temp = construct.clone(preop);
|
||||
this.spec_mod.mod(spec, temp);
|
||||
this.spec_mod.del_rules(temp);
|
||||
lang.mixin(spec, temp);
|
||||
}
|
||||
}
|
||||
return spec;
|
||||
},
|
||||
|
||||
/**
|
||||
* Apply post_ops
|
||||
* @protected
|
||||
*/
|
||||
_run_post_ops: function(post_ops, obj, spec, context) {
|
||||
for (var i=0; i<post_ops.length; i++) {
|
||||
var postop = post_ops[i];
|
||||
var postop_t = typeof postop;
|
||||
if (postop_t === 'function') {
|
||||
obj = postop(obj, spec, context);
|
||||
} else if (postop_t === 'object') {
|
||||
lang.mixin(obj, postop);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* set spec.registry to use Construct_registry instance
|
||||
*/
|
||||
constructor: function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
this.pre_ops = [];
|
||||
this.post_ops = [];
|
||||
if (spec.factory) this.factory = spec.factory;
|
||||
if (spec.ctor) this.ctor = spec.ctor;
|
||||
if (spec.registry) this.registry = spec.registry;
|
||||
else this.registry = new Construct_registry();
|
||||
if (spec.spec_mod) this.spec_mod = spec.spec_mod;
|
||||
else this.spec_mod = new Spec_mod();
|
||||
if (spec.pre_ops) this.pre_ops.push.call(this.pre_ops, spec.pre_ops);
|
||||
if (spec.post_ops) this.post_ops.push.call(this.post_ops, spec.post_ops);
|
||||
}
|
||||
});
|
||||
|
||||
return Builder;
|
||||
});
|
||||
196
install/ui/src/freeipa/_base/Construct_registry.js
Normal file
196
install/ui/src/freeipa/_base/Construct_registry.js
Normal file
@@ -0,0 +1,196 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define(['dojo/_base/declare',
|
||||
'dojo/_base/array',
|
||||
'dojo/_base/lang',
|
||||
'./construct'
|
||||
], function(declare, array, lang, construct) {
|
||||
|
||||
/**
|
||||
* Registry for storing construction specification.
|
||||
* @class _base.Construct_registry
|
||||
*/
|
||||
var Construct_registry = declare(null, {
|
||||
|
||||
|
||||
/**
|
||||
* Internal map for construction specifications.
|
||||
* @protected
|
||||
*/
|
||||
_map: null,
|
||||
|
||||
/**
|
||||
* Registers construction specification
|
||||
*
|
||||
* // May be defined by single construction spec object:
|
||||
* var construction_spec = {
|
||||
* type: String,
|
||||
* factory: Function,
|
||||
* ctor: Function,
|
||||
* spec: Object,
|
||||
* pre_ops: [],
|
||||
* post_ops: []
|
||||
* };
|
||||
* register(construction_spec);
|
||||
*
|
||||
* // or by defining them separately as params:
|
||||
* register(type, factory|ctor, spec);
|
||||
*
|
||||
* @param {string|Object} type type or construction spec
|
||||
* @param {Function} func ctor or factory function
|
||||
* @param {Object} [default_spec] default spec object for given type
|
||||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
register: function(type, func, default_spec) {
|
||||
|
||||
var cs, f, c;
|
||||
|
||||
if (typeof type === 'object') {
|
||||
cs = type;
|
||||
} else {
|
||||
construct.is_ctor(func) ? c = func : f = func;
|
||||
cs = {
|
||||
type: type,
|
||||
factory: f,
|
||||
ctor: c,
|
||||
spec: default_spec
|
||||
};
|
||||
}
|
||||
|
||||
if (!cs.pre_ops) cs.pre_ops = [];
|
||||
if (!cs.post_ops) cs.post_ops = [];
|
||||
|
||||
this._check_spec(cs);
|
||||
|
||||
this._map[cs.type] = cs;
|
||||
return cs;
|
||||
},
|
||||
|
||||
/**
|
||||
* Makes a copy of construct specification of original type. Extends
|
||||
* it with values in supplied construct specification.
|
||||
*
|
||||
* @param {string} org_type Original type
|
||||
* @param {string} new_type New type
|
||||
* @param {Object} construct_spec Construction specification
|
||||
*/
|
||||
copy: function(org_type, new_type, construct_spec) {
|
||||
|
||||
var def_cs = construct_spec;
|
||||
var old_cs = this._check_get(org_type);
|
||||
var cs = construct.clone(old_cs);
|
||||
|
||||
cs.type = new_type;
|
||||
if (def_cs.pre_ops) cs.pre_ops.push.apply(cs.pre_ops, def_cs.pre_ops);
|
||||
if (def_cs.post_ops) cs.post_ops.push.apply(cs.post_ops, def_cs.post_ops);
|
||||
if (def_cs.factory) cs.factory = def_cs.factory;
|
||||
if (def_cs.ctor) cs.ctor = def_cs.ctor;
|
||||
if (def_cs.spec) {
|
||||
cs.spec = cs.spec || {};
|
||||
lang.mixin(cs.spec, def_cs.spec);
|
||||
}
|
||||
|
||||
this._check_spec(cs);
|
||||
|
||||
this._map[cs.type] = cs;
|
||||
return cs;
|
||||
},
|
||||
|
||||
/**
|
||||
* Registers pre operation.
|
||||
*
|
||||
* Purpose of pre operation is to modify spec object before build
|
||||
* operation.
|
||||
*
|
||||
* When op is Function it gets called with spec as a param and should
|
||||
* return modified spec.
|
||||
*
|
||||
* When op is Object, the object gets mixed in into spec.
|
||||
*
|
||||
* @param {string} type
|
||||
* @param {Function|Object} op
|
||||
* @param {boolean} move op to first position
|
||||
*/
|
||||
register_pre_op: function(type, op, first) {
|
||||
|
||||
var cs = this._check_get(type);
|
||||
if (first) cs.pre_ops.unshift(op);
|
||||
else cs.pre_ops.push(op);
|
||||
},
|
||||
|
||||
/**
|
||||
* Registers post operation.
|
||||
*
|
||||
* Purpose of post operation is to modify built object.
|
||||
*
|
||||
* When op is Function it gets called with built object as a param
|
||||
* and should return modified obj.
|
||||
*
|
||||
* When op is Object, the object gets mixed in into built object. Use
|
||||
* with caution.
|
||||
*
|
||||
* @param {string} type
|
||||
* @param {Function|Object} op
|
||||
* @param {boolean} first move op to first position
|
||||
*/
|
||||
register_post_op: function(type, op, first) {
|
||||
|
||||
var cs = this._check_get(type);
|
||||
if (first) cs.post_ops.unshift(op);
|
||||
else cs.post_ops.push(op);
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets construction specification for given type.
|
||||
*
|
||||
* @param {string} string Type name
|
||||
* @returns {Object|null}
|
||||
*/
|
||||
get: function(type) {
|
||||
return this._map[type] || null;
|
||||
},
|
||||
|
||||
_check_get: function(type) {
|
||||
var cs = this.get(type);
|
||||
if (!cs) throw construct.no_cs_for_type_error(type);
|
||||
return cs;
|
||||
},
|
||||
|
||||
_check_spec: function(spec) {
|
||||
if (typeof spec.type !== 'string' || spec.type === '') {
|
||||
throw 'Argument exception: Invalid type';
|
||||
}
|
||||
if (!lang.isArrayLike(spec.pre_ops)) {
|
||||
throw 'Argument exception: Invalid pre_ops type.';
|
||||
}
|
||||
if (!lang.isArrayLike(spec.post_ops)) {
|
||||
throw 'Argument exception: Invalid post_ops type.';
|
||||
}
|
||||
},
|
||||
|
||||
constructor: function(spec) {
|
||||
this._map = {};
|
||||
}
|
||||
});
|
||||
|
||||
return Construct_registry;
|
||||
});
|
||||
258
install/ui/src/freeipa/_base/Phase_controller.js
Normal file
258
install/ui/src/freeipa/_base/Phase_controller.js
Normal file
@@ -0,0 +1,258 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'dojo/_base/array',
|
||||
'dojo/_base/declare',
|
||||
'dojo/Deferred',
|
||||
'dojo/promise/all',
|
||||
'dojo/topic',
|
||||
'../ordered-map'
|
||||
], function(array, declare, Deferred, all, topic, ordered_map) {
|
||||
|
||||
|
||||
/**
|
||||
* Phase
|
||||
*
|
||||
* This class does not exist, it's only for documentation purposes.
|
||||
*
|
||||
* @class _base.Phase_controller.phase
|
||||
* @abstract
|
||||
*/
|
||||
/**
|
||||
* Name
|
||||
* @property {string} name
|
||||
*/
|
||||
/**
|
||||
* Tasks
|
||||
* @property {Array.<_base.Phase_controller.task>} tasks
|
||||
*/
|
||||
|
||||
/**
|
||||
* Phase task
|
||||
*
|
||||
* This class does not exist, it's only for documentation purposes.
|
||||
*
|
||||
* @class _base.Phase_controller.task
|
||||
* @abstract
|
||||
*/
|
||||
/**
|
||||
* Name
|
||||
* @property {number} priority
|
||||
*/
|
||||
/**
|
||||
* Tasks
|
||||
* @property {Function} handler
|
||||
*/
|
||||
|
||||
/**
|
||||
* Phase Controller
|
||||
*
|
||||
* Creates synchronization points - phases - in application life cycle.
|
||||
*
|
||||
* Phases:
|
||||
*
|
||||
* - are ordered
|
||||
* - consist of task
|
||||
* - phase finishes when all task finishes
|
||||
* - new phases can be added at runtime
|
||||
*
|
||||
* @class _base.Phase_controller
|
||||
*/
|
||||
var Phase_controller = declare(null, {
|
||||
|
||||
/**
|
||||
* Phases
|
||||
* @property {ordered_map.<string, _base.Phase_controller.phase>}
|
||||
*/
|
||||
phases: null,
|
||||
|
||||
/**
|
||||
* Current phase name
|
||||
* @property {string}
|
||||
*/
|
||||
current: null,
|
||||
|
||||
/**
|
||||
* Run all phases in a row starting from current, or the first when
|
||||
* current is not set.
|
||||
*/
|
||||
run: function() {
|
||||
if (this.current !== null) {
|
||||
var phase = this.phases.get(this.current);
|
||||
this._run_phase(phase);
|
||||
} else {
|
||||
this.next_phase(true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Runs phase
|
||||
*
|
||||
* 1. Sorts tasks of the phase based on their priority.
|
||||
* 2. Runs all task sequentially.
|
||||
* 3. Waits for all tasks to complete (in case of asynchronous ones)
|
||||
* 4. Optionally runs next phase
|
||||
*
|
||||
* @param {_base.Phase_controller.phase} phase Phase to run
|
||||
* @param {boolean} next_phase Whether to run next phase when current finishes
|
||||
*/
|
||||
_run_phase: function(phase, next_phase) {
|
||||
|
||||
if (!phase) return;
|
||||
this.current = phase.name;
|
||||
topic.publish('phase-start', { phase: phase.name });
|
||||
var promises = [];
|
||||
|
||||
var tasks = phase.tasks.sort(function(a,b) {
|
||||
return a.priority-b.priority;
|
||||
});
|
||||
|
||||
array.forEach(tasks, function(task) {
|
||||
var promise;
|
||||
try {
|
||||
promise = task.handler();
|
||||
} catch (e) {
|
||||
var fail = new Deferred();
|
||||
fail.reject(e, true);
|
||||
promise = fail.promise;
|
||||
}
|
||||
promises.push(promise);
|
||||
});
|
||||
|
||||
all(promises).then(function(results) {
|
||||
topic.publish('phase-finished',
|
||||
{ phase: phase.name, results: results });
|
||||
if (next_phase) {
|
||||
this.next_phase(next_phase);
|
||||
}
|
||||
}.bind(this), function(results) {
|
||||
topic.publish('phase-error',
|
||||
{ phase: phase.name, results: results });
|
||||
// don't go for next phase on error, let app decide what to do
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Selects next phase and then runs it.
|
||||
*
|
||||
* @param {boolean} continuous Whether to run phases continuously
|
||||
*/
|
||||
next_phase: function(continuous) {
|
||||
var phase;
|
||||
|
||||
if (this.current === null) {
|
||||
phase = this.phases.get_value_by_index(0);
|
||||
} else {
|
||||
var index = this.phases.get_key_index(this.current);
|
||||
phase = this.phases.get_value_by_index(index + 1);
|
||||
}
|
||||
|
||||
this._run_phase(phase, continuous);
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds task for a phase.
|
||||
*
|
||||
* At phase execution, tasks are sorted by priority and executed in
|
||||
* that order.
|
||||
*
|
||||
* @param {string} phase_name Name of associated phase
|
||||
* @param {Function} handler Task handler. Should return promise if async.
|
||||
* @param {number} [priority=10] Priority of task.
|
||||
*/
|
||||
add_task: function(phase_name, handler, priority) {
|
||||
|
||||
var phase = this.phases.get(phase_name);
|
||||
|
||||
if (!phase) {
|
||||
window.console.warn('no such phase: ' + phase_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof priority !== 'number') priority = 10;
|
||||
|
||||
phase.tasks.push({
|
||||
priority: priority,
|
||||
handler: handler
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a phase
|
||||
*
|
||||
* Possible options:
|
||||
*
|
||||
* - before: 'name-of-phase'
|
||||
* - after: 'name-of-phase'
|
||||
* - position: 'position for new phase'
|
||||
*
|
||||
* @param {string} phase name
|
||||
* @param {Array.<_base.Phase_controller.task>} tasks
|
||||
* @param {Object} options
|
||||
*/
|
||||
add_phase: function(name, tasks, options) {
|
||||
|
||||
var phase = {
|
||||
name: name,
|
||||
tasks: tasks || []
|
||||
};
|
||||
|
||||
var position;
|
||||
if (options) {
|
||||
if (options.before) {
|
||||
position = this.phases.get_key_index(options.before);
|
||||
} else if (options.after) {
|
||||
position = this.phases.get_key_index(options.after);
|
||||
if (position === -1) position = this.phases.length;
|
||||
else position++;
|
||||
} else if (options.position) {
|
||||
position = options.position;
|
||||
}
|
||||
}
|
||||
|
||||
this.phases.put(name, phase, position);
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if phases with given name exists
|
||||
*
|
||||
* @param {string} name
|
||||
* @return {boolean}
|
||||
*/
|
||||
exists: function(name) {
|
||||
return !!this.phases.get(name);
|
||||
},
|
||||
|
||||
constructor: function(spec) {
|
||||
spec = spec || {};
|
||||
|
||||
this.phases = ordered_map();
|
||||
|
||||
var phases = spec.phases || [];
|
||||
array.forEach(phases, function(phase) {
|
||||
this.add_phase(phase);
|
||||
}.bind(this));
|
||||
}
|
||||
});
|
||||
|
||||
return Phase_controller;
|
||||
|
||||
});
|
||||
230
install/ui/src/freeipa/_base/Provider.js
Normal file
230
install/ui/src/freeipa/_base/Provider.js
Normal file
@@ -0,0 +1,230 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Value provider.
|
||||
*
|
||||
* It search source or child providers for value defined by key.
|
||||
*
|
||||
* Key consists of code and path.
|
||||
*
|
||||
* Code defines the type of resource. Provider's handles() method tells whether
|
||||
* it can handle this type of resource.
|
||||
*
|
||||
* Path is a plain object path within a source.
|
||||
*
|
||||
* // if source is
|
||||
* {
|
||||
* foo: {
|
||||
* bar: {
|
||||
* a: 'val'
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // path: `foo.bar.a` would return `val`
|
||||
*
|
||||
* @class _base.Provider
|
||||
*
|
||||
*/
|
||||
define([
|
||||
'dojo/_base/declare',
|
||||
'dojo/_base/lang',
|
||||
'./debug'],
|
||||
function(declare, lang, debug) {
|
||||
|
||||
var undefined;
|
||||
var Provider = declare(null, {
|
||||
|
||||
/**
|
||||
* Array of other providers
|
||||
* @property {_base.Provider[]}
|
||||
*/
|
||||
providers: null,
|
||||
|
||||
/**
|
||||
* Source object or a function which returns source object.
|
||||
* @property {Function|Object|_base.Provider}
|
||||
*/
|
||||
source: null,
|
||||
|
||||
/**
|
||||
* Path within a source.
|
||||
*
|
||||
* When defined, all lookups in source are based on the object
|
||||
* defined by this path within a source.
|
||||
* @property {string}
|
||||
*/
|
||||
path: null,
|
||||
|
||||
/**
|
||||
* Value which is returned if no value nor alternative is found
|
||||
* @property {Mixed}
|
||||
*/
|
||||
null_value: null,
|
||||
|
||||
/**
|
||||
* Specifies which type should be returned. Limited to output of
|
||||
* typeof operator.
|
||||
* @property {string}
|
||||
*/
|
||||
required_type: null,
|
||||
|
||||
_code: null,
|
||||
_code_length: null,
|
||||
_handling_provider: null,
|
||||
|
||||
_set_code: function(code) {
|
||||
this._code = code;
|
||||
if (code) this._code_length = code.length;
|
||||
},
|
||||
|
||||
_get_source: function() {
|
||||
var source;
|
||||
var type = typeof this.source;
|
||||
if (type === 'function') {
|
||||
source = this.source.call(this);
|
||||
} else if (type === 'object') {
|
||||
source = this.source;
|
||||
|
||||
// if source is another provider, use its source as this source
|
||||
if (source.isInstanceOf && source.isInstanceOf(Provider) &&
|
||||
source.source) {
|
||||
source = source._get_source();
|
||||
}
|
||||
}
|
||||
if (this.path) {
|
||||
source = lang.getObject(this.path, false, source);
|
||||
}
|
||||
return source;
|
||||
},
|
||||
|
||||
|
||||
_handles: function(key) {
|
||||
if (!this._code) return false;
|
||||
if (typeof key !== 'string') return false;
|
||||
if (key[0] !== '@') return false;
|
||||
var code = key.substring(0, this._code_length);
|
||||
var handles = code === this._code;
|
||||
return handles;
|
||||
},
|
||||
|
||||
_handle_children: function(key) {
|
||||
var handles = false;
|
||||
this._handling_provider = null;
|
||||
for (var i=0; i< this.providers.length; i++) {
|
||||
handles = this.providers[i].handles(key);
|
||||
if (handles) {
|
||||
this._handling_provider = this.providers[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return handles;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get's value from this provider's source
|
||||
* @protected
|
||||
*/
|
||||
_get: function(key) {
|
||||
var property = key.substring(this._code_length);
|
||||
var value = lang.getObject(property, false, this._get_source());
|
||||
return value;
|
||||
},
|
||||
|
||||
/**
|
||||
* Finds out whether this or some of its children handles given key.
|
||||
*/
|
||||
handles: function(key) {
|
||||
var handles = this._handles(key);
|
||||
handles = handles || this._handle_children(key);
|
||||
return handles;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets value.
|
||||
*
|
||||
* @param {string|Object} Key or value
|
||||
* @param {Object} Alternate value
|
||||
*/
|
||||
get: function(key, alternate) {
|
||||
|
||||
var value = key;
|
||||
if (key !== undefined) {
|
||||
if (this._handles(key)) {
|
||||
value = this._get(key);
|
||||
} else if(this._handle_children(key)) {
|
||||
value = this._handling_provider.get(key);
|
||||
} else {
|
||||
// Report invalid keys
|
||||
if (typeof key === 'string' && key[0] === '@') {
|
||||
window.console.warn('Using key as value:'+key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var ret = value || alternate;
|
||||
if (!ret && key && debug.provider_missing_value) {
|
||||
window.console.log('No value for:'+key);
|
||||
}
|
||||
|
||||
if ((this.required_type && typeof ret !== this.required_type) ||
|
||||
ret === null ||
|
||||
ret === undefined){
|
||||
ret = this.null_value;
|
||||
}
|
||||
|
||||
return ret;
|
||||
},
|
||||
|
||||
/**
|
||||
* Finds object with attr_name === value in array defined by key.
|
||||
*/
|
||||
find: function(key, attr_name, value) {
|
||||
|
||||
var arr = this.get(key);
|
||||
if (!lang.isArrayLike(arr)) return null;
|
||||
|
||||
for (var i=0; i<arr.length; i++) {
|
||||
if (arr[i][attr_name] === value) {
|
||||
return arr[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
constructor: function(spec) {
|
||||
spec = spec || {};
|
||||
this.source = spec.source || {};
|
||||
this.path = spec.path || null;
|
||||
this.providers = spec.providers || [];
|
||||
if (spec.null_value !== undefined) {
|
||||
this.null_value = spec.null_value;
|
||||
}
|
||||
this.required_type = spec.required_type;
|
||||
if (spec.code) {
|
||||
this._set_code(spec.code);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return Provider;
|
||||
});
|
||||
122
install/ui/src/freeipa/_base/Search_provider.js
Normal file
122
install/ui/src/freeipa/_base/Search_provider.js
Normal file
@@ -0,0 +1,122 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Search value provider
|
||||
*
|
||||
* Serves for searching for values within an array in a source object.
|
||||
*
|
||||
* Path has input formats as follows:
|
||||
*
|
||||
* * key1:key2:key3
|
||||
* * key1:key2
|
||||
* * key2
|
||||
*
|
||||
* With:
|
||||
*
|
||||
* * base_query: `%1.takes_params`
|
||||
* * array_attr: `name`
|
||||
*
|
||||
* Such path is translates into query:
|
||||
*
|
||||
* * `%key1.takes_params[name=%key2].$key3`
|
||||
*
|
||||
* In a future we should support defining generic queries and thus not be
|
||||
* limited to simple search.
|
||||
*
|
||||
* @class _base.Search_provider
|
||||
* @extends _base.Provider
|
||||
*/
|
||||
define(['dojo/_base/declare','dojo/_base/lang', './Provider'],
|
||||
function(declare, lang, Provider) {
|
||||
|
||||
var Search_provider = declare([Provider], {
|
||||
|
||||
base_query: null,
|
||||
array_attr: null,
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @protected
|
||||
*/
|
||||
_get: function(key) {
|
||||
var search_keys = key.substring(this._code_length);
|
||||
search_keys = search_keys.split(':');
|
||||
var count = search_keys.length;
|
||||
if (count < 1 || count > 3) return null;
|
||||
|
||||
var key1, key2, key3;
|
||||
if (count === 1) {
|
||||
key2 = search_keys[0];
|
||||
} else if (count === 2) {
|
||||
key1 = search_keys[0];
|
||||
key2 = search_keys[1];
|
||||
} else {
|
||||
key1 = search_keys[0];
|
||||
key2 = search_keys[1];
|
||||
key3 = search_keys[2];
|
||||
}
|
||||
|
||||
var arr;
|
||||
var source = arr = this._get_source();
|
||||
|
||||
if (key1) {
|
||||
var property = this.base_query.replace('%1', search_keys[0]);
|
||||
arr = lang.getObject(property, false, source);
|
||||
}
|
||||
var ret = this._find(arr, this.array_attr, key2, false);
|
||||
if (ret && key3) {
|
||||
ret = lang.getObject(key3, false, ret);
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
|
||||
/**
|
||||
* Finds object with attr_name === value in array defined by key.
|
||||
* @protected
|
||||
*/
|
||||
_find: function(array, attr, value, all) {
|
||||
|
||||
var vals = [];
|
||||
|
||||
if (!lang.isArrayLike(array)) return null;
|
||||
|
||||
for (var i=0; i<array.length; i++) {
|
||||
if (array[i][attr] === value) {
|
||||
vals.push(array[i]);
|
||||
if (!all) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!all) return vals[0] || null;
|
||||
|
||||
return vals;
|
||||
},
|
||||
|
||||
constructor: function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
this.base_query = spec.base_query || '%1';
|
||||
this.array_attr = spec.array_attr || 'name';
|
||||
}
|
||||
});
|
||||
|
||||
return Search_provider;
|
||||
});
|
||||
168
install/ui/src/freeipa/_base/Singleton_registry.js
Normal file
168
install/ui/src/freeipa/_base/Singleton_registry.js
Normal file
@@ -0,0 +1,168 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define(['dojo/_base/declare',
|
||||
'dojo/_base/array',
|
||||
'dojo/_base/lang',
|
||||
'./construct',
|
||||
'./Builder',
|
||||
'./Construct_registry'
|
||||
], function(declare, array, lang, construct, Builder, Construct_registry) {
|
||||
|
||||
/**
|
||||
* Registry for storing singleton instances of various items based
|
||||
* on their type.
|
||||
*
|
||||
* @class _base.Singleton_registry
|
||||
*/
|
||||
var Singleton_registry = declare(null, {
|
||||
|
||||
/**
|
||||
* Internal map for instances
|
||||
* @protected
|
||||
* @property {Object}
|
||||
*/
|
||||
_map: {},
|
||||
|
||||
/**
|
||||
* Builder used for building new instances. Builder has to have a
|
||||
* Constructor registry set.
|
||||
* @property {_base.Builder}
|
||||
*/
|
||||
builder: null,
|
||||
|
||||
/**
|
||||
* Gets an instance of given type. Creates a new one if it doesn't
|
||||
* exist.
|
||||
*
|
||||
* When an object is passed in, the function returns it.
|
||||
*
|
||||
* @param {string|Object} type Type's name. Or the object itself.
|
||||
* @return {Object|null}
|
||||
*/
|
||||
get: function(type) {
|
||||
|
||||
if (typeof type === 'object') return type;
|
||||
|
||||
var obj = this._map[type];
|
||||
|
||||
if (!obj) {
|
||||
if (!this.builder) return null;
|
||||
try {
|
||||
obj = this._map[type] = this.builder.build(type);
|
||||
} catch (e) {
|
||||
if (e.code === 'no-ctor-fac') obj = null;
|
||||
else {
|
||||
window.console.error('Error while building: ' + type);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set object of given type - overwrites existing
|
||||
*
|
||||
* @param {string} type
|
||||
* @param {Mixed} object
|
||||
*/
|
||||
set: function (type, obj) {
|
||||
this._map[type] = obj;
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes object of given type from registry
|
||||
*
|
||||
* @param {string} type
|
||||
*/
|
||||
remove: function(type) {
|
||||
|
||||
var undefined;
|
||||
this._map[type] = undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
* Registers construction specification
|
||||
*
|
||||
* @param {string|Object} type type or construction spec
|
||||
* @param {Function} func ctor or factory function
|
||||
* @param {Object} [default_spec] default spec object for given type
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
register: function(type, func, default_spec) {
|
||||
this._check_builder();
|
||||
this.builder.registry.register(type, func, default_spec);
|
||||
},
|
||||
|
||||
/**
|
||||
* Makes a copy of construct specification of original type. Extends
|
||||
* it with values in supplied construct specification.
|
||||
*
|
||||
* @param {string} org_type Original type
|
||||
* @param {string} new_type New type
|
||||
* @param {Object} construct_spec Construction specification
|
||||
*/
|
||||
copy: function(org_type, new_type, construct_spec) {
|
||||
this._check_builder();
|
||||
this.builder.registry.copy(org_type, new_type, construct_spec);
|
||||
},
|
||||
|
||||
/**
|
||||
* Create new construction specification based on an existing one and
|
||||
* a specification object. Save it as a new type.
|
||||
* @param {string|Function} type New type or a callback to get
|
||||
* the type: `callback(spec)`
|
||||
* @param {Object} spec Construction specification
|
||||
*/
|
||||
register_from_spec: function(type, spec) {
|
||||
this._check_builder();
|
||||
var cs = this.builder.merge_spec(spec, true);
|
||||
if (typeof type === 'function') {
|
||||
cs.type = type(cs.spec);
|
||||
} else {
|
||||
cs.type = type;
|
||||
}
|
||||
this.builder.registry.register(cs);
|
||||
},
|
||||
|
||||
_check_builder: function() {
|
||||
if (!lang.exists('builder.registry', this)) {
|
||||
throw {
|
||||
error: 'Object Initialized Exception: builder not initalized',
|
||||
context: this
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
constructor: function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
this._map = {};
|
||||
this.builder = spec.builder || new Builder({
|
||||
registry: new Construct_registry()
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return Singleton_registry;
|
||||
});
|
||||
242
install/ui/src/freeipa/_base/Spec_mod.js
Normal file
242
install/ui/src/freeipa/_base/Spec_mod.js
Normal file
@@ -0,0 +1,242 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define(['dojo/_base/declare',
|
||||
'dojo/_base/lang'
|
||||
], function(declare, lang) {
|
||||
|
||||
/**
|
||||
* Utility for common modification of specification objects
|
||||
*
|
||||
* @class _base.Spec_mod
|
||||
*/
|
||||
var Spec_mod = declare(null, {
|
||||
|
||||
/**
|
||||
* Modifies spec according to rules defined in diff object.
|
||||
*
|
||||
* Diff should have structure as follows:
|
||||
*
|
||||
* {
|
||||
* $add: array of add rules
|
||||
* $del: array of del rules
|
||||
* $set: array of set rules
|
||||
* $replace: array of replace rules
|
||||
* }
|
||||
*
|
||||
* The order of modification is del, add, set, replace.
|
||||
*
|
||||
* @param {Object} spec
|
||||
* @param {Object} diff
|
||||
*/
|
||||
mod: function(spec, diff) {
|
||||
|
||||
if (!diff) return spec;
|
||||
|
||||
this.del(spec, diff.$del);
|
||||
this.add(spec, diff.$add);
|
||||
this.set(spec, diff.$set);
|
||||
this.replace(spec, diff.$replace);
|
||||
|
||||
return spec;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Adds objects according to rules to array.
|
||||
*
|
||||
* A rule is a triple of path and a object and position to add:
|
||||
*
|
||||
* ['path.to.spec.array', {}, position]
|
||||
* @param {Object} spec
|
||||
* @param {Array} rules
|
||||
*/
|
||||
add: function(spec, rules) {
|
||||
|
||||
return this._apply_rules(spec, rules, this._add);
|
||||
},
|
||||
|
||||
/**
|
||||
* Deletes objects according to rules from an array.
|
||||
*
|
||||
* A rule is a pair of path and delete conditions:
|
||||
*
|
||||
* ['path.to.spec.array', [ { name: 'foo'}, { name: 'baz'} ]]
|
||||
* // Deletes all objects with name 'baz' or 'foo'.
|
||||
* @param {Object} spec
|
||||
* @param {Array} rules
|
||||
*/
|
||||
del: function(spec, rules) {
|
||||
|
||||
return this._apply_rules(spec, rules, this._del);
|
||||
},
|
||||
|
||||
/**
|
||||
* A rule is a pair of path and a object to set.
|
||||
*
|
||||
* ['path.to.spec.property', {}]
|
||||
* @param {Object} spec
|
||||
* @param {Array} rules
|
||||
*/
|
||||
set: function(spec, rules) {
|
||||
|
||||
return this._apply_rules(spec, rules, this._set);
|
||||
},
|
||||
|
||||
/**
|
||||
* Replace objects in an arrays
|
||||
*
|
||||
* A rule is a pair of path to an array and a objects to replace in that array
|
||||
*
|
||||
* [
|
||||
* 'path.to.spec.array',
|
||||
* [
|
||||
* [match, new_obj_spec],
|
||||
* [match2, new_obj_spec_2],
|
||||
* ...
|
||||
* ]
|
||||
* ]
|
||||
* Example of replacement specs:
|
||||
*
|
||||
* ['add', { name: 'add', hide_cond: [] }]
|
||||
* [{ name: 'add' }, { name: 'add', hide_cond: [] }]
|
||||
* @param {Object} spec
|
||||
* @param {Array} rules
|
||||
*/
|
||||
replace: function(spec, rules) {
|
||||
|
||||
return this._apply_rules(spec, rules, this._replace);
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes all rule props
|
||||
* @param {Object} diff
|
||||
*/
|
||||
del_rules: function(diff) {
|
||||
delete diff.$add;
|
||||
delete diff.$del;
|
||||
delete diff.$set;
|
||||
delete diff.$replace;
|
||||
},
|
||||
|
||||
_apply_rules: function(spec, rules, method) {
|
||||
if (!lang.isArrayLike(rules)) return spec;
|
||||
|
||||
for (var i=0; i<rules.length; i++) {
|
||||
method.call(this, spec, rules[i]);
|
||||
}
|
||||
|
||||
return spec;
|
||||
},
|
||||
|
||||
_add: function(spec, rule) {
|
||||
|
||||
var path = rule[0];
|
||||
var value = rule[1];
|
||||
var pos = rule[2];
|
||||
var arr = lang.getObject(path, false, spec);
|
||||
|
||||
if (!arr) {
|
||||
arr = [];
|
||||
lang.setObject(path, arr, spec);
|
||||
}
|
||||
|
||||
if (typeof pos !== 'number') pos = arr.length;
|
||||
else if (pos < 0) pos = 0;
|
||||
else if (pos > arr.length) pos = arr.length;
|
||||
|
||||
arr.splice(pos, 0, value);
|
||||
return spec;
|
||||
},
|
||||
|
||||
_del: function(spec, rule) {
|
||||
|
||||
var path = rule[0];
|
||||
var conds = rule[1];
|
||||
var arr = lang.getObject(path, false, spec);
|
||||
|
||||
if (!arr) return spec;
|
||||
|
||||
var del = [];
|
||||
var i,j;
|
||||
|
||||
for (i=0; i<arr.length; i++) {
|
||||
for (j=0; j<conds.length; j++) {
|
||||
if (this._match(arr[i], conds[j])) {
|
||||
del.push(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
del.sort(function(a,b) {return b-a;});
|
||||
for (i=0; i<del.length;i++) {
|
||||
arr.splice(del[i], 1);
|
||||
}
|
||||
return spec;
|
||||
},
|
||||
|
||||
_replace: function(spec, rule) {
|
||||
|
||||
var path = rule[0];
|
||||
var replace_rules = rule[1];
|
||||
var arr = lang.getObject(path, false, spec);
|
||||
if (!arr) return spec;
|
||||
|
||||
for (var i=0; i<replace_rules.length; i++) {
|
||||
var conds = replace_rules[i][0];
|
||||
var new_spec = replace_rules[i][1];
|
||||
|
||||
for (var j=0; j<arr.length; j++) {
|
||||
if (this._match(arr[j], conds)) {
|
||||
arr[j] = new_spec;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return spec;
|
||||
},
|
||||
|
||||
_match: function(value, cond) {
|
||||
var match = true;
|
||||
|
||||
if (typeof cond !== 'object') {
|
||||
match = cond === value;
|
||||
} else {
|
||||
for (var prop in cond) {
|
||||
if (cond.hasOwnProperty(prop) && cond[prop] !== value[prop]) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return match;
|
||||
},
|
||||
|
||||
_set: function(spec, rule) {
|
||||
lang.setObject(rule[0], rule[1], spec);
|
||||
return spec;
|
||||
}
|
||||
});
|
||||
|
||||
return Spec_mod;
|
||||
});
|
||||
126
install/ui/src/freeipa/_base/construct.js
Normal file
126
install/ui/src/freeipa/_base/construct.js
Normal file
@@ -0,0 +1,126 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define(['dojo/_base/declare',
|
||||
'dojo/_base/array',
|
||||
'dojo/_base/lang'
|
||||
], function(declare, array, lang) {
|
||||
|
||||
/**
|
||||
* Helper module
|
||||
* @class _base.construct
|
||||
* @singleton
|
||||
*/
|
||||
var construct = {
|
||||
|
||||
/**
|
||||
* Checks if supplied object is a constructor function.
|
||||
* It can recognize only classes declared by `dojo/_base/declare`.
|
||||
* @param {Object} obj
|
||||
*/
|
||||
is_ctor: function(obj) {
|
||||
|
||||
return typeof obj === 'function' && typeof obj.extend === 'function';
|
||||
},
|
||||
|
||||
/**
|
||||
* Finds out if object is a spec object.
|
||||
*
|
||||
* Object is not a spec object when it has an `isInstanceOf` function.
|
||||
*
|
||||
* @param {Object} obj
|
||||
*/
|
||||
is_spec: function(obj) {
|
||||
var ret = false;
|
||||
if (typeof obj === 'object') {
|
||||
ret = typeof obj.isInstanceOf === 'function';
|
||||
}
|
||||
return !ret;
|
||||
},
|
||||
|
||||
/**
|
||||
* Deep clone
|
||||
*
|
||||
* - does not clone framework objects
|
||||
* - fails on cyclic non-framework objects
|
||||
*
|
||||
* based on `dojo/_base/lang.clone`
|
||||
*
|
||||
* @param {Mixed} src object to clone
|
||||
*/
|
||||
clone: function(src) {
|
||||
|
||||
if(!src || typeof src != "object" || lang.isFunction(src)) {
|
||||
// null, undefined, any non-object, or function
|
||||
return src; // anything
|
||||
}
|
||||
if(src.nodeType && "cloneNode" in src) {
|
||||
// DOM Node
|
||||
return src.cloneNode(true); // Node
|
||||
}
|
||||
if (!construct.is_spec(src)) {
|
||||
// framework object
|
||||
return src;
|
||||
}
|
||||
if (src instanceof Date) {
|
||||
// Date
|
||||
return new Date(src.getTime()); // Date
|
||||
}
|
||||
if (src instanceof RegExp) {
|
||||
// RegExp
|
||||
return new RegExp(src); // RegExp
|
||||
}
|
||||
var r, i, l;
|
||||
if (lang.isArray(src)){
|
||||
// array
|
||||
r = [];
|
||||
for (i = 0, l = src.length; i < l; ++i) {
|
||||
if (i in src){
|
||||
r.push(construct.clone(src[i]));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// generic objects
|
||||
r = src.constructor ? new src.constructor() : {};
|
||||
}
|
||||
return lang._mixin(r, src, construct.clone);
|
||||
},
|
||||
|
||||
/**
|
||||
* Run object's init function after instantiation if it has one
|
||||
* @param {Object} obj
|
||||
* @param {Object} spec
|
||||
*/
|
||||
init_post_op: function(obj, spec) {
|
||||
if (obj && typeof obj.init === 'function') {
|
||||
obj.init(spec);
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
no_cs_for_type_error: function(type) {
|
||||
return {
|
||||
error: 'No construction specification for given type',
|
||||
type: type
|
||||
};
|
||||
}
|
||||
};
|
||||
return construct;
|
||||
});
|
||||
41
install/ui/src/freeipa/_base/debug.js
Normal file
41
install/ui/src/freeipa/_base/debug.js
Normal file
@@ -0,0 +1,41 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2014 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
define([], function() {
|
||||
|
||||
/**
|
||||
* Debug module
|
||||
*
|
||||
* One can set flags to enable console output of various messages.
|
||||
*
|
||||
* """
|
||||
* var debug = require('freeipa._base.debug');
|
||||
* debug.provider_missing_value = true;
|
||||
* """
|
||||
*
|
||||
* Currently used flags
|
||||
*
|
||||
* - provider_missing_value
|
||||
*
|
||||
* @class _base.debug
|
||||
*/
|
||||
return {
|
||||
provider_missing_value: false
|
||||
};
|
||||
});
|
||||
42
install/ui/src/freeipa/_base/i18n.js
Normal file
42
install/ui/src/freeipa/_base/i18n.js
Normal file
@@ -0,0 +1,42 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets translated message.
|
||||
*
|
||||
* If a message starts with `@i18n`: it tries to get the message from
|
||||
* message object. If it doesn't contain a string with
|
||||
* the key it returns alternate string.
|
||||
*
|
||||
* It all other cases the message itself or empty string is returned.
|
||||
* @class _base.i18n
|
||||
* @extends _base.Provider
|
||||
* @singleton
|
||||
*/
|
||||
define(['dojo/_base/lang', './Provider'], function(lang, Provider) {
|
||||
|
||||
var i18n = new Provider({
|
||||
code: '@i18n:',
|
||||
null_value: '',
|
||||
required_type: 'string'
|
||||
});
|
||||
|
||||
return i18n;
|
||||
});
|
||||
972
install/ui/src/freeipa/aci.js
Normal file
972
install/ui/src/freeipa/aci.js
Normal file
@@ -0,0 +1,972 @@
|
||||
/* Authors:
|
||||
* Adam Young <ayoung@redhat.com>
|
||||
* Endi S. Dewata <edewata@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'dojo/on',
|
||||
'./metadata',
|
||||
'./ipa',
|
||||
'./jquery',
|
||||
'./phases',
|
||||
'./reg',
|
||||
'./text',
|
||||
'./details',
|
||||
'./search',
|
||||
'./association',
|
||||
'./entity'],
|
||||
function(on, metadata_provider, IPA, $, phases, reg, text) {
|
||||
|
||||
/**
|
||||
* Widgets, entities and fields related to Access Control that means
|
||||
* Permissions, Privilege, Role, Delegation and Self-service.
|
||||
*
|
||||
* @class aci
|
||||
* @singleton
|
||||
*/
|
||||
var aci = {};
|
||||
|
||||
/**
|
||||
* List of fields which are disabled for managed permissions
|
||||
* @property {Array}
|
||||
*/
|
||||
aci.managed_fields = [
|
||||
'ipapermright', 'extratargetfilter', 'memberof', 'ipapermlocation',
|
||||
'ipapermtarget', 'type'
|
||||
];
|
||||
|
||||
var make_permission_spec = function() {
|
||||
|
||||
return {
|
||||
name: 'permission',
|
||||
facet_groups: ['settings', 'privilege'],
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
columns: [ 'cn' ]
|
||||
},
|
||||
{
|
||||
$factory: aci.permission_details_facet,
|
||||
$type: 'details',
|
||||
fields: [
|
||||
{
|
||||
name:'cn',
|
||||
widget: 'identity.cn'
|
||||
},
|
||||
{
|
||||
$type: 'radio',
|
||||
name:'ipapermbindruletype',
|
||||
widget: 'identity.ipapermbindruletype',
|
||||
flags: ['w_if_no_aci']
|
||||
},
|
||||
{
|
||||
$type: 'rights',
|
||||
name: 'ipapermright',
|
||||
widget: 'identity.ipapermright',
|
||||
required: true,
|
||||
flags: ['w_if_no_aci']
|
||||
},
|
||||
{
|
||||
$type: 'multivalued',
|
||||
name: 'extratargetfilter',
|
||||
widget: 'target.extratargetfilter',
|
||||
acl_param: 'ipapermtargetfilter',
|
||||
enabled: false,
|
||||
flags: ['w_if_no_aci']
|
||||
},
|
||||
{
|
||||
$type: 'multivalued',
|
||||
name: 'memberof',
|
||||
widget: 'target.memberof',
|
||||
enabled: false,
|
||||
flags: ['w_if_no_aci']
|
||||
},
|
||||
{
|
||||
name: 'ipapermlocation',
|
||||
widget: 'target.ipapermlocation',
|
||||
enabled: false,
|
||||
flags: ['w_if_no_aci']
|
||||
},
|
||||
{
|
||||
name: 'ipapermtarget',
|
||||
widget: 'target.ipapermtarget',
|
||||
enabled: false,
|
||||
flags: ['w_if_no_aci']
|
||||
},
|
||||
{
|
||||
$type: 'select',
|
||||
name: 'type',
|
||||
widget: 'target.type',
|
||||
enabled: false,
|
||||
flags: ['w_if_no_aci']
|
||||
|
||||
},
|
||||
{
|
||||
name: 'attrs',
|
||||
widget: 'target.attrs',
|
||||
enabled: false,
|
||||
flags: ['w_if_no_aci']
|
||||
},
|
||||
{
|
||||
name: 'attrs_multi',
|
||||
param: 'attrs',
|
||||
$type: 'multivalued',
|
||||
widget: 'target.attrs_multi',
|
||||
enabled: false,
|
||||
flags: ['w_if_no_aci']
|
||||
},
|
||||
{
|
||||
name: 'ipapermdefaultattr',
|
||||
$type: 'multivalued',
|
||||
widget: 'managed.ipapermdefaultattr'
|
||||
},
|
||||
{
|
||||
name: 'ipapermincludedattr',
|
||||
$type: 'multivalued',
|
||||
widget: 'managed.ipapermincludedattr',
|
||||
read_only: true
|
||||
},
|
||||
{
|
||||
name: 'ipapermexcludedattr',
|
||||
$type: 'multivalued',
|
||||
widget: 'managed.ipapermexcludedattr',
|
||||
read_only: true
|
||||
}
|
||||
],
|
||||
widgets: [
|
||||
{
|
||||
$type: 'details_section',
|
||||
name: 'identity',
|
||||
label: '@i18n:objects.permission.identity',
|
||||
widgets: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'ipapermbindruletype',
|
||||
options: ['permission', 'all', 'anonymous']
|
||||
},
|
||||
{
|
||||
$type: 'rights',
|
||||
name: 'ipapermright',
|
||||
layout: 'columns'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'permission_target',
|
||||
container_factory: IPA.details_section,
|
||||
label: '@i18n:objects.permission.target',
|
||||
name: 'target'
|
||||
},
|
||||
{
|
||||
$type: 'details_section',
|
||||
name: 'managed',
|
||||
label: '@i18n:objects.permission.managed',
|
||||
widgets: [
|
||||
{
|
||||
$type: 'multivalued',
|
||||
name: 'ipapermdefaultattr'
|
||||
},
|
||||
{
|
||||
$type: 'multivalued',
|
||||
name: 'ipapermincludedattr'
|
||||
},
|
||||
{
|
||||
$type: 'multivalued',
|
||||
name: 'ipapermexcludedattr'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
policies: [
|
||||
aci.permission_managed_policy,
|
||||
{
|
||||
$factory: aci.permission_target_policy,
|
||||
widget_name: 'target'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'association',
|
||||
name: 'member_privilege',
|
||||
facet_group: 'privilege'
|
||||
}
|
||||
],
|
||||
adder_dialog: {
|
||||
height: 450,
|
||||
fields: [
|
||||
{
|
||||
name:'cn',
|
||||
widget: 'general.cn'
|
||||
},
|
||||
{
|
||||
$type: 'radio',
|
||||
name:'ipapermbindruletype',
|
||||
widget: 'general.ipapermbindruletype'
|
||||
},
|
||||
{
|
||||
$type: 'rights',
|
||||
name: 'ipapermright',
|
||||
widget: 'general.ipapermright',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
$type: 'multivalued',
|
||||
name: 'extratargetfilter',
|
||||
widget: 'target.extratargetfilter',
|
||||
acl_param: 'ipapermtargetfilter',
|
||||
enabled: false
|
||||
},
|
||||
{
|
||||
$type: 'multivalued',
|
||||
name: 'memberof',
|
||||
widget: 'target.memberof',
|
||||
enabled: false
|
||||
},
|
||||
{
|
||||
name: 'ipapermlocation',
|
||||
widget: 'target.ipapermlocation',
|
||||
enabled: false
|
||||
},
|
||||
{
|
||||
name: 'ipapermtarget',
|
||||
widget: 'target.ipapermtarget',
|
||||
enabled: false
|
||||
},
|
||||
{
|
||||
$type: 'select',
|
||||
name: 'type',
|
||||
widget: 'target.type',
|
||||
enabled: false
|
||||
},
|
||||
{
|
||||
name: 'attrs',
|
||||
widget: 'target.attrs',
|
||||
enabled: false
|
||||
},
|
||||
{
|
||||
name: 'attrs_multi',
|
||||
$type: 'multivalued',
|
||||
param: 'attrs',
|
||||
widget: 'target.attrs_multi',
|
||||
enabled: false
|
||||
}
|
||||
],
|
||||
widgets: [
|
||||
{
|
||||
$type: 'details_section',
|
||||
name: 'general',
|
||||
widgets: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'ipapermbindruletype',
|
||||
options: ['permission', 'all', 'anonymous'],
|
||||
default_value: 'permission'
|
||||
},
|
||||
{
|
||||
$type: 'rights',
|
||||
name: 'ipapermright',
|
||||
layout: 'columns'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'permission_target',
|
||||
name:'target'
|
||||
}
|
||||
],
|
||||
policies: [
|
||||
{
|
||||
$factory: aci.permission_target_policy,
|
||||
widget_name: 'target'
|
||||
}
|
||||
]
|
||||
}
|
||||
};};
|
||||
|
||||
/**
|
||||
* @class aci.permission_details_facet
|
||||
* @extends details.details_facet
|
||||
*/
|
||||
aci.permission_details_facet = function(spec) {
|
||||
|
||||
var that = IPA.details_facet(spec);
|
||||
|
||||
that.get_refresh_command_name = function() {
|
||||
return that.entity.name+'_show_'+that.get_pkey();
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
var make_privilege_spec = function() {
|
||||
return {
|
||||
name: 'privilege',
|
||||
facet_groups: ['permission', 'settings', 'role'],
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
columns: [
|
||||
'cn',
|
||||
'description'
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
sections: [
|
||||
{
|
||||
name: 'identity',
|
||||
label: '@i18n:details.identity',
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'association',
|
||||
name: 'member_role',
|
||||
facet_group: 'role',
|
||||
add_method: 'add_privilege',
|
||||
remove_method: 'remove_privilege',
|
||||
associator: IPA.serial_associator
|
||||
},
|
||||
{
|
||||
$type: 'association',
|
||||
name: 'memberof_permission',
|
||||
facet_group: 'permission',
|
||||
add_method: 'add_permission',
|
||||
remove_method: 'remove_permission'
|
||||
}
|
||||
],
|
||||
standard_association_facets: true,
|
||||
adder_dialog: {
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
};};
|
||||
|
||||
var make_role_spec = function() {
|
||||
return {
|
||||
name: 'role',
|
||||
facet_groups: ['member', 'privilege', 'settings'],
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
columns: [
|
||||
'cn',
|
||||
'description'
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
sections: [
|
||||
{
|
||||
name: 'identity',
|
||||
label: '@i18n:objects.role.identity',
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'association',
|
||||
name: 'memberof_privilege',
|
||||
facet_group: 'privilege',
|
||||
add_method: 'add_privilege',
|
||||
remove_method: 'remove_privilege'
|
||||
}
|
||||
],
|
||||
standard_association_facets: true,
|
||||
adder_dialog: {
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
};};
|
||||
|
||||
var make_selfservice_spec = function() {
|
||||
return {
|
||||
name: 'selfservice',
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
columns: [ 'aciname' ],
|
||||
pagination: false
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
check_rights: false,
|
||||
sections: [
|
||||
{
|
||||
name: 'general',
|
||||
label: '@i18n:details.general',
|
||||
fields: [
|
||||
'aciname',
|
||||
{
|
||||
$type: 'attributes',
|
||||
object_type: 'user',
|
||||
name: 'attrs'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
adder_dialog: {
|
||||
fields: [
|
||||
'aciname',
|
||||
{
|
||||
$type: 'attributes',
|
||||
object_type: 'user',
|
||||
name: 'attrs'
|
||||
}
|
||||
]
|
||||
}
|
||||
};};
|
||||
|
||||
|
||||
var make_delegation_spec = function() {
|
||||
return {
|
||||
name: 'delegation',
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
columns: [ 'aciname' ],
|
||||
pagination: false
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
check_rights: false,
|
||||
sections: [
|
||||
{
|
||||
name: 'general',
|
||||
label: '@i18n:details.general',
|
||||
fields: [
|
||||
'aciname',
|
||||
{
|
||||
$type: 'checkboxes',
|
||||
name: 'permissions',
|
||||
required: true,
|
||||
options: IPA.create_options(['read', 'write'])
|
||||
},
|
||||
{
|
||||
$type: 'entity_select',
|
||||
name: 'group',
|
||||
other_entity: 'group',
|
||||
other_field: 'cn'
|
||||
},
|
||||
{
|
||||
$type: 'entity_select',
|
||||
name: 'memberof',
|
||||
other_entity: 'group',
|
||||
other_field: 'cn'
|
||||
},
|
||||
{
|
||||
$type: 'attributes',
|
||||
name: 'attrs',
|
||||
object_type: 'user'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
standard_association_facets: false,
|
||||
adder_dialog: {
|
||||
fields: [
|
||||
'aciname',
|
||||
{
|
||||
$type: 'checkboxes',
|
||||
name: 'permissions',
|
||||
options: IPA.create_options(['read', 'write'])
|
||||
},
|
||||
{
|
||||
$type: 'entity_select',
|
||||
name: 'group',
|
||||
other_entity: 'group',
|
||||
other_field: 'cn'
|
||||
},
|
||||
{
|
||||
$type: 'entity_select',
|
||||
name: 'memberof',
|
||||
other_entity: 'group',
|
||||
other_field: 'cn'
|
||||
},
|
||||
{
|
||||
$type: 'attributes',
|
||||
name: 'attrs',
|
||||
object_type: 'user'
|
||||
}
|
||||
]
|
||||
}
|
||||
};};
|
||||
|
||||
aci.attributes_widget = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
spec.layout = spec.layout || 'columns attribute_widget';
|
||||
spec.add_dialog_title = spec.add_dialog_title ||
|
||||
"@i18n:objects.permission.add_custom_attr";
|
||||
spec.add_field_label = spec.add_field_label ||
|
||||
'@i18n:objects.permission.attribute';
|
||||
|
||||
spec.set_value_to_lowercase = spec.set_value_to_lowercase === undefined ?
|
||||
true : spec.set_value_to_lowercase;
|
||||
|
||||
var that = IPA.custom_checkboxes_widget(spec);
|
||||
|
||||
that.object_type = spec.object_type;
|
||||
|
||||
that.populate = function() {
|
||||
|
||||
if (!that.object_type || that.object_type === '') return;
|
||||
|
||||
var metadata = metadata_provider.get('@mo:'+that.object_type);
|
||||
if (!metadata) return;
|
||||
|
||||
var aciattrs = metadata.aciattrs;
|
||||
|
||||
that.options = that.prepare_options(aciattrs);
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class aci.rights_widget
|
||||
* @extends IPA.checkboxes_widget
|
||||
*/
|
||||
aci.rights_widget = function(spec) {
|
||||
|
||||
var that = IPA.checkboxes_widget(spec);
|
||||
|
||||
that.rights = ['read', 'search', 'compare', 'write', 'add', 'delete', 'all'];
|
||||
for (var i=0; i<that.rights.length; i++) {
|
||||
var right = that.rights[i];
|
||||
that.add_option({label: right, value: right});
|
||||
}
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Default target to display in `permission_target_widget`
|
||||
* @property {string}
|
||||
*/
|
||||
aci.default_target = 'general';
|
||||
|
||||
/**
|
||||
* @class aci.permission_target_widget
|
||||
* @extends IPA.details_section
|
||||
*/
|
||||
aci.permission_target_widget = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var factory = spec.container_factory || IPA.details_section;
|
||||
|
||||
var that = factory(spec);
|
||||
|
||||
that.group_entity = IPA.get_entity(spec.group_entity || 'group');
|
||||
|
||||
that.target = aci.default_target;
|
||||
|
||||
var init = function() {
|
||||
|
||||
var objects = metadata_provider.get('@m:objects');
|
||||
var types = IPA.create_options(['']);
|
||||
for (var o in objects) {
|
||||
if (objects.hasOwnProperty(o)) {
|
||||
var obj = objects[o];
|
||||
if (obj.can_have_permissions) {
|
||||
types.push({
|
||||
label: obj.label_singular,
|
||||
value: o
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
that.type_select = IPA.select_widget({
|
||||
entity: that.entity,
|
||||
name: 'type',
|
||||
visible: false,
|
||||
options: types
|
||||
});
|
||||
that.widgets.add_widget(that.type_select);
|
||||
|
||||
that.ipapermlocation_text = IPA.text_widget({
|
||||
entity: that.entity,
|
||||
name: 'ipapermlocation',
|
||||
visible: false
|
||||
});
|
||||
that.widgets.add_widget(that.ipapermlocation_text);
|
||||
|
||||
that.extratargetfilter_text = IPA.multivalued_widget({
|
||||
entity: that.entity,
|
||||
name: 'extratargetfilter',
|
||||
visible: false
|
||||
});
|
||||
that.widgets.add_widget(that.extratargetfilter_text);
|
||||
|
||||
that.ipapermtarget_text = IPA.text_widget({
|
||||
entity: that.entity,
|
||||
name: 'ipapermtarget',
|
||||
visible: false
|
||||
});
|
||||
that.widgets.add_widget(that.ipapermtarget_text);
|
||||
|
||||
that.memberof_select = IPA.multivalued_widget({
|
||||
name: 'memberof',
|
||||
entity: that.entity,
|
||||
hidden: true,
|
||||
child_spec: {
|
||||
$type: 'entity_select',
|
||||
other_entity: that.group_entity,
|
||||
other_field: 'cn'
|
||||
}
|
||||
});
|
||||
that.widgets.add_widget(that.memberof_select);
|
||||
|
||||
|
||||
that.attribute_table = aci.attributes_widget({
|
||||
entity: that.entity,
|
||||
name: 'attrs',
|
||||
object_type: types[0].name,
|
||||
visible: false
|
||||
});
|
||||
that.widgets.add_widget(that.attribute_table);
|
||||
|
||||
that.attribute_multivalued = IPA.multivalued_widget({
|
||||
entity: that.entity,
|
||||
name: 'attrs_multi',
|
||||
visible: false
|
||||
});
|
||||
that.widgets.add_widget(that.attribute_multivalued);
|
||||
};
|
||||
|
||||
init();
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* Permission target policy
|
||||
* @class aci.permission_target_policy
|
||||
* @extends IPA.facet_policy
|
||||
*/
|
||||
aci.permission_target_policy = function (spec) {
|
||||
|
||||
var that = IPA.facet_policy();
|
||||
that.widget_name = spec.widget_name;
|
||||
that.managed = false;
|
||||
|
||||
that.init = function() {
|
||||
|
||||
that.permission_target = that.container.widgets.get_widget(that.widget_name);
|
||||
var type_f = that.container.fields.get_field('type');
|
||||
|
||||
on(type_f, 'value-change', that.apply_type);
|
||||
};
|
||||
|
||||
that.apply_type = function () {
|
||||
|
||||
var widgets = that.permission_target.widgets;
|
||||
var type_select = widgets.get_widget('type');
|
||||
var type = type_select.save()[0];
|
||||
var new_target = type === '' ? 'general' : 'type';
|
||||
if (that.permission_target.target !== new_target) {
|
||||
|
||||
var attr_table = widgets.get_widget('attrs');
|
||||
var attr_multi = widgets.get_widget('attrs_multi');
|
||||
var loc_w = widgets.get_widget('ipapermlocation');
|
||||
var loc_f = that.container.fields.get_field('ipapermlocation');
|
||||
var attrs;
|
||||
that.select_target(new_target);
|
||||
|
||||
if (new_target === 'general') {
|
||||
attrs = attr_table.save();
|
||||
attr_multi.update(attrs);
|
||||
attr_multi.value_changed.notify([], attr_multi);
|
||||
|
||||
// permission plugin resets ipapermlocation to basedn when
|
||||
// type is unset. -> use it as pristine value so undo will
|
||||
// work correctly.
|
||||
loc_f.set_value([IPA.env.basedn], true);
|
||||
} else {
|
||||
attrs = attr_multi.save();
|
||||
attr_table.update(attrs);
|
||||
// notification will be done by `set_attrs_type`
|
||||
}
|
||||
}
|
||||
|
||||
that.set_attrs_type(type, true);
|
||||
};
|
||||
|
||||
that.set_attrs_type = function(type, skip_unmatched) {
|
||||
var attribute_field = that.container.fields.get_field('attrs');
|
||||
var attribute_table = that.permission_target.widgets.get_widget('attrs');
|
||||
var skip_unmatched_org = attribute_table.skip_unmatched;
|
||||
attribute_table.object_type = type;
|
||||
|
||||
// UI doesn't always know what are the possible attributes.
|
||||
// In case of managed permissions, one of the possible lists is in ipapermdefaultattr.
|
||||
var default_attrs = that.container.fields.get_field('ipapermdefaultattr');
|
||||
if (default_attrs && default_attrs.enabled) { // if managed permission
|
||||
attribute_table.custom_options = default_attrs.get_value();
|
||||
} else {
|
||||
attribute_table.custom_options = [];
|
||||
}
|
||||
|
||||
// skip values which don't belong to new type. Bug #2617
|
||||
attribute_table.skip_unmatched = skip_unmatched || skip_unmatched_org;
|
||||
attribute_field.reset();
|
||||
// force value_change to update dirty status if some unmatched values were skipped
|
||||
attribute_table.value_changed.notify([], attribute_table);
|
||||
attribute_table.skip_unmatched = skip_unmatched_org;
|
||||
};
|
||||
|
||||
that.update_attrs = function() {
|
||||
|
||||
var type_select = that.permission_target.widgets.get_widget('type');
|
||||
var type = type_select.save()[0];
|
||||
that.set_attrs_type(type, false);
|
||||
};
|
||||
|
||||
that.post_create = function() {
|
||||
that.select_target(aci.default_target);
|
||||
};
|
||||
|
||||
that.post_load = function(data) {
|
||||
|
||||
var displayed_target = 'general';
|
||||
var permtype = data.result.result.ipapermissiontype;
|
||||
that.managed = permtype && permtype.indexOf("MANAGED") > -1;
|
||||
that.system = permtype && permtype.indexOf("SYSTEM") > -1 && permtype.length === 1;
|
||||
|
||||
for (var target in that.target_mapping) {
|
||||
var property = that.target_mapping[target].property;
|
||||
if (property && data.result.result[property]) {
|
||||
displayed_target = target;
|
||||
} else {
|
||||
that.set_target_visible(target, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (displayed_target) {
|
||||
that.permission_target.target = displayed_target;
|
||||
that.set_target_visible(displayed_target, true);
|
||||
}
|
||||
};
|
||||
|
||||
that.select_target = function(target) {
|
||||
that.set_target_visible(that.permission_target.target, false);
|
||||
that.permission_target.target = target;
|
||||
that.set_target_visible(that.permission_target.target, true);
|
||||
};
|
||||
|
||||
that.set_target_visible = function(target, visible) {
|
||||
|
||||
var target_info = that.target_mapping[target];
|
||||
|
||||
for (var i=0,l=target_info.fields.length; i<l; i++) {
|
||||
var info = target_info.fields[i];
|
||||
that.set_target_row_visible(info, visible);
|
||||
}
|
||||
|
||||
if (visible && target_info.action) target_info.action();
|
||||
};
|
||||
|
||||
that.set_target_row_visible = function(target_info, visible) {
|
||||
var widget = that.permission_target.widgets.get_widget(target_info.name);
|
||||
var field = that.container.fields.get_field(target_info.name);
|
||||
that.permission_target.set_row_visible(target_info.name, visible);
|
||||
field.set_enabled(visible);
|
||||
field.set_required(visible && target_info.required);
|
||||
widget.set_visible(visible);
|
||||
};
|
||||
|
||||
that.target_mapping = {
|
||||
general: {
|
||||
fields: [
|
||||
{
|
||||
name: 'extratargetfilter'
|
||||
},
|
||||
{
|
||||
name: 'ipapermlocation',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: 'ipapermtarget'
|
||||
},
|
||||
{
|
||||
name: 'type'
|
||||
},
|
||||
{
|
||||
name: 'memberof'
|
||||
},
|
||||
{
|
||||
name: 'attrs_multi'
|
||||
}
|
||||
]
|
||||
},
|
||||
type: {
|
||||
property: 'type',
|
||||
fields: [
|
||||
{
|
||||
name: 'extratargetfilter'
|
||||
},
|
||||
{
|
||||
name: 'memberof'
|
||||
},
|
||||
{
|
||||
name: 'type'
|
||||
},
|
||||
{
|
||||
name: 'attrs'
|
||||
},
|
||||
{
|
||||
name: 'ipapermtarget'
|
||||
}
|
||||
],
|
||||
action: function() {
|
||||
that.update_attrs();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* Facet policy which shows and hides managed section based on presence
|
||||
* "MANAGED" in ippapermissiontype attribute
|
||||
* @class aci.permission_managed_policy
|
||||
* @extends IPA.facet_policy
|
||||
*/
|
||||
aci.permission_managed_policy = function (spec) {
|
||||
|
||||
var that = IPA.facet_policy();
|
||||
|
||||
that.post_load = function(data) {
|
||||
|
||||
var result = data.result.result;
|
||||
var permtype = result.ipapermissiontype;
|
||||
var managed = permtype && permtype.indexOf("MANAGED") > -1;
|
||||
var system = permtype && permtype.indexOf("SYSTEM") > -1 && permtype.length === 1;
|
||||
var m_section = that.container.widgets.get_widget("managed");
|
||||
m_section.set_visible(managed);
|
||||
|
||||
var fields = that.container.fields.get_fields();
|
||||
for (var i=0, l=fields.length; i<l; i++) {
|
||||
var field = fields[i];
|
||||
if (field.read_only) continue;
|
||||
var managed_f = aci.managed_fields.indexOf(field.name) > -1;
|
||||
field.set_writable(!system && !(managed_f && managed) && field.writable);
|
||||
}
|
||||
|
||||
// Bind rule type cannot be changed if permission is in a privilege
|
||||
var privileges = result.member_privilege;
|
||||
if (privileges && privileges.length > 0) {
|
||||
var f = that.container.fields.get_field('ipapermbindruletype');
|
||||
f.set_writable(false);
|
||||
}
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* Permission entity spec
|
||||
* @member aci
|
||||
*/
|
||||
aci.permission_entity_spec = make_permission_spec();
|
||||
|
||||
/**
|
||||
* Privilege entity spec
|
||||
* @member aci
|
||||
*/
|
||||
aci.privilege_entity_spec = make_privilege_spec();
|
||||
|
||||
/**
|
||||
* Role entity spec
|
||||
* @member aci
|
||||
*/
|
||||
aci.role_entity_spec = make_role_spec();
|
||||
|
||||
/**
|
||||
* Self-service entity spec
|
||||
* @member aci
|
||||
*/
|
||||
aci.selfservice_entity_spec = make_selfservice_spec();
|
||||
|
||||
/**
|
||||
* Delegation entity spec
|
||||
* @member aci
|
||||
*/
|
||||
aci.delegation_entity_spec = make_delegation_spec();
|
||||
|
||||
/**
|
||||
* Register entities, widgets and fields to global registers.
|
||||
* @member aci
|
||||
*/
|
||||
aci.register = function() {
|
||||
var e = reg.entity;
|
||||
var w = reg.widget;
|
||||
var f = reg.field;
|
||||
|
||||
e.register({ type: 'permission', spec: aci.permission_entity_spec });
|
||||
e.register({ type: 'privilege', spec: aci.privilege_entity_spec });
|
||||
e.register({ type: 'role', spec: aci.role_entity_spec });
|
||||
e.register({ type: 'selfservice', spec: aci.selfservice_entity_spec });
|
||||
e.register({ type: 'delegation', spec: aci.delegation_entity_spec });
|
||||
|
||||
w.register('attributes', aci.attributes_widget);
|
||||
f.register('attributes', IPA.field);
|
||||
w.register('rights', aci.rights_widget);
|
||||
f.register('rights', IPA.field);
|
||||
w.register('permission_target', aci.permission_target_widget);
|
||||
};
|
||||
|
||||
phases.on('registration', aci.register);
|
||||
|
||||
return aci;
|
||||
});
|
||||
270
install/ui/src/freeipa/add.js
Normal file
270
install/ui/src/freeipa/add.js
Normal file
@@ -0,0 +1,270 @@
|
||||
/* Authors:
|
||||
* Pavel Zuna <pzuna@redhat.com>
|
||||
* Endi Sukma Dewata <edewata@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define(['./ipa', './jquery', './navigation', './rpc', './text', './field', './widget', './dialog'],
|
||||
function(IPA, $, navigation, rpc, text, field_mod, widget_mod) {
|
||||
|
||||
/**
|
||||
* Entity adder dialog
|
||||
* @class
|
||||
* @extends IPA.dialog
|
||||
* @mixins IPA.confirm_mixin
|
||||
*/
|
||||
IPA.entity_adder_dialog = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
spec.name = spec.name || 'entity_adder_dialog';
|
||||
|
||||
var that = IPA.dialog(spec);
|
||||
|
||||
that.on_cancel = that.close;
|
||||
|
||||
IPA.confirm_mixin().apply(that);
|
||||
|
||||
/** @property {string} method="add" API method for add command */
|
||||
that.method = spec.method || 'add';
|
||||
/** @property {Function} on_error Custom add error handler */
|
||||
that.on_error = spec.on_error ;
|
||||
/** @property {boolean} retry=true Allow retry on error (same as in rpc.command)*/
|
||||
that.retry = typeof spec.retry !== 'undefined' ? spec.retry : true;
|
||||
/**
|
||||
* Add command
|
||||
* @property {rpc.command}
|
||||
* @protected
|
||||
*/
|
||||
that.command = null;
|
||||
/** @property {IPA.observer} added Added event */
|
||||
that.added = IPA.observer();
|
||||
/** @property {string} subject Name of added subject (usually entity label) */
|
||||
that.subject = spec.subject || that.entity.metadata.label_singular;
|
||||
/**
|
||||
* Pkeys of containing entities to use in add command when adding nested entity
|
||||
* @property {string[]}
|
||||
*/
|
||||
that.pkey_prefix = spec.pkey_prefix || [];
|
||||
|
||||
/**
|
||||
* Custom logic for navigation to edit page in case of 'Add and Edit'
|
||||
* @property {Function}
|
||||
* @param {entity.entity} entity
|
||||
* @param {Object} result
|
||||
*/
|
||||
that.show_edit_page = spec.show_edit_page || show_edit_page;
|
||||
|
||||
var init = function() {
|
||||
that.create_button({
|
||||
name: 'add',
|
||||
label: '@i18n:buttons.add',
|
||||
click: function() {
|
||||
that.on_add();
|
||||
}
|
||||
});
|
||||
|
||||
that.create_button({
|
||||
name: 'add_and_add_another',
|
||||
label: '@i18n:buttons.add_and_add_another',
|
||||
click: function() {
|
||||
that.hide_message();
|
||||
that.add(
|
||||
function(data, text_status, xhr) {
|
||||
that.added.notify([data, 'add_and_add_another'], that);
|
||||
that.show_message(that.get_success_message(data), 'success');
|
||||
that.reset();
|
||||
that.focus_first_element();
|
||||
},
|
||||
that.on_error);
|
||||
}
|
||||
});
|
||||
|
||||
that.create_button({
|
||||
name: 'add_and_edit',
|
||||
label: '@i18n:buttons.add_and_edit',
|
||||
click: function() {
|
||||
that.hide_message();
|
||||
that.add(
|
||||
function(data, text_status, xhr) {
|
||||
that.added.notify([data, 'add_and_edit'], that);
|
||||
that.close();
|
||||
var result = data.result.result;
|
||||
that.show_edit_page(that.entity, result);
|
||||
that.notify_success(data);
|
||||
},
|
||||
that.on_error);
|
||||
}
|
||||
});
|
||||
|
||||
that.create_button({
|
||||
name: 'cancel',
|
||||
label: '@i18n:buttons.cancel',
|
||||
click: function() {
|
||||
that.hide_message();
|
||||
that.close();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Invokes simple add
|
||||
* @protected
|
||||
*/
|
||||
that.on_add = function() {
|
||||
|
||||
that.hide_message();
|
||||
that.add(
|
||||
function(data, text_status, xhr) {
|
||||
that.added.notify([data, 'add'], that);
|
||||
that.close();
|
||||
that.notify_success(data);
|
||||
},
|
||||
that.on_error);
|
||||
};
|
||||
|
||||
/**
|
||||
* Confirm handler
|
||||
* @protected
|
||||
*/
|
||||
that.on_confirm = function() {
|
||||
that.on_add();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get success notification message text
|
||||
* @protected
|
||||
* @param {Object} data Add command result
|
||||
*/
|
||||
that.get_success_message = function(data) {
|
||||
var message = text.get('@i18n:dialogs.add_confirmation');
|
||||
return message.replace('${entity}', that.subject);
|
||||
};
|
||||
|
||||
/**
|
||||
* Show success notification
|
||||
* @protected
|
||||
* @param {Object} data Add command result
|
||||
*/
|
||||
that.notify_success = function(data) {
|
||||
IPA.notify_success(that.get_success_message(data));
|
||||
};
|
||||
|
||||
function show_edit_page(entity,result) {
|
||||
var pkey_name = entity.metadata.primary_key;
|
||||
var pkey = result[pkey_name];
|
||||
if (!(pkey instanceof Array)) {
|
||||
pkey = [pkey];
|
||||
}
|
||||
rpc.extract_objects(pkey);
|
||||
|
||||
var pkeys = that.pkey_prefix.slice(0);
|
||||
pkeys.push(pkey[0]);
|
||||
navigation.show_entity(that.entity.name, 'default', pkeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create add command
|
||||
* @protected
|
||||
* @param {Object} record Saved data
|
||||
*/
|
||||
that.create_add_command = function(record) {
|
||||
|
||||
var pkey_name = that.entity.metadata.primary_key;
|
||||
|
||||
var command = rpc.command({
|
||||
entity: that.entity.name,
|
||||
method: that.method,
|
||||
retry: that.retry
|
||||
});
|
||||
|
||||
command.add_args(that.pkey_prefix.slice(0));
|
||||
|
||||
var fields = that.fields.get_fields();
|
||||
for (var j=0; j<fields.length; j++) {
|
||||
var field = fields[j];
|
||||
|
||||
var values = record[field.param];
|
||||
if (!values || values.length === 0 || !field.enabled) continue;
|
||||
if (field.flags.indexOf('no_command') > -1) continue;
|
||||
|
||||
if (field.param === pkey_name) {
|
||||
command.add_arg(values[0]);
|
||||
} else if (values.length === 1) {
|
||||
command.set_option(field.param, values[0]);
|
||||
} else {
|
||||
command.set_option(field.param, values);
|
||||
}
|
||||
}
|
||||
|
||||
return command;
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute add command
|
||||
* @param {Function} on_success
|
||||
* @param {Function} on_error
|
||||
*/
|
||||
that.add = function(on_success, on_error) {
|
||||
|
||||
if (!that.validate()) {
|
||||
widget_mod.focus_invalid(that);
|
||||
return;
|
||||
}
|
||||
|
||||
var record = {};
|
||||
that.save(record);
|
||||
|
||||
that.command = that.create_add_command(record);
|
||||
that.command.on_success = on_success;
|
||||
that.command.on_error = on_error;
|
||||
|
||||
that.command.execute();
|
||||
};
|
||||
|
||||
/** @inheritDoc */
|
||||
that.create_content = function() {
|
||||
that.dialog_create_content();
|
||||
|
||||
var div = $('<div/>', {
|
||||
}).appendTo(that.container);
|
||||
|
||||
$('<span/>', {
|
||||
'class': 'required-indicator',
|
||||
text: IPA.required_indicator
|
||||
}).appendTo(div);
|
||||
|
||||
div.append(' ');
|
||||
|
||||
$('<span/>', {
|
||||
text: text.get('@i18n:widget.validation.required')
|
||||
}).appendTo(div);
|
||||
};
|
||||
|
||||
// methods that should be invoked by subclasses
|
||||
that.entity_adder_dialog_create_content = that.create_content;
|
||||
that.entity_adder_dialog_create_add_command = that.create_add_command;
|
||||
that.entity_adder_dialog_get_success_message = that.get_success_message;
|
||||
|
||||
init();
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
return IPA.entity_adder_dialog;
|
||||
});
|
||||
63
install/ui/src/freeipa/app.js
Normal file
63
install/ui/src/freeipa/app.js
Normal file
@@ -0,0 +1,63 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
// core
|
||||
'./app_container',
|
||||
'./plugins/sync_otp',
|
||||
'./plugins/login',
|
||||
'./plugins/login_process',
|
||||
'./plugins/api_browser',
|
||||
// entities
|
||||
'./aci',
|
||||
'./automember',
|
||||
'./automount',
|
||||
'./plugins/ca',
|
||||
'./plugins/caacl',
|
||||
'./plugins/certprofile',
|
||||
'./plugins/certmap',
|
||||
'./plugins/certmapmatch',
|
||||
'./dns',
|
||||
'./group',
|
||||
'./hbac',
|
||||
'./hbactest',
|
||||
'./hostgroup',
|
||||
'./host',
|
||||
'./idrange',
|
||||
'./idviews',
|
||||
'./netgroup',
|
||||
'./otptoken',
|
||||
'./policy',
|
||||
'./radiusproxy',
|
||||
'./realmdomains',
|
||||
'./rule',
|
||||
'./selinux',
|
||||
'./serverconfig',
|
||||
'./service',
|
||||
'./stageuser',
|
||||
'./sudo',
|
||||
'./trust',
|
||||
'./topology',
|
||||
'./user',
|
||||
'./vault',
|
||||
'dojo/domReady!'
|
||||
],function(app_container) {
|
||||
return app_container;
|
||||
});
|
||||
163
install/ui/src/freeipa/app_container.js
Normal file
163
install/ui/src/freeipa/app_container.js
Normal file
@@ -0,0 +1,163 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'dojo/_base/lang',
|
||||
'dojo/Deferred',
|
||||
'dojo/on',
|
||||
'dojo/when',
|
||||
'./plugin_loader',
|
||||
'./phases',
|
||||
'./reg',
|
||||
'./Application_controller',
|
||||
'exports'
|
||||
],function(lang, Deferred, on, when, plugin_loader, phases, reg, Application_controller, app) {
|
||||
|
||||
/**
|
||||
* Application wrapper
|
||||
*
|
||||
* Prepares application controller and registers phases.
|
||||
*
|
||||
* @class app
|
||||
* @singleton
|
||||
*/
|
||||
lang.mixin(app, {
|
||||
|
||||
/**
|
||||
* Application instance
|
||||
*/
|
||||
app: null,
|
||||
|
||||
/**
|
||||
* Application class
|
||||
*/
|
||||
App_class: Application_controller,
|
||||
|
||||
/**
|
||||
* Phases registration
|
||||
*/
|
||||
register_phases: function() {
|
||||
|
||||
phases.on('init', function() {
|
||||
var app = this.app = new this.App_class();
|
||||
app.init();
|
||||
return app;
|
||||
}.bind(this));
|
||||
|
||||
phases.on('init', function() {
|
||||
var deferred = new Deferred();
|
||||
|
||||
function reject(item) {
|
||||
var msg = "Web UI requires " + item + " enabled. " +
|
||||
"Possible cause: too strict browser " +
|
||||
"configuration.";
|
||||
deferred.reject({ message: msg });
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testStorage(storage) {
|
||||
try {
|
||||
if (!window[storage]) return false;
|
||||
} catch(e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!window.navigator.cookieEnabled) return reject('cookies');
|
||||
if (!testStorage('sessionStorage')) return reject('sessionStorage');
|
||||
if (!testStorage('localStorage')) return reject('localStorage');
|
||||
|
||||
if (window.sessionStorage.getItem('logout')) {
|
||||
window.sessionStorage.removeItem('logout');
|
||||
var login_facet = reg.facet.get('login');
|
||||
this.app.show_facet(login_facet);
|
||||
on.once(login_facet, "logged_in", function() {
|
||||
deferred.resolve();
|
||||
});
|
||||
} else {
|
||||
deferred.resolve();
|
||||
}
|
||||
return deferred.promise;
|
||||
}.bind(this));
|
||||
|
||||
phases.on('metadata', function() {
|
||||
var deferred = new Deferred();
|
||||
|
||||
this.app.get_configuration(function(success) {
|
||||
deferred.resolve(success);
|
||||
}, function(error) {
|
||||
deferred.reject(error);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}.bind(this));
|
||||
|
||||
phases.on('profile', function() {
|
||||
this.app.choose_profile();
|
||||
}.bind(this));
|
||||
|
||||
phases.on('runtime', function() {
|
||||
return this.app.start_runtime();
|
||||
}.bind(this));
|
||||
|
||||
phases.on('shutdown', function() {
|
||||
return this.app.start_logout();
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
simple_mode_phases: function() {
|
||||
|
||||
phases.on('init', function() {
|
||||
var app = this.app = new this.App_class();
|
||||
app.init();
|
||||
return app;
|
||||
}.bind(this));
|
||||
|
||||
phases.on('runtime', function() {
|
||||
var d = new Deferred();
|
||||
var facet = reg.facet.get(this.target_facet);
|
||||
if (!facet) {
|
||||
window.console.error('Target facet not found: '+this.target_facet);
|
||||
} else {
|
||||
this.app.show_facet(facet);
|
||||
}
|
||||
return d.promise;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
run: function() {
|
||||
when(plugin_loader.load_plugins(), function() {
|
||||
this.register_phases();
|
||||
phases.controller.run();
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
run_simple: function(facet) {
|
||||
this.target_facet = facet;
|
||||
when(plugin_loader.load_plugins(), function() {
|
||||
this.simple_mode_phases();
|
||||
phases.controller.run();
|
||||
}.bind(this));
|
||||
}
|
||||
});
|
||||
|
||||
return app;
|
||||
});
|
||||
1716
install/ui/src/freeipa/association.js
Normal file
1716
install/ui/src/freeipa/association.js
Normal file
File diff suppressed because it is too large
Load Diff
252
install/ui/src/freeipa/auth.js
Normal file
252
install/ui/src/freeipa/auth.js
Normal file
@@ -0,0 +1,252 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2014 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'dojo/_base/declare',
|
||||
'dojo/_base/lang',
|
||||
'dojo/Deferred',
|
||||
'dojo/Evented',
|
||||
'dojo/Stateful',
|
||||
'dojo/topic',
|
||||
'dojo/when'
|
||||
],
|
||||
function(declare, lang, Deferred, Evented, Stateful, topic, when) {
|
||||
|
||||
/**
|
||||
* Authentication module
|
||||
* @class auth
|
||||
* @singleton
|
||||
*/
|
||||
var auth = {
|
||||
/**
|
||||
* Current authentication state
|
||||
* @property {auth.Auth}
|
||||
*/
|
||||
current: null
|
||||
};
|
||||
|
||||
/**
|
||||
* Authentication interface and state.
|
||||
*
|
||||
* Can be used for checking whether user is authenticated, by what method or
|
||||
* what methods can be used for authentication. Actual authentication is
|
||||
* done by separate object - authentication provider.
|
||||
*
|
||||
* Communication with authentication providers is done through global messages
|
||||
* (`dojo/topic`).
|
||||
*
|
||||
* Some component can initiate the authentication process by calling:
|
||||
*
|
||||
* var auth_promise = auth.current.authenticate();
|
||||
*
|
||||
* `auth_promise` is a promise which is resolve on auth success and rejected
|
||||
* on auth failure.
|
||||
*
|
||||
* Logout works in similar fashion:
|
||||
*
|
||||
* var logout_promise = auth.current.logout();
|
||||
*
|
||||
* The communication with authentication providers works as follows:
|
||||
*
|
||||
* 1. `auth.current.authenticate();` publishes `authenticate` topic
|
||||
* 2. provider starts the authentication process
|
||||
* 3. if it finishes with a success provider publishes `auth-successful`, if not
|
||||
* it publishes `auth-failed`
|
||||
* 4. the promise is resolved or rejected
|
||||
*
|
||||
* Logout works in similar fashion, only the topic names are `log-out`,
|
||||
* `logout-successful` and `logout-failed`.
|
||||
*
|
||||
* New `authenticate` or `log-out` topics are not published if there is
|
||||
* already authentication or logout in progress. The promises from subsequent
|
||||
* `authenticate()` or `logout()` calls are resolved as expected.
|
||||
*
|
||||
* `login`, `principal`, `whoami`, `fullname` properties are supposed to be
|
||||
* set by authentication providers.
|
||||
*
|
||||
* @class
|
||||
*/
|
||||
auth.Auth = declare([Stateful, Evented], {
|
||||
/**
|
||||
* Raw User information
|
||||
*
|
||||
* @property {Object}
|
||||
*/
|
||||
whoami: {},
|
||||
|
||||
/**
|
||||
* User is authenticated
|
||||
*
|
||||
* Use `set_authenticated(state, method)` for setting it.
|
||||
*
|
||||
* @property {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
authenticated: false,
|
||||
|
||||
/**
|
||||
* Method used for authentication
|
||||
* @property {string}
|
||||
*/
|
||||
authenticated_by: "",
|
||||
|
||||
/**
|
||||
* Enabled auth methods
|
||||
* @property {string[]}
|
||||
*/
|
||||
auth_methods: ['kerberos', 'password', 'certificate'],
|
||||
|
||||
/**
|
||||
* Authenticated user's Kerberos principal
|
||||
* @property {string}
|
||||
*/
|
||||
principal: "",
|
||||
|
||||
/**
|
||||
* Authenticated user's login
|
||||
* @property {string}
|
||||
*/
|
||||
login: "",
|
||||
|
||||
/**
|
||||
* Authenticated user's fullname
|
||||
* @property {string}
|
||||
*/
|
||||
fullname: "",
|
||||
|
||||
/**
|
||||
* Authentication is in progress
|
||||
* @property {boolean}
|
||||
*/
|
||||
authenticating: false,
|
||||
|
||||
/**
|
||||
* Logging out is in progress
|
||||
* @property {boolean}
|
||||
*/
|
||||
logging_out: false,
|
||||
|
||||
/**
|
||||
* Indicates whether user was previously authenticated
|
||||
* @property {boolean}
|
||||
*/
|
||||
expired: false,
|
||||
|
||||
/**
|
||||
* Update authenticated state
|
||||
* @param {boolean} state User is authenticated
|
||||
* @param {string} method used for authentication
|
||||
*/
|
||||
set_authenticated: function(state, method) {
|
||||
|
||||
if (this.authenticated && !state) {
|
||||
this.set('expired', true);
|
||||
}
|
||||
|
||||
this.set('authenticated', state);
|
||||
this.set('authenticated_by', method);
|
||||
|
||||
if (this.authenticated) {
|
||||
this.set('expired', false);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Initiate authentication process (if not already initiated)
|
||||
*
|
||||
* Returns promise which is fulfilled when user is authenticated. It's
|
||||
* rejected when authentication is canceled.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
authenticate: function() {
|
||||
var authenticated = new Deferred();
|
||||
var ok_handler = topic.subscribe('auth-successful', function(info) {
|
||||
authenticated.resolve(true);
|
||||
ok_handler.remove();
|
||||
fail_handler.remove();
|
||||
});
|
||||
var fail_handler = topic.subscribe('auth-failed', function(info) {
|
||||
authenticated.reject();
|
||||
ok_handler.remove();
|
||||
fail_handler.remove();
|
||||
});
|
||||
if (!this.authenticating) {
|
||||
topic.publish('authenticate', this);
|
||||
}
|
||||
return authenticated.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Initiate logout process (if not already initiated)
|
||||
*
|
||||
* Returns promise which is fulfilled when user is logged-out. It's
|
||||
* rejected when logout failed.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
logout: function() {
|
||||
var loggedout = new Deferred();
|
||||
var ok_handler = topic.subscribe('logout-successful', function(info) {
|
||||
loggedout.resolve(true);
|
||||
ok_handler.remove();
|
||||
fail_handler.remove();
|
||||
});
|
||||
var fail_handler = topic.subscribe('logout-failed', function(info) {
|
||||
loggedout.reject();
|
||||
ok_handler.remove();
|
||||
fail_handler.remove();
|
||||
});
|
||||
if (!this.logging_out) {
|
||||
topic.publish('log-out', this);
|
||||
}
|
||||
return loggedout.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Initializes instance
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
postscript: function() {
|
||||
var self = this;
|
||||
var auth_true = function() {
|
||||
self.set('authenticating', true);
|
||||
};
|
||||
var auth_false = function() {
|
||||
self.set('authenticating', false);
|
||||
};
|
||||
var out_true = function() {
|
||||
self.set('logging_out', true);
|
||||
};
|
||||
var out_false = function() {
|
||||
self.set('logging_out', false);
|
||||
};
|
||||
|
||||
topic.subscribe('auth-successful', auth_false);
|
||||
topic.subscribe('auth-failed', auth_false);
|
||||
topic.subscribe('authenticate', auth_true);
|
||||
topic.subscribe('logout-successful', out_true);
|
||||
topic.subscribe('logout-failed', out_true);
|
||||
topic.subscribe('log-out', out_false);
|
||||
}
|
||||
});
|
||||
|
||||
auth.current = new auth.Auth();
|
||||
return auth;
|
||||
});
|
||||
781
install/ui/src/freeipa/automember.js
Normal file
781
install/ui/src/freeipa/automember.js
Normal file
@@ -0,0 +1,781 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'dojo/_base/declare',
|
||||
'./field',
|
||||
'./metadata',
|
||||
'./ipa',
|
||||
'./jquery',
|
||||
'./navigation',
|
||||
'./phases',
|
||||
'./reg',
|
||||
'./rpc',
|
||||
'./text',
|
||||
'./details',
|
||||
'./search',
|
||||
'./association',
|
||||
'./entity'],
|
||||
function(declare, field_mod, metadata_provider, IPA, $, navigation,
|
||||
phases, reg, rpc, text) {
|
||||
|
||||
var exp = IPA.automember = {};
|
||||
|
||||
var make_spec = function() {
|
||||
return {
|
||||
|
||||
name: 'automember',
|
||||
|
||||
policies:[
|
||||
{
|
||||
$factory: IPA.facet_update_policy,
|
||||
source_facet: 'usergrouprule',
|
||||
dest_facet: 'searchgroup'
|
||||
},
|
||||
{
|
||||
$factory: IPA.facet_update_policy,
|
||||
source_facet: 'hostgrouprule',
|
||||
dest_facet: 'searchhostgroup'
|
||||
}
|
||||
],
|
||||
facets: [
|
||||
{
|
||||
$factory: IPA.automember.rule_search_facet,
|
||||
$type: 'search',
|
||||
name: 'searchgroup',
|
||||
group_type: 'group',
|
||||
label: '@i18n:objects.automember.usergrouprules',
|
||||
details_facet: 'usergrouprule',
|
||||
pagination: false,
|
||||
columns: [
|
||||
'cn',
|
||||
'description'
|
||||
]
|
||||
},
|
||||
{
|
||||
$factory: IPA.automember.rule_search_facet,
|
||||
$type: 'search',
|
||||
name: 'searchhostgroup',
|
||||
group_type: 'hostgroup',
|
||||
label: '@i18n:objects.automember.hostgrouprules',
|
||||
details_facet: 'hostgrouprule',
|
||||
pagination: false,
|
||||
columns: [
|
||||
'cn',
|
||||
'description'
|
||||
]
|
||||
},
|
||||
{
|
||||
$factory: IPA.automember.rule_details_facet,
|
||||
$type: 'details',
|
||||
name: 'usergrouprule',
|
||||
group_type: 'group',
|
||||
label: '@i18n:objects.automember.usergrouprule',
|
||||
disable_facet_tabs: true,
|
||||
check_rights: false,
|
||||
redirect_info: { facet: 'searchgroup' }
|
||||
},
|
||||
{
|
||||
$factory: IPA.automember.rule_details_facet,
|
||||
$type: 'details',
|
||||
name: 'hostgrouprule',
|
||||
group_type: 'hostgroup',
|
||||
label: '@i18n:objects.automember.hostgrouprule',
|
||||
disable_facet_tabs: true,
|
||||
check_rights: false,
|
||||
redirect_info: { facet: 'searchhostgroup' }
|
||||
}
|
||||
],
|
||||
adder_dialog: {
|
||||
$factory: IPA.automember.rule_adder_dialog,
|
||||
title: '@i18n:objects.automember.add_rule',
|
||||
fields: [
|
||||
{
|
||||
$type: 'entity_select',
|
||||
name: 'cn',
|
||||
other_entity: 'group',
|
||||
other_field: 'cn'
|
||||
}
|
||||
],
|
||||
height: '300'
|
||||
},
|
||||
deleter_dialog: {
|
||||
$factory: IPA.automember.rule_deleter_dialog
|
||||
}
|
||||
};};
|
||||
|
||||
exp.metadata_extension_pre_op = function(spec, context) {
|
||||
//HACK: Automember takes_params is missing a cn attribute. This hack
|
||||
//copies cn from mod command. Also it is set as pkey.
|
||||
var metadata = metadata_provider.source;
|
||||
var pkey_attr = metadata.commands.automember_mod.takes_args[0];
|
||||
pkey_attr.primary_key = true;
|
||||
metadata.objects.automember.takes_params.push(pkey_attr);
|
||||
metadata.objects.automember.primary_key = pkey_attr.name;
|
||||
return spec;
|
||||
};
|
||||
|
||||
IPA.automember.rule_search_facet = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.search_facet(spec);
|
||||
|
||||
that.group_type = spec.group_type;
|
||||
|
||||
var init = function() {
|
||||
|
||||
that.default_group_widget = IPA.automember.default_group_widget({
|
||||
entity: that.entity,
|
||||
group_type: that.group_type
|
||||
});
|
||||
};
|
||||
|
||||
that.refresh = function() {
|
||||
|
||||
that.search_facet_refresh();
|
||||
that.default_group_widget.refresh();
|
||||
};
|
||||
|
||||
|
||||
that.get_records_command_name = function() {
|
||||
return that.managed_entity.name + that.group_type+'_get_records';
|
||||
};
|
||||
|
||||
that.get_search_command_name = function() {
|
||||
var name = that.managed_entity.name + that.group_type + '_find';
|
||||
if (that.pagination && !that.search_all_entries) {
|
||||
name += '_pkeys';
|
||||
}
|
||||
return name;
|
||||
};
|
||||
|
||||
that.create_get_records_command = function(records, pkeys, on_success, on_error) {
|
||||
|
||||
var batch = that.table_facet_create_get_records_command(records, pkeys,
|
||||
on_success, on_error);
|
||||
|
||||
for (var i=0; i<batch.commands.length; i++) {
|
||||
var command = batch.commands[i];
|
||||
command.set_option('type', that.group_type);
|
||||
}
|
||||
|
||||
return batch;
|
||||
};
|
||||
|
||||
that.create_refresh_command = function() {
|
||||
|
||||
var command = that.search_facet_create_refresh_command();
|
||||
|
||||
command.set_option('type', that.group_type);
|
||||
|
||||
return command;
|
||||
};
|
||||
|
||||
that.create_content = function(container) {
|
||||
|
||||
var header = $('<div/>', {
|
||||
'class': 'automember-header'
|
||||
}).appendTo(container);
|
||||
|
||||
var content = $('<div/>', {
|
||||
'class': 'automember-content'
|
||||
}).appendTo(container);
|
||||
|
||||
that.default_group_widget.create(header);
|
||||
that.table.create(content);
|
||||
};
|
||||
|
||||
that.show_add_dialog = function() {
|
||||
var dialog = that.managed_entity.get_dialog('add');
|
||||
if (!that.adder_dialog) {
|
||||
that.adder_dialog = dialog;
|
||||
dialog.added.attach(function() {
|
||||
that.refresh();
|
||||
});
|
||||
}
|
||||
dialog.pkey_prefix = that.managed_entity_pkey_prefix();
|
||||
dialog.group_type = that.group_type;
|
||||
dialog.open();
|
||||
};
|
||||
|
||||
that.create_remove_dialog = function() {
|
||||
var dialog = that.search_facet_create_remove_dialog();
|
||||
dialog.group_type = that.group_type;
|
||||
return dialog;
|
||||
};
|
||||
|
||||
init();
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.automember.rule_details_facet = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
spec.fields = [
|
||||
{
|
||||
name: 'cn',
|
||||
widget: 'general.cn'
|
||||
},
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description',
|
||||
widget: 'general.description'
|
||||
},
|
||||
{
|
||||
$type: 'automember_condition',
|
||||
name: 'automemberinclusiveregex',
|
||||
widget: 'inclusive.automemberinclusiveregex'
|
||||
},
|
||||
{
|
||||
$type: 'automember_condition',
|
||||
name: 'automemberexclusiveregex',
|
||||
widget: 'exclusive.automemberexclusiveregex'
|
||||
}
|
||||
];
|
||||
|
||||
spec.widgets = [
|
||||
{
|
||||
$type: 'details_section',
|
||||
name: 'general',
|
||||
label: '@i18n:details.general',
|
||||
widgets: [
|
||||
{
|
||||
name: 'cn'
|
||||
},
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$factory: IPA.section,
|
||||
name: 'inclusive',
|
||||
label: '@i18n:objects.automember.inclusive',
|
||||
widgets: [
|
||||
{
|
||||
$type: 'automember_condition',
|
||||
name: 'automemberinclusiveregex',
|
||||
group_type: spec.group_type,
|
||||
add_command: 'add_condition',
|
||||
remove_command: 'remove_condition',
|
||||
adder_dialog: {
|
||||
title: '@i18n:objects.automember.add_condition',
|
||||
fields: [
|
||||
{
|
||||
name: 'key',
|
||||
$type: 'select',
|
||||
options: IPA.automember.get_condition_attributes(spec.group_type),
|
||||
label: '@i18n:objects.automember.attribute'
|
||||
},
|
||||
{
|
||||
name: 'automemberinclusiveregex',
|
||||
label: '@i18n:objects.automember.expression',
|
||||
required: true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$factory: IPA.section,
|
||||
name: 'exclusive',
|
||||
label: '@i18n:objects.automember.exclusive',
|
||||
widgets: [
|
||||
{
|
||||
$type: 'automember_condition',
|
||||
name: 'automemberexclusiveregex',
|
||||
group_type: spec.group_type,
|
||||
add_command: 'add_condition',
|
||||
remove_command: 'remove_condition',
|
||||
adder_dialog: {
|
||||
title: '@i18n:objects.automember.add_condition',
|
||||
fields: [
|
||||
{
|
||||
name: 'key',
|
||||
$type: 'select',
|
||||
options: IPA.automember.get_condition_attributes(spec.group_type),
|
||||
label: '@i18n:objects.automember.attribute'
|
||||
},
|
||||
{
|
||||
name: 'automemberexclusiveregex',
|
||||
label: '@i18n:objects.automember.expression',
|
||||
required: true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
var that = IPA.details_facet(spec);
|
||||
|
||||
that.group_type = spec.group_type;
|
||||
|
||||
that.get_refresh_command_name = function() {
|
||||
return that.entity.name+that.group_type+'_show';
|
||||
};
|
||||
|
||||
that.create_refresh_command = function() {
|
||||
|
||||
var command = that.details_facet_create_refresh_command();
|
||||
command.set_option('type', that.group_type);
|
||||
|
||||
return command;
|
||||
};
|
||||
|
||||
that.create_update_command = function() {
|
||||
|
||||
var command = that.details_facet_create_update_command();
|
||||
command.set_option('type', that.group_type);
|
||||
|
||||
return command;
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.automember.rule_adder_dialog = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.entity_adder_dialog(spec);
|
||||
that.group_type = spec.group_type || '';
|
||||
|
||||
that.show_edit_page = function (entity,result) {
|
||||
var pkey_name = entity.metadata.primary_key;
|
||||
var pkey = result[pkey_name];
|
||||
if (pkey instanceof Array) {
|
||||
pkey = pkey[0];
|
||||
}
|
||||
|
||||
var facetname = that.group_type === 'group' ? 'usergrouprule' :
|
||||
'hostgrouprule';
|
||||
|
||||
navigation.show_entity(that.entity.name, facetname, [pkey]);
|
||||
};
|
||||
|
||||
that.reset = function() {
|
||||
|
||||
var field = that.fields.get_field('cn');
|
||||
|
||||
field.widget.other_entity = IPA.get_entity(that.group_type);
|
||||
|
||||
that.dialog_reset();
|
||||
};
|
||||
|
||||
that.create_add_command = function(record) {
|
||||
|
||||
var command = that.entity_adder_dialog_create_add_command(record);
|
||||
command.name = that.entity.name+that.group_type+'_show';
|
||||
command.set_option('type', that.group_type);
|
||||
|
||||
return command;
|
||||
};
|
||||
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.automember.rule_deleter_dialog = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.search_deleter_dialog(spec);
|
||||
that.group_type = spec.group_type || '';
|
||||
|
||||
that.create_command = function() {
|
||||
|
||||
var batch = that.search_deleter_dialog_create_command();
|
||||
|
||||
for (var i=0; i<batch.commands.length; i++) {
|
||||
var command = batch.commands[i];
|
||||
command.set_option('type', that.group_type);
|
||||
}
|
||||
|
||||
return batch;
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.automember.get_condition_attributes = function(type) {
|
||||
var options = [];
|
||||
|
||||
if (type === 'group') {
|
||||
options = metadata_provider.get('@mo:user.aciattrs');
|
||||
} else if (type === 'hostgroup') {
|
||||
options = metadata_provider.get('@mo:host.aciattrs');
|
||||
}
|
||||
|
||||
var list_options = IPA.create_options(options);
|
||||
return list_options;
|
||||
};
|
||||
|
||||
IPA.automember.parse_condition_regex = function(regex) {
|
||||
|
||||
var delimeter_index = regex.indexOf('=');
|
||||
var condition = {
|
||||
condition: regex,
|
||||
attribute: regex.substring(0, delimeter_index),
|
||||
expression: regex.substring(delimeter_index+1)
|
||||
};
|
||||
|
||||
return condition;
|
||||
};
|
||||
|
||||
IPA.automember.condition_field = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
spec.adapter = spec.adapter || IPA.automember.condition_adapter;
|
||||
var that = IPA.field(spec);
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.automember.condition_adapter = declare([field_mod.Adapter], {
|
||||
|
||||
load: function(data) {
|
||||
var regexes = this.inherited(arguments);
|
||||
var values = [];
|
||||
if (regexes) {
|
||||
for (var i=0, j=0; i<regexes.length; i++) {
|
||||
if (regexes[i] === '') continue;
|
||||
var condition = IPA.automember.parse_condition_regex(regexes[i]);
|
||||
values.push(condition);
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
});
|
||||
|
||||
IPA.automember.condition_widget = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
spec.footer = spec.footer === undefined ? false : spec.footer;
|
||||
|
||||
spec.columns = $.merge(spec.columns || [], [
|
||||
{
|
||||
name: 'attribute',
|
||||
label: '@i18n:objects.automember.attribute'
|
||||
},
|
||||
{
|
||||
name: 'expression',
|
||||
label: '@i18n:objects.automember.expression'
|
||||
}
|
||||
]);
|
||||
|
||||
spec.value_attribute = 'condition';
|
||||
|
||||
var that = IPA.attribute_table_widget(spec);
|
||||
|
||||
that.group_type = spec.group_type;
|
||||
|
||||
that.get_additional_options = function() {
|
||||
return [
|
||||
{
|
||||
name: 'type',
|
||||
value: that.group_type
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
that.on_add = function(data) {
|
||||
|
||||
if (data.result.completed === 0) {
|
||||
that.refresh_facet();
|
||||
} else {
|
||||
that.reload_facet(data);
|
||||
}
|
||||
};
|
||||
|
||||
that.on_remove = function(data) {
|
||||
|
||||
var results = data.result.results;
|
||||
|
||||
var i = results.length - 1;
|
||||
while (i >= 0) {
|
||||
if (results[i].completed === 1){
|
||||
that.reload_facet({ error: results[i].error, id: null,
|
||||
result: results[i] });
|
||||
return;
|
||||
}
|
||||
i--;
|
||||
}
|
||||
|
||||
that.refresh_facet();
|
||||
};
|
||||
|
||||
that.create_remove_command = function(values, on_success, on_error) {
|
||||
|
||||
var batch = rpc.batch_command({
|
||||
name: 'automember_remove_condition',
|
||||
on_success: on_success,
|
||||
on_error: on_error
|
||||
});
|
||||
|
||||
var pkeys = that.get_pkeys();
|
||||
|
||||
for (var i=0; i<values.length; i++) {
|
||||
var condition = IPA.automember.parse_condition_regex(values[i]);
|
||||
|
||||
var command = that.attribute_table_create_remove_command([]);
|
||||
command.set_option('key', condition.attribute);
|
||||
command.set_option(that.attribute_name, condition.expression);
|
||||
|
||||
batch.add_command(command);
|
||||
}
|
||||
|
||||
return batch;
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.automember.default_group_widget = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.widget(spec);
|
||||
that.group_type = spec.group_type;
|
||||
that.group = '';
|
||||
|
||||
var init = function() {
|
||||
|
||||
that.group_select = IPA.entity_select_widget({
|
||||
name: 'automemberdefaultgroup',
|
||||
other_entity: that.group_type,
|
||||
other_field: 'cn',
|
||||
show_undo: false
|
||||
});
|
||||
|
||||
that.group_select.value_changed.attach(that.group_changed);
|
||||
};
|
||||
|
||||
that.get_group = function() {
|
||||
|
||||
var group = that.group_select.save();
|
||||
group = group.length === 0 ? '' : group[0];
|
||||
return group;
|
||||
};
|
||||
|
||||
that.set_group = function(group) {
|
||||
|
||||
if (group === that.group) return;
|
||||
|
||||
that.group = group;
|
||||
that.group_select.update([group]);
|
||||
};
|
||||
|
||||
that.group_changed = function() {
|
||||
|
||||
var group = that.get_group();
|
||||
|
||||
if (group === that.group) return;
|
||||
|
||||
if (group === '') {
|
||||
that.remove_default_group();
|
||||
} else {
|
||||
that.set_default_group(group);
|
||||
}
|
||||
};
|
||||
|
||||
that.load = function(data) {
|
||||
|
||||
var group = data.result.result.automemberdefaultgroup;
|
||||
|
||||
if (group) group = group[0];
|
||||
|
||||
if (!group || group.indexOf('cn=') === -1) {
|
||||
group = '';
|
||||
} else {
|
||||
//extract from dn
|
||||
var i1 = group.indexOf('=');
|
||||
var i2 = group.indexOf(',');
|
||||
if (i1 > -1 && i2 > -1) {
|
||||
group = group.substring(i1 + 1,i2);
|
||||
}
|
||||
}
|
||||
|
||||
that.update(group);
|
||||
that.set_visible(true);
|
||||
};
|
||||
|
||||
that.update = function(group) {
|
||||
|
||||
group = group || '';
|
||||
|
||||
that.set_group(group);
|
||||
};
|
||||
|
||||
that.create_command = function(method) {
|
||||
|
||||
method = 'default_group_' + method;
|
||||
var command_name = that.entity.name + that.group_type + '_' + method;
|
||||
|
||||
var command = rpc.command({
|
||||
name: command_name,
|
||||
entity: that.entity.name,
|
||||
method: method,
|
||||
options: {
|
||||
type: that.group_type
|
||||
}
|
||||
});
|
||||
|
||||
return command;
|
||||
};
|
||||
|
||||
that.refresh = function() {
|
||||
|
||||
var command = that.create_command('show');
|
||||
command.retry = false;
|
||||
command.on_success = that.load;
|
||||
command.on_error = function() {
|
||||
that.set_visible(false);
|
||||
};
|
||||
|
||||
command.execute();
|
||||
};
|
||||
|
||||
that.remove_default_group = function() {
|
||||
|
||||
var command = that.create_command('remove');
|
||||
|
||||
command.on_success = function() {
|
||||
that.update('');
|
||||
};
|
||||
command.on_error = that.refresh;
|
||||
|
||||
command.execute();
|
||||
};
|
||||
|
||||
that.set_default_group = function(group) {
|
||||
|
||||
var command = that.create_command('set');
|
||||
command.on_success = that.load;
|
||||
command.on_error = that.refresh;
|
||||
command.set_option('automemberdefaultgroup', group);
|
||||
|
||||
command.execute();
|
||||
};
|
||||
|
||||
|
||||
that.create = function(container) {
|
||||
|
||||
var title = that.get_title();
|
||||
that.container = container;
|
||||
|
||||
that.header = $('<div/>', {
|
||||
'class': 'automember-header-label',
|
||||
name: 'header',
|
||||
text: title,
|
||||
title: title
|
||||
}).appendTo(container);
|
||||
|
||||
that.group_select_node = $('<div/>', { 'class': 'automember-header-control' });
|
||||
that.group_select.create(that.group_select_node);
|
||||
that.group_select_node.appendTo(container);
|
||||
that.group_select.update([]); // preload groups
|
||||
that.set_visible(false);
|
||||
};
|
||||
|
||||
that.get_title = function() {
|
||||
if (that.group_type === 'group') {
|
||||
return text.get('@i18n:objects.automember.default_user_group');
|
||||
} else {
|
||||
return text.get('@i18n:objects.automember.default_host_group');
|
||||
}
|
||||
};
|
||||
|
||||
init();
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.automember.rebuild_action = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
spec.name = spec.name || 'automember_rebuild';
|
||||
spec.label = spec.label || '@i18n:actions.automember_rebuild';
|
||||
spec.needs_confirm = spec.needs_confirm !== undefined ? spec.needs_confirm : true;
|
||||
spec.confirm_msg = spec.confirm_msg || '@i18n:actions.automember_rebuild_confirm';
|
||||
|
||||
var that = IPA.action(spec);
|
||||
|
||||
that.execute_action = function(facet) {
|
||||
var entity = facet.entity.name;
|
||||
if (facet.name == 'search') {
|
||||
var entries = facet.get_selected_values();
|
||||
} else {
|
||||
entries = facet.get_pkeys();
|
||||
}
|
||||
|
||||
var options = {};
|
||||
if (entries.length > 0) {
|
||||
options[entity + 's'] = entries;
|
||||
} else if (entity == 'user') {
|
||||
options['type'] = 'group';
|
||||
} else {
|
||||
options['type'] = 'hostgroup';
|
||||
}
|
||||
|
||||
var command = rpc.command({
|
||||
entity: 'automember',
|
||||
method: 'rebuild',
|
||||
options: options,
|
||||
on_success: function() {
|
||||
IPA.notify_success('@i18n:actions.automember_rebuild_success');
|
||||
},
|
||||
on_error: function() {
|
||||
}
|
||||
});
|
||||
|
||||
command.execute();
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
exp.entity_spec = make_spec();
|
||||
|
||||
exp.register = function() {
|
||||
var e = reg.entity;
|
||||
var w = reg.widget;
|
||||
var f = reg.field;
|
||||
var a = reg.action;
|
||||
|
||||
e.register({
|
||||
type: 'automember',
|
||||
spec: exp.entity_spec,
|
||||
pre_ops: [ exp.metadata_extension_pre_op ]
|
||||
});
|
||||
w.register('automember_condition', IPA.automember.condition_widget);
|
||||
f.register('automember_condition', IPA.automember.condition_field);
|
||||
a.register('automember_rebuild', exp.rebuild_action);
|
||||
};
|
||||
|
||||
phases.on('registration', exp.register);
|
||||
|
||||
return exp;
|
||||
});
|
||||
376
install/ui/src/freeipa/automount.js
Normal file
376
install/ui/src/freeipa/automount.js
Normal file
@@ -0,0 +1,376 @@
|
||||
/* Authors:
|
||||
* Adam Young <ayoung@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'./ipa',
|
||||
'./jquery',
|
||||
'./navigation',
|
||||
'./phases',
|
||||
'./reg',
|
||||
'./details',
|
||||
'./search',
|
||||
'./association',
|
||||
'./entity'],
|
||||
function(IPA, $, navigation, phases, reg) {
|
||||
|
||||
var exp = IPA.automount = {};
|
||||
|
||||
var make_location_spec = function() {
|
||||
return {
|
||||
name: 'automountlocation',
|
||||
facet_groups: [ 'automountmap', 'settings' ],
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
title: '@mo:automountlocation.label',
|
||||
columns:['cn']
|
||||
},
|
||||
{
|
||||
$type: 'nested_search',
|
||||
facet_group: 'automountmap',
|
||||
nested_entity: 'automountmap',
|
||||
label: '@mo:automountmap.label',
|
||||
tab_label: '@mo:automountmap.label',
|
||||
name: 'maps',
|
||||
columns: [ 'automountmapname' ]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
sections:[
|
||||
{
|
||||
name: 'identity',
|
||||
label: '@i18n:details.identity',
|
||||
fields: [ 'cn' ]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
adder_dialog: {
|
||||
fields: [ 'cn' ]
|
||||
}
|
||||
};};
|
||||
|
||||
var make_map_spec = function() {
|
||||
return {
|
||||
name: 'automountmap',
|
||||
containing_entity: 'automountlocation',
|
||||
facet_groups: [ 'automountkey', 'settings' ],
|
||||
facets: [
|
||||
{
|
||||
$type: 'nested_search',
|
||||
$factory: IPA.automount.key_search_facet,
|
||||
facet_group: 'automountkey',
|
||||
nested_entity: 'automountkey',
|
||||
search_all_entries: true,
|
||||
label: '@mo:automountkey.label',
|
||||
tab_label: '@mo:automountkey.label',
|
||||
name: 'keys',
|
||||
columns: [
|
||||
{
|
||||
$factory: IPA.automount_key_column,
|
||||
name: 'automountkey',
|
||||
label: '@mo-param:automountkey:automountkey:label'
|
||||
},
|
||||
'automountinformation'
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
sections: [
|
||||
{
|
||||
name: 'identity',
|
||||
label: '@i18n:details.identity',
|
||||
fields: [
|
||||
'automountmapname',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
adder_dialog: {
|
||||
$factory: IPA.automountmap_adder_dialog,
|
||||
sections: [
|
||||
{
|
||||
name: 'general',
|
||||
fields: [
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'method',
|
||||
flags: ['no_command'],
|
||||
label: '@i18n:objects.automountmap.map_type',
|
||||
options: [
|
||||
{
|
||||
value: 'add',
|
||||
label: '@i18n:objects.automountmap.direct'
|
||||
},
|
||||
{
|
||||
value: 'add_indirect',
|
||||
label: '@i18n:objects.automountmap.indirect'
|
||||
}
|
||||
]
|
||||
},
|
||||
'automountmapname',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'indirect',
|
||||
fields: [
|
||||
{
|
||||
name: 'key',
|
||||
label: '@mc-opt:automountmap_add_indirect:key:label'
|
||||
},
|
||||
{
|
||||
name: 'parentmap',
|
||||
label: '@mc-opt:automountmap_add_indirect:parentmap:label'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
};};
|
||||
|
||||
var make_key_spec = function() {
|
||||
return {
|
||||
name: 'automountkey',
|
||||
policies:[
|
||||
{
|
||||
$factory: IPA.facet_update_policy,
|
||||
source_facet: 'details',
|
||||
dest_entity: 'automountmap',
|
||||
dest_facet: 'keys'
|
||||
}
|
||||
],
|
||||
containing_entity: 'automountmap',
|
||||
facets: [
|
||||
{
|
||||
$type: 'details',
|
||||
$factory: IPA.automount.key_details_facet,
|
||||
sections: [
|
||||
{
|
||||
name:'identity',
|
||||
label: '@i18n:details.identity',
|
||||
fields: [
|
||||
{
|
||||
name: 'automountkey',
|
||||
read_only: true
|
||||
},
|
||||
'automountinformation'
|
||||
]
|
||||
}
|
||||
],
|
||||
disable_breadcrumb: false
|
||||
}
|
||||
],
|
||||
adder_dialog: {
|
||||
show_edit_page : function(entity, result){
|
||||
var key = result.automountkey[0];
|
||||
var info = result.automountinformation[0];
|
||||
var pkeys = this.pkey_prefix.slice(0);
|
||||
pkeys.push(key);
|
||||
|
||||
var args = {
|
||||
info: info,
|
||||
key: key
|
||||
};
|
||||
|
||||
navigation.show_entity(entity.name, 'details', pkeys, args);
|
||||
return false;
|
||||
},
|
||||
fields:['automountkey','automountinformation']
|
||||
}
|
||||
};};
|
||||
|
||||
IPA.automount.key_details_facet = function(spec) {
|
||||
|
||||
var that = IPA.details_facet(spec);
|
||||
|
||||
that.create_update_command = function() {
|
||||
|
||||
var command = that.details_facet_create_update_command();
|
||||
|
||||
command.args.pop();
|
||||
|
||||
var key = that.state.key;
|
||||
var info = that.state.info;
|
||||
|
||||
command.options.newautomountinformation = command.options.automountinformation;
|
||||
command.options.automountkey = key;
|
||||
command.options.automountinformation = info;
|
||||
|
||||
return command;
|
||||
};
|
||||
|
||||
that.create_refresh_command = function() {
|
||||
|
||||
var command = that.details_facet_create_refresh_command();
|
||||
|
||||
command.args.pop();
|
||||
|
||||
var key = that.state.key;
|
||||
var info = that.state.info;
|
||||
|
||||
command.options.automountkey = key;
|
||||
command.options.automountinformation = info;
|
||||
|
||||
return command;
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.automount_key_column = function(spec) {
|
||||
|
||||
var that = IPA.column(spec);
|
||||
|
||||
that.setup = function(container, record) {
|
||||
|
||||
container.empty();
|
||||
|
||||
var key = record.automountkey;
|
||||
if (key instanceof Array) key = key[0];
|
||||
var info = record.automountinformation;
|
||||
if (info instanceof Array) info = info[0];
|
||||
|
||||
$('<a/>', {
|
||||
href: '#'+key,
|
||||
text: key,
|
||||
click: function() {
|
||||
|
||||
var pkeys = that.facet.get_pkeys();
|
||||
pkeys.push(key);
|
||||
|
||||
var args = {
|
||||
info: info,
|
||||
key: key
|
||||
};
|
||||
|
||||
navigation.show_entity(that.entity.name, 'details', pkeys, args);
|
||||
return false;
|
||||
}
|
||||
}).appendTo(container);
|
||||
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.automountmap_adder_dialog = function(spec) {
|
||||
|
||||
var that = IPA.entity_adder_dialog(spec);
|
||||
|
||||
that.create_content = function() {
|
||||
that.entity_adder_dialog_create_content();
|
||||
|
||||
var method_widget = that.widgets.get_widget('general.method');
|
||||
var indirect_section = that.widgets.get_widget('indirect');
|
||||
var key_field = that.fields.get_field('key');
|
||||
var parentmap_field = that.fields.get_field('parentmap');
|
||||
|
||||
var direct_input = $('input[value="add"]', method_widget.container);
|
||||
direct_input.change(function() {
|
||||
that.method = 'add';
|
||||
|
||||
key_field.set_enabled(false);
|
||||
parentmap_field.set_enabled(false);
|
||||
|
||||
key_field.set_required(false);
|
||||
indirect_section.set_visible(false);
|
||||
});
|
||||
|
||||
var indirect_input = $('input[value="add_indirect"]', method_widget.container);
|
||||
indirect_input.change(function() {
|
||||
that.method = 'add_indirect';
|
||||
|
||||
key_field.set_enabled(true);
|
||||
parentmap_field.set_enabled(true);
|
||||
|
||||
key_field.set_required(true);
|
||||
indirect_section.set_visible(true);
|
||||
});
|
||||
|
||||
direct_input.prop('checked', true);
|
||||
direct_input.trigger('change');
|
||||
};
|
||||
|
||||
that.reset = function() {
|
||||
that.dialog_reset();
|
||||
|
||||
var method_widget = that.widgets.get_widget('general.method');
|
||||
|
||||
var direct_input = $('input[value="add"]', method_widget.container);
|
||||
direct_input.prop('checked', true);
|
||||
direct_input.trigger('change');
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.automount.key_search_facet = function(spec) {
|
||||
|
||||
var that = IPA.nested_search_facet(spec);
|
||||
|
||||
that.get_selected_values = function() {
|
||||
|
||||
var values = [];
|
||||
var keys = that.table.get_selected_values();
|
||||
var records = that.table.records;
|
||||
|
||||
if (keys.length === 0 || !records) return values;
|
||||
|
||||
for (var i=0,l=records.length; i<l; i++) {
|
||||
var record = records[i];
|
||||
if (keys.indexOf(record.description[0]) > -1) {
|
||||
values.push({
|
||||
automountkey: record.automountkey[0],
|
||||
automountinformation: record.automountinformation[0]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return values;
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
exp.location_spec = make_location_spec();
|
||||
exp.map_spec = make_map_spec();
|
||||
exp.key_spec = make_key_spec();
|
||||
|
||||
exp.register = function() {
|
||||
var e = reg.entity;
|
||||
|
||||
e.register({type: 'automountlocation', spec: exp.location_spec});
|
||||
e.register({type: 'automountmap', spec: exp.map_spec});
|
||||
e.register({type: 'automountkey', spec: exp.key_spec});
|
||||
};
|
||||
|
||||
phases.on('registration', exp.register);
|
||||
|
||||
return exp;
|
||||
});
|
||||
82
install/ui/src/freeipa/builder.js
Normal file
82
install/ui/src/freeipa/builder.js
Normal file
@@ -0,0 +1,82 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define(['dojo/_base/declare',
|
||||
'dojo/_base/array',
|
||||
'dojo/_base/lang',
|
||||
'./_base/Builder',
|
||||
'./_base/Singleton_registry'
|
||||
], function(declare, array, lang, Builder, Singleton_registry) {
|
||||
|
||||
var builder_registry = new Singleton_registry();
|
||||
builder_registry.builder.ctor = Builder;
|
||||
|
||||
/**
|
||||
* Global builder interface.
|
||||
*
|
||||
* Contains a map of builders for a specific object type.
|
||||
*
|
||||
* @class builder
|
||||
* @singleton
|
||||
*/
|
||||
var exp = {
|
||||
/**
|
||||
* Registry of builders
|
||||
* @property {_base.Singleton_registry}
|
||||
*/
|
||||
builders: builder_registry,
|
||||
|
||||
/**
|
||||
* Get builder for object type
|
||||
*
|
||||
* @param {string} object type
|
||||
*/
|
||||
get: function(obj_type) {
|
||||
return this.builders.get(obj_type);
|
||||
},
|
||||
|
||||
/**
|
||||
* Set builder for object type.
|
||||
*
|
||||
* @param {string} object type
|
||||
* @param {_base.Builder} builder
|
||||
*/
|
||||
set: function(obj_type, builder) {
|
||||
this.builders.set(obj_type, builder);
|
||||
},
|
||||
|
||||
/**
|
||||
* Build object by builder for given object type.
|
||||
*
|
||||
* @param {string} object type. Uses generic builder if empty string.
|
||||
* @param {string|Object|Function} spec
|
||||
* @param {Object|null} context
|
||||
* @param {Object|null} build overrides
|
||||
*/
|
||||
build: function(obj_type, spec, context, overrides) {
|
||||
|
||||
obj_type = obj_type || 'generic';
|
||||
var builder = this.builders.get(obj_type);
|
||||
return builder.build(spec, context, overrides);
|
||||
}
|
||||
};
|
||||
|
||||
return exp;
|
||||
});
|
||||
1954
install/ui/src/freeipa/certificate.js
Executable file
1954
install/ui/src/freeipa/certificate.js
Executable file
File diff suppressed because it is too large
Load Diff
128
install/ui/src/freeipa/config.js
Normal file
128
install/ui/src/freeipa/config.js
Normal file
@@ -0,0 +1,128 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
define([
|
||||
'dojo/_base/declare',
|
||||
'dojo/topic'
|
||||
],
|
||||
function(declare, topic) {
|
||||
|
||||
/**
|
||||
* Application configuration
|
||||
* @class config
|
||||
* @singleton
|
||||
*/
|
||||
var config = declare([], {
|
||||
|
||||
/**
|
||||
* Selector for application container node
|
||||
*/
|
||||
app_container: 'body',
|
||||
|
||||
/**
|
||||
* Live server path
|
||||
*/
|
||||
url: '/ipa/ui/',
|
||||
|
||||
/**
|
||||
* RPC url
|
||||
*/
|
||||
json_url: '/ipa/session/json',
|
||||
|
||||
/**
|
||||
* Kerberos authentication url
|
||||
*/
|
||||
krb_login_url: '/ipa/session/login_kerberos',
|
||||
|
||||
/**
|
||||
* Forms based login url
|
||||
*/
|
||||
frms_login_url: '/ipa/session/login_password',
|
||||
|
||||
//logout_url: '/ipa/session/json',
|
||||
|
||||
/**
|
||||
* Password reset url
|
||||
*/
|
||||
reset_psw_url: '/ipa/session/change_password',
|
||||
|
||||
/**
|
||||
* Ajax options for RPC commands
|
||||
*/
|
||||
ajax_options: {
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
dataType: 'json',
|
||||
async: true,
|
||||
processData: false
|
||||
},
|
||||
|
||||
/**
|
||||
* Hide read-only widgets without value
|
||||
* @property {boolean}
|
||||
*/
|
||||
hide_empty_widgets: false,
|
||||
|
||||
/**
|
||||
* Hide sections without any visible widget
|
||||
* @property {boolean}
|
||||
*/
|
||||
hide_empty_sections: true,
|
||||
|
||||
/**
|
||||
* Number of lines in table on table_facets
|
||||
* @property {Integer}
|
||||
*/
|
||||
table_page_size: 20,
|
||||
|
||||
/**
|
||||
* Genereal setter for config values.
|
||||
* @param item_name {string}
|
||||
* @param value
|
||||
* @param store {Boolean} sets whether the value will be stored into
|
||||
* local storage
|
||||
*/
|
||||
set: function(item_name, value, store) {
|
||||
if (!item_name) return;
|
||||
this[item_name] = value;
|
||||
|
||||
if (store) {
|
||||
window.localStorage.setItem(item_name, value);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Genereal setter for config values.
|
||||
* @param item_name {string}
|
||||
*/
|
||||
get: function(item_name) {
|
||||
return this[item_name];
|
||||
},
|
||||
|
||||
constructor: function() {
|
||||
var user_limit = window.localStorage.getItem('table_page_size');
|
||||
if (user_limit) this.table_page_size = user_limit;
|
||||
}
|
||||
});
|
||||
|
||||
return new config();
|
||||
});
|
||||
27
install/ui/src/freeipa/core.js
Normal file
27
install/ui/src/freeipa/core.js
Normal file
@@ -0,0 +1,27 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'./app_container',
|
||||
'./plugins/sync_otp',
|
||||
'./plugins/login'
|
||||
],function(app_container) {
|
||||
return app_container;
|
||||
});
|
||||
217
install/ui/src/freeipa/datetime.js
Normal file
217
install/ui/src/freeipa/datetime.js
Normal file
@@ -0,0 +1,217 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2014 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
define([
|
||||
'dojo/string'
|
||||
], function(string) {
|
||||
|
||||
var templates = {
|
||||
human: '${YYYY}-${MM}-${DD} ${HH}:${mm}:${ss}Z',
|
||||
generalized: '${YYYY}${MM}${DD}${HH}${mm}${ss}Z'
|
||||
};
|
||||
|
||||
var dates = [
|
||||
['YYYY-MM-DD', /^(\d{4})-(\d{2})-(\d{2})$/],
|
||||
['YYYYMMDD',/^(\d{4})(\d{2})(\d{2})$/]
|
||||
];
|
||||
|
||||
var times = [
|
||||
['HH:mm:ss', /^(\d\d):(\d\d):(\d\d)$/],
|
||||
['HH:mm', /^(\d\d):(\d\d)$/]
|
||||
];
|
||||
|
||||
var generalized_regex = /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z$/;
|
||||
var datetime_regex = /^((?:\d{8})|(?:\d{4}-\d{2}-\d{2}))(?:(T| )(\d\d:\d\d(?::\d\d)?)(Z?))?$/;
|
||||
|
||||
function parse(value) {
|
||||
|
||||
var Y=0, M=0, D=0, H=0, m=0, s=0;
|
||||
var i, l, dateStr, timeStr, utc;
|
||||
|
||||
var dt_match = datetime_regex.exec(value);
|
||||
var gt_match = generalized_regex.exec(value);
|
||||
if (dt_match) {
|
||||
dateStr = dt_match[1];
|
||||
timeStr = dt_match[3];
|
||||
utc = dt_match[4] || !timeStr;
|
||||
|
||||
// error out if local time not supported
|
||||
if (!this.allow_local && !utc) return null;
|
||||
|
||||
for (i = 0, l = dates.length; i < l; i++) {
|
||||
var dm = dates[i][1].exec(dateStr);
|
||||
if (dm) {
|
||||
Y = dm[1];
|
||||
M = dm[2];
|
||||
D = dm[3];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (timeStr) {
|
||||
for (i = 0, l = times.length; i < l; i++) {
|
||||
var tm = times[i][1].exec(timeStr);
|
||||
if (tm) {
|
||||
H = tm[1];
|
||||
m = tm[2] || 0;
|
||||
s = tm[3] || 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (gt_match) {
|
||||
Y = gt_match[1];
|
||||
M = gt_match[2];
|
||||
D = gt_match[3];
|
||||
H = gt_match[4];
|
||||
m = gt_match[5];
|
||||
s = gt_match[6];
|
||||
utc = true;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
var date = new Date();
|
||||
|
||||
if (utc || !timeStr) {
|
||||
date.setUTCFullYear(Y, M-1, D);
|
||||
date.setUTCHours(H, m, s, 0);
|
||||
} else {
|
||||
date.setFullYear(Y, M-1, D);
|
||||
date.setHours(H, m, s, 0);
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
function formatDate(date, format, local) {
|
||||
|
||||
var fmt = format || templates.human;
|
||||
var str;
|
||||
|
||||
function pad(value) {
|
||||
return string.pad(value, 2, '0');
|
||||
}
|
||||
|
||||
if (local) {
|
||||
str = string.substitute(fmt, {
|
||||
YYYY: date.getFullYear(),
|
||||
MM: pad(date.getMonth()+1),
|
||||
DD: pad(date.getDate()),
|
||||
HH: pad(date.getHours()),
|
||||
mm: pad(date.getMinutes()),
|
||||
ss: pad(date.getSeconds())
|
||||
});
|
||||
} else {
|
||||
str = string.substitute(fmt, {
|
||||
YYYY: date.getUTCFullYear(),
|
||||
MM: pad(date.getUTCMonth()+1),
|
||||
DD: pad(date.getUTCDate()),
|
||||
HH: pad(date.getUTCHours()),
|
||||
mm: pad(date.getUTCMinutes()),
|
||||
ss: pad(date.getUTCSeconds())
|
||||
});
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility module to parse strings in ISO 8601-ish format into Date object
|
||||
* and vice versa
|
||||
*
|
||||
* @class datetime
|
||||
* @singleton
|
||||
*/
|
||||
var datetime = {
|
||||
/**
|
||||
* Parse string, return date or null on error.
|
||||
*
|
||||
* Supported date formats:
|
||||
*
|
||||
* - `YYYY-MM-DD`
|
||||
* - `YYYYMMDD`
|
||||
*
|
||||
* Supported time formats:
|
||||
*
|
||||
* - `HH:mm:ss`
|
||||
* - `HH:mm`
|
||||
*
|
||||
* Supported formats:
|
||||
*
|
||||
* - `$dateT$timeZ`
|
||||
* - `$date $timeZ`
|
||||
* - `$date`
|
||||
* - `YYYYMMDDHHmmssZ`
|
||||
*
|
||||
* Where Z indicates UTC date. Parsing of local dates is by default
|
||||
* disabled. It can be enabled by setting `datetime.allow_local` to
|
||||
* `true`.
|
||||
*
|
||||
* @param {string} value
|
||||
* @returns {Date|null} parsed date
|
||||
*/
|
||||
parse: parse,
|
||||
|
||||
/**
|
||||
* Convert date to string
|
||||
*
|
||||
* - `${YYYY}` - year
|
||||
* - `${MM}` - month
|
||||
* - `${DD}` - day
|
||||
* - `${HH}` - hours
|
||||
* - `${mm}` - minutes
|
||||
* - `${ss}` - seconds
|
||||
*
|
||||
* Default format string: `${YYYY}-${MM}-${DD} ${HH}:${mm}:${ss}`
|
||||
*
|
||||
* @param {Date} date
|
||||
* @param {string} [format] format string
|
||||
* @param {boolean} [local] use local time
|
||||
*/
|
||||
format: formatDate,
|
||||
|
||||
/**
|
||||
* Local time input method support
|
||||
* @property {boolean}
|
||||
*/
|
||||
allow_local: false,
|
||||
|
||||
/**
|
||||
* Convert date value to generalized time string
|
||||
* @param {Date} date
|
||||
* @returns {string}
|
||||
*/
|
||||
to_generalized_time: function(date) {
|
||||
return this.format(date, templates.generalized);
|
||||
},
|
||||
|
||||
/**
|
||||
* Dictionary of common format strings
|
||||
*
|
||||
* - `human` - default format string of `format` method
|
||||
* - `generalized` - generalized time (LDAP) format
|
||||
*
|
||||
* @property {Object}
|
||||
*/
|
||||
templates: templates
|
||||
};
|
||||
|
||||
return datetime;
|
||||
});
|
||||
2114
install/ui/src/freeipa/details.js
Normal file
2114
install/ui/src/freeipa/details.js
Normal file
File diff suppressed because it is too large
Load Diff
51
install/ui/src/freeipa/develop.js
Normal file
51
install/ui/src/freeipa/develop.js
Normal file
@@ -0,0 +1,51 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
define(['./ipa'], function(IPA) {
|
||||
|
||||
//polute global namespace - easy usage in browser console
|
||||
window.IPA = IPA;
|
||||
var console = window.console; // avoid jsl error
|
||||
|
||||
var tools = window.ipadev = IPA.dev = {
|
||||
|
||||
// map of loaded modules
|
||||
modules: {},
|
||||
|
||||
get: function (mid,name) {
|
||||
/* loads module into ipa dev modules property */
|
||||
|
||||
var self = this;
|
||||
var mid_parts = mid.split('/');
|
||||
name = name || mid_parts[mid_parts.length-1];
|
||||
|
||||
require([mid], function(module) {
|
||||
self.modules[name] = module;
|
||||
console.log('Module '+mid+' loaded.');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
console.log('Dev tools loaded.');
|
||||
|
||||
return tools;
|
||||
|
||||
}); //define
|
||||
1942
install/ui/src/freeipa/dialog.js
Normal file
1942
install/ui/src/freeipa/dialog.js
Normal file
File diff suppressed because it is too large
Load Diff
147
install/ui/src/freeipa/dialogs/password.js
Normal file
147
install/ui/src/freeipa/dialogs/password.js
Normal file
@@ -0,0 +1,147 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'dojo/_base/lang',
|
||||
'../builder',
|
||||
'../ipa',
|
||||
'../phases',
|
||||
'../reg',
|
||||
'../rpc',
|
||||
'../text',
|
||||
'../dialog'],
|
||||
function(lang, builder, IPA, phases, reg, rpc, text, dialogs) {
|
||||
|
||||
/**
|
||||
* Password dialog module
|
||||
* @class
|
||||
* @singleton
|
||||
*/
|
||||
dialogs.password = {};
|
||||
var DP = dialogs.password;
|
||||
|
||||
/**
|
||||
* Dialog's pre_ops
|
||||
*/
|
||||
dialogs.password.default_fields_pre_op = function(spec) {
|
||||
|
||||
var name = spec.password_name || 'password1';
|
||||
var label = spec.password_label || '@i18n:password.new_password';
|
||||
var verify_label = spec.verify_label ||'@i18n:password.verify_password';
|
||||
|
||||
spec.title = spec.title || '@i18n:password.reset_password';
|
||||
spec.width = spec.width || 400;
|
||||
spec.success_message = spec.success_message || '@i18n:password.password_change_complete';
|
||||
spec.confirm_button_label = spec.confirm_button_label || '@i18n:password.reset_password';
|
||||
spec.sections = spec.sections || [
|
||||
{
|
||||
name: 'general',
|
||||
fields: [
|
||||
{
|
||||
name: name,
|
||||
label: label,
|
||||
$type: 'password',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: 'password2',
|
||||
label: verify_label,
|
||||
$type: 'password',
|
||||
required: true,
|
||||
flags: ['no_command'],
|
||||
validators: [{
|
||||
$type: 'same_password',
|
||||
other_field: name
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
return spec;
|
||||
};
|
||||
|
||||
/**
|
||||
* Action to open a password dialog
|
||||
* @class
|
||||
* @extends facet.action
|
||||
*/
|
||||
dialogs.password.action = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
spec.name = spec.name || 'password';
|
||||
spec.label = spec.label || '@i18n:password.reset_password';
|
||||
|
||||
var that = IPA.action(spec);
|
||||
|
||||
/**
|
||||
* Dialog spec
|
||||
* @property {Object}
|
||||
*/
|
||||
that.dialog = spec.dialog || {};
|
||||
|
||||
/**
|
||||
* Refresh facet after successful password reset
|
||||
* @property {boolean} refresh=true
|
||||
*/
|
||||
that.refresh = spec.refresh !== undefined ? spec.refresh : true;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
that.execute_action = function(facet) {
|
||||
|
||||
var ds = lang.clone(that.dialog);
|
||||
ds.entity = ds.entity || facet.entity;
|
||||
if (!ds.$type && !ds.$factory && !ds.$ctor) {
|
||||
ds.$type = 'password';
|
||||
}
|
||||
var dialog = builder.build('dialog', ds);
|
||||
dialog.args = facet.get_pkeys();
|
||||
dialog.succeeded.attach(function() {
|
||||
if (that.refresh) facet.refresh();
|
||||
});
|
||||
dialog.open();
|
||||
};
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* Register dialog
|
||||
* @member dialogs.password
|
||||
*/
|
||||
dialogs.password.register = function() {
|
||||
|
||||
var d = reg.dialog;
|
||||
var a = reg.action;
|
||||
|
||||
d.register({
|
||||
type: 'password',
|
||||
factory: dialogs.command_dialog,
|
||||
pre_ops: [DP.default_fields_pre_op],
|
||||
post_ops: [dialogs.command_dialog_post_op]
|
||||
});
|
||||
|
||||
a.register('password', DP.action);
|
||||
};
|
||||
|
||||
phases.on('registration', DP.register);
|
||||
|
||||
return DP;
|
||||
});
|
||||
2695
install/ui/src/freeipa/dns.js
Normal file
2695
install/ui/src/freeipa/dns.js
Normal file
File diff suppressed because it is too large
Load Diff
1107
install/ui/src/freeipa/entity.js
Normal file
1107
install/ui/src/freeipa/entity.js
Normal file
File diff suppressed because it is too large
Load Diff
60
install/ui/src/freeipa/extend.js
Normal file
60
install/ui/src/freeipa/extend.js
Normal file
@@ -0,0 +1,60 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2014 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'dojo/_base/lang',
|
||||
'./jquery',
|
||||
'./phases',
|
||||
'./app_container',
|
||||
'exports'
|
||||
],function(lang, $, phases, app, extend) {
|
||||
|
||||
/**
|
||||
* Extension interface
|
||||
*
|
||||
* This class provides interface for plugins and tries to hide underlying functionality
|
||||
*
|
||||
* @class extend
|
||||
* @singleton
|
||||
*/
|
||||
lang.mixin(extend, {
|
||||
/**
|
||||
* Adds element to utility section
|
||||
*
|
||||
* This method doesn't do any correction. Expended root node type to add is
|
||||
* by default `<li>`.
|
||||
*
|
||||
* Preferred phase: any after `init`
|
||||
*
|
||||
* @param {HTMLElement|jQuery} element Element to add to utility section
|
||||
* @return {HTMLElement} Utility node
|
||||
*/
|
||||
add_menu_utility: function(element) {
|
||||
|
||||
// Should we check if we are in good stage or atleast report that app doesn't exist yet?
|
||||
|
||||
var $utility = $(app.app.app_widget.nav_util_tool_node);
|
||||
$utility.prepend(element);
|
||||
return $utility.eq(0);
|
||||
}
|
||||
});
|
||||
|
||||
return extend;
|
||||
});
|
||||
3733
install/ui/src/freeipa/facet.js
Normal file
3733
install/ui/src/freeipa/facet.js
Normal file
File diff suppressed because it is too large
Load Diff
49
install/ui/src/freeipa/facets/ActionMixin.js
Normal file
49
install/ui/src/freeipa/facets/ActionMixin.js
Normal file
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// Copyright (C) 2015 FreeIPA Contributors see COPYING for license
|
||||
//
|
||||
|
||||
define(['dojo/_base/declare',
|
||||
'../builder',
|
||||
'../facet'
|
||||
],
|
||||
function(declare, builder, mod_facet) {
|
||||
|
||||
|
||||
/**
|
||||
* Header Mixin
|
||||
*
|
||||
* Extension of facet - actions
|
||||
*
|
||||
* @class facets.ActionMixin
|
||||
*/
|
||||
var ActionMixin = declare([], {
|
||||
|
||||
/**
|
||||
* State object for actions
|
||||
* @property {facet.state}
|
||||
*/
|
||||
action_state: null,
|
||||
|
||||
/**
|
||||
* Collection of facet actions
|
||||
* @property {facet.action_holder}
|
||||
*/
|
||||
actions: null,
|
||||
|
||||
show: function() {
|
||||
this.inherited(arguments);
|
||||
this.actions.on_load();
|
||||
},
|
||||
|
||||
/** Constructor */
|
||||
constructor: function(spec) {
|
||||
|
||||
this.action_state = builder.build('', spec.state || {}, {}, { $factory: mod_facet.state });
|
||||
this.actions = builder.build('', { actions: spec.actions }, {}, { $factory: mod_facet.action_holder } );
|
||||
this.action_state.init(this);
|
||||
this.actions.init(this);
|
||||
}
|
||||
});
|
||||
|
||||
return ActionMixin;
|
||||
});
|
||||
357
install/ui/src/freeipa/facets/Facet.js
Normal file
357
install/ui/src/freeipa/facets/Facet.js
Normal file
@@ -0,0 +1,357 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define(['dojo/_base/declare',
|
||||
'dojo/_base/lang',
|
||||
'dojo/Evented',
|
||||
'dojo/dom-construct',
|
||||
'dojo/dom-class',
|
||||
'dojo/on',
|
||||
'../builder',
|
||||
'../facet',
|
||||
'../ipa', // for util functions
|
||||
'../jquery',
|
||||
'../text',
|
||||
'../widgets/ContainerMixin'
|
||||
],
|
||||
function(declare, lang, Evented, construct, dom_class,
|
||||
on, builder, mod_facet, IPA, $, text, ContainerMixin) {
|
||||
|
||||
/**
|
||||
* Base class of Facet
|
||||
*
|
||||
* A future replacement/base class for `facet.facet`
|
||||
*
|
||||
* @class facets.Facet
|
||||
* @mixins widgets.ContainerMixin
|
||||
*/
|
||||
var Facet = declare([Evented, ContainerMixin], {
|
||||
|
||||
/**
|
||||
* Name of preferred facet container
|
||||
*
|
||||
* Leave unset to use default container.
|
||||
* @property {string}
|
||||
*/
|
||||
preferred_container: null,
|
||||
|
||||
/**
|
||||
* Facet name
|
||||
* @property {string}
|
||||
*/
|
||||
name: null,
|
||||
|
||||
/**
|
||||
* Facet label
|
||||
* @property {string}
|
||||
*/
|
||||
label: null,
|
||||
|
||||
/**
|
||||
* Facet title
|
||||
* @property {string}
|
||||
*/
|
||||
title: null,
|
||||
|
||||
/**
|
||||
* Facet tab label
|
||||
* @property {string}
|
||||
*/
|
||||
tab_label: null,
|
||||
|
||||
/**
|
||||
* Facet element's CSS class
|
||||
* @property {string}
|
||||
*/
|
||||
'class': null,
|
||||
|
||||
/**
|
||||
* Class which tells that the facet should be visible
|
||||
* @property {string}
|
||||
*/
|
||||
active_class: 'active',
|
||||
|
||||
/**
|
||||
* dom_node of container
|
||||
* Suppose to contain dom_node of this and other facets.
|
||||
* @property {jQuery}
|
||||
*/
|
||||
container_node: null,
|
||||
|
||||
/**
|
||||
* dom_node which contains all content of this Facet.
|
||||
* @property {HTMLElement}
|
||||
* @readonly
|
||||
*/
|
||||
dom_node: null,
|
||||
|
||||
/**
|
||||
* DOM node which serves as container for child widgets
|
||||
* @property {HTMLElement}
|
||||
*/
|
||||
children_node: null,
|
||||
|
||||
/**
|
||||
* Redirection target information.
|
||||
*
|
||||
* Can be facet and/or entity name.
|
||||
* @property {Object}
|
||||
* @param {string} entity entity name
|
||||
* @param {string} facet facet name
|
||||
*/
|
||||
redirect_info: null,
|
||||
|
||||
/**
|
||||
* Facet requires authenticated user
|
||||
* @type {Boolean}
|
||||
*/
|
||||
requires_auth: true,
|
||||
|
||||
/**
|
||||
* Public state
|
||||
* @property {facet.FacetState}
|
||||
* @protected
|
||||
*/
|
||||
state: null,
|
||||
|
||||
get_full_name: function() {
|
||||
return this.name;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if two objects has the same properties with equal values.
|
||||
*
|
||||
* @param {Object} a
|
||||
* @param {Object} b
|
||||
* @return {boolean} `a` and `b` are value-equal
|
||||
* @protected
|
||||
*/
|
||||
state_diff: function(a, b) {
|
||||
var diff = false;
|
||||
var checked = {};
|
||||
|
||||
var check_diff = function(a, b, skip) {
|
||||
|
||||
var same = true;
|
||||
skip = skip || {};
|
||||
|
||||
for (var key in a) {
|
||||
if (a.hasOwnProperty(key) && !(key in skip)) {
|
||||
var va = a[key];
|
||||
var vb = b[key];
|
||||
if (lang.isArray(va)) {
|
||||
if (IPA.array_diff(va,vb)) {
|
||||
same = false;
|
||||
skip[a] = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (va != vb) {
|
||||
same = false;
|
||||
skip[a] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return !same;
|
||||
};
|
||||
|
||||
diff = check_diff(a,b, checked);
|
||||
diff = diff || check_diff(b,a, checked);
|
||||
return diff;
|
||||
},
|
||||
|
||||
/**
|
||||
* Reset facet state to supplied
|
||||
*
|
||||
* @param {Object} state state to set
|
||||
*/
|
||||
reset_state: function(state) {
|
||||
this.state.reset(state);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get copy of current state
|
||||
*
|
||||
* @return {Object} state
|
||||
*/
|
||||
get_state: function() {
|
||||
return this.state.clone();
|
||||
},
|
||||
|
||||
/**
|
||||
* Merges state into current and notifies it.
|
||||
*
|
||||
* @param {Object} state object to merge into current state
|
||||
*/
|
||||
set_state: function(state) {
|
||||
this.state.set(state);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle state set
|
||||
* @param {Object} old_state
|
||||
* @param {Object} state
|
||||
* @protected
|
||||
*/
|
||||
on_state_set: function(old_state, state) {
|
||||
this.on_state_change(state);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle state change
|
||||
* @param {Object} state
|
||||
* @protected
|
||||
*/
|
||||
on_state_change: function(state) {
|
||||
|
||||
this._notify_state_change(state);
|
||||
},
|
||||
|
||||
/**
|
||||
* Fires `facet-state-change` event with given state as event parameter.
|
||||
*
|
||||
* @fires facet-state-change
|
||||
* @protected
|
||||
* @param {Object} state
|
||||
*/
|
||||
_notify_state_change: function(state) {
|
||||
this.emit('facet-state-change', {
|
||||
facet: this,
|
||||
state: state
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Create facet's HTML representation
|
||||
* NOTE: may be renamed to render
|
||||
*/
|
||||
create: function() {
|
||||
|
||||
if (this.dom_node) {
|
||||
construct.empty(this.dom_node);
|
||||
} else {
|
||||
this.dom_node = construct.create('div', {
|
||||
'class': 'facet',
|
||||
name: this.name,
|
||||
'data-name': this.name
|
||||
});
|
||||
}
|
||||
if (this['class']) {
|
||||
dom_class.add(this.dom_node, this['class']);
|
||||
}
|
||||
if (this.container_node) {
|
||||
construct.place(this.dom_node, this.container_node);
|
||||
}
|
||||
this.children_node = this.dom_node;
|
||||
return this.dom_node;
|
||||
},
|
||||
|
||||
/**
|
||||
* Render child widgets
|
||||
*/
|
||||
render_children: function() {
|
||||
var widgets = this.get_widgets();
|
||||
|
||||
for (var i=0;i<widgets.length; i++) {
|
||||
var widget = widgets[i];
|
||||
var modern = typeof widget.render === 'function';
|
||||
|
||||
if (modern) {
|
||||
widget.container_node = this.children_node;
|
||||
widget.render();
|
||||
} else {
|
||||
var container = $('<div/>').appendTo(this.children_node);
|
||||
widget.create(container);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Show facet
|
||||
*
|
||||
* - mark itself as active facet
|
||||
*/
|
||||
show: function() {
|
||||
|
||||
if (!this.dom_node) {
|
||||
this.create();
|
||||
this.render_children();
|
||||
} else if (!this.dom_node.parentElement) {
|
||||
construct.place(this.dom_node, this.container_node);
|
||||
}
|
||||
|
||||
dom_class.add(this.dom_node, 'active-facet');
|
||||
this.emit('show', { source: this });
|
||||
},
|
||||
|
||||
/**
|
||||
* Un-mark itself as active facet
|
||||
*/
|
||||
hide: function() {
|
||||
if (this.dom_node.parentElement) {
|
||||
this.container_node.removeChild(this.dom_node);
|
||||
}
|
||||
dom_class.remove(this.dom_node, 'active-facet');
|
||||
this.emit('hide', { source: this });
|
||||
},
|
||||
|
||||
/**
|
||||
* Initializes facet
|
||||
*
|
||||
* Facet builder should run this method after instantiation.
|
||||
* @param {Object} spec
|
||||
*/
|
||||
init: function(spec) {
|
||||
|
||||
this.add_widgets(spec.widgets || []);
|
||||
},
|
||||
|
||||
can_leave: function() {
|
||||
return true;
|
||||
},
|
||||
|
||||
show_leave_dialog: function(callback) {
|
||||
window.console.warning('Unimplemented');
|
||||
},
|
||||
|
||||
/** Constructor */
|
||||
constructor: function(spec) {
|
||||
|
||||
this.preferred_container = spec.preferred_container;
|
||||
this.name = spec.name;
|
||||
this.label = text.get(spec.label);
|
||||
this.tab_label = text.get(spec.tab_label || spec.label);
|
||||
this.title = text.get(spec.title || spec.label);
|
||||
this['class'] = spec['class'];
|
||||
this.container_node = spec.container_node;
|
||||
this.dom_node = spec.dom_node;
|
||||
this.redirect_info = spec.redirect_info;
|
||||
if (spec.requires_auth !== undefined) {
|
||||
this.requires_auth = spec.requires_auth;
|
||||
}
|
||||
this.state = new mod_facet.FacetState();
|
||||
on(this.state, 'set', this.on_state_set.bind(this));
|
||||
}
|
||||
});
|
||||
|
||||
return Facet;
|
||||
});
|
||||
260
install/ui/src/freeipa/facets/HeaderMixin.js
Normal file
260
install/ui/src/freeipa/facets/HeaderMixin.js
Normal file
@@ -0,0 +1,260 @@
|
||||
//
|
||||
// Copyright (C) 2015 FreeIPA Contributors see COPYING for license
|
||||
//
|
||||
|
||||
define(['dojo/_base/declare',
|
||||
'dojo/_base/lang',
|
||||
'dojo/on',
|
||||
'dojo/dom-construct',
|
||||
'dojo/dom-class',
|
||||
'../builder',
|
||||
'../facet',
|
||||
'../text',
|
||||
'../widgets/ActionDropdownWidget'
|
||||
],
|
||||
function(declare, lang, on, construct, dom_class,
|
||||
builder, mod_facet, text, ActionDropdownWidget) {
|
||||
|
||||
|
||||
/**
|
||||
* Header Mixin
|
||||
*
|
||||
* Extension of facet - header with title and facet groups. Requires
|
||||
* facets.ActionMixin.
|
||||
*
|
||||
* @class facets.HeaderMixin
|
||||
*/
|
||||
var HeaderMixin = declare([], {
|
||||
|
||||
/**
|
||||
* Facet header
|
||||
* @property {facet.facet_header}
|
||||
*/
|
||||
header: null,
|
||||
|
||||
/**
|
||||
* Facet tabs are not displayed when set.
|
||||
* @property {boolean}
|
||||
*/
|
||||
disable_facet_tabs: false,
|
||||
|
||||
/**
|
||||
* Facet tabs in sidebar
|
||||
*
|
||||
* There is and effort (#4625) to move all facet tabs into sidebar but it
|
||||
* was not user tested, therefore they remain on the old place for the
|
||||
* time being.
|
||||
*
|
||||
* This option should be changed when ^^ is removed.
|
||||
* @property {boolean}
|
||||
*/
|
||||
tabs_in_sidebar: true,
|
||||
|
||||
/**
|
||||
* Array of actions which are displayed in facet header
|
||||
* @property {Array.<string>}
|
||||
*/
|
||||
header_actions: null,
|
||||
|
||||
/**
|
||||
* Facet groups
|
||||
*
|
||||
* @property {IPA.facet_group[]}
|
||||
*/
|
||||
facet_groups: null,
|
||||
|
||||
/**
|
||||
* Facet group name
|
||||
* @property {string}
|
||||
*/
|
||||
facet_group: null,
|
||||
|
||||
|
||||
/**
|
||||
* Create facet's HTML representation
|
||||
* NOTE: may be renamed to render
|
||||
*/
|
||||
create: function() {
|
||||
|
||||
// this create method is Facet.create extended by header/sidebar logic
|
||||
|
||||
if (this.dom_node) {
|
||||
construct.empty(this.dom_node);
|
||||
} else {
|
||||
this.dom_node = construct.create('div', {
|
||||
'class': 'facet',
|
||||
name: this.name,
|
||||
'data-name': this.name
|
||||
});
|
||||
}
|
||||
if (this['class']) {
|
||||
dom_class.add(this.dom_node, this['class']);
|
||||
}
|
||||
if (this.container_node) {
|
||||
construct.place(this.dom_node, this.container_node);
|
||||
}
|
||||
|
||||
var row = $('<div/>', {
|
||||
'class': 'row'
|
||||
}).appendTo(this.dom_node);
|
||||
var content_cont = row;
|
||||
|
||||
this.sidebar_content_el = $('<div/>', {
|
||||
'class': mod_facet.sidebar_content_width
|
||||
}).appendTo(row);
|
||||
content_cont = $('<div/>', {
|
||||
'class': 'row'
|
||||
}).appendTo(this.sidebar_content_el);
|
||||
|
||||
this.sidebar_el = $('<div/>', {
|
||||
'class': mod_facet.sidebar_class + mod_facet.sidebar_width
|
||||
}).appendTo(row);
|
||||
|
||||
this.header_container = $('<div/>', {
|
||||
'class': 'facet-header col-sm-12'
|
||||
}).appendTo(content_cont);
|
||||
this.create_header(this.header_container);
|
||||
|
||||
this.content = $('<div/>', {
|
||||
'class': 'facet-content col-sm-12'
|
||||
}).appendTo(content_cont);
|
||||
|
||||
|
||||
this.children_node = this.content[0];
|
||||
return this.dom_node;
|
||||
},
|
||||
|
||||
/**
|
||||
* Create control buttons
|
||||
*
|
||||
* @param {jQuery} container
|
||||
* @protected
|
||||
*/
|
||||
create_header: function(container) {
|
||||
|
||||
this.header.create(container);
|
||||
|
||||
this.controls = $('<div/>', {
|
||||
'class': 'facet-controls clearfix'
|
||||
}).appendTo(container);
|
||||
|
||||
this.controls_left = $('<div/>', {
|
||||
'class': 'facet-controls-left'
|
||||
}).appendTo(this.controls);
|
||||
|
||||
this.controls_right = $('<div/>', {
|
||||
'class': 'facet-controls-right'
|
||||
}).appendTo(this.controls);
|
||||
|
||||
this.create_controls();
|
||||
},
|
||||
|
||||
/**
|
||||
* Create header controls
|
||||
*
|
||||
* - ie control buttons orActionDropDown
|
||||
*/
|
||||
create_controls: function() {
|
||||
|
||||
this.create_control_buttons(this.controls_left);
|
||||
this.create_action_dropdown(this.controls_left);
|
||||
},
|
||||
|
||||
/**
|
||||
* Create control buttons
|
||||
*
|
||||
* @param {jQuery} container
|
||||
* @protected
|
||||
*/
|
||||
create_control_buttons: function(container) {
|
||||
|
||||
if (this.control_buttons) {
|
||||
this.control_buttons.create(container);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Create action dropdown widget in supplied container
|
||||
*
|
||||
* @param {jQuery} container
|
||||
* @protected
|
||||
*/
|
||||
create_action_dropdown: function(container) {
|
||||
if (this.action_dropdown && this.header_actions && this.header_actions.length > 0) {
|
||||
var dropdown = this.action_dropdown.render();
|
||||
container.append(dropdown);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Display or hide facet tabs - either in sidebar or facet header
|
||||
* @param {boolean} visible
|
||||
*/
|
||||
set_tabs_visible: function(visible) {
|
||||
|
||||
if (this.disable_facet_tabs) return;
|
||||
if (this.tabs_in_sidebar && this.sidebar_el) {
|
||||
var a = visible ? mod_facet.sidebar_content_width : mod_facet.sidebar_content_full_width;
|
||||
var r = visible ? mod_facet.sidebar_content_full_width : mod_facet.sidebar_content_width;
|
||||
this.sidebar_content_el.removeClass(r);
|
||||
this.sidebar_content_el.addClass(a);
|
||||
this.sidebar_el.css('display', visible ? '' : 'none');
|
||||
}
|
||||
this.header.set_tabs_visible(visible);
|
||||
},
|
||||
|
||||
/**
|
||||
* Overrides parent's object(usually facet.Facet) show method. To select a
|
||||
* tab.
|
||||
*/
|
||||
show: function() {
|
||||
this.inherited(arguments);
|
||||
this.header.select_tab();
|
||||
},
|
||||
|
||||
/** Constructor */
|
||||
constructor: function(spec) {
|
||||
|
||||
this.facet_groups = builder.build('', spec.facet_groups, {}, {
|
||||
$factory: mod_facet.facet_group
|
||||
});
|
||||
this.facet_group = spec.facet_group;
|
||||
|
||||
this.header = builder.build(
|
||||
'',
|
||||
spec.header || { init_group_names: true},
|
||||
{},
|
||||
{
|
||||
$pre_ops: [{ facet: this }],
|
||||
$factory: mod_facet.simple_facet_header
|
||||
}
|
||||
);
|
||||
this.header.init();
|
||||
this.header_actions = spec.header_actions || [];
|
||||
|
||||
var buttons_spec = {
|
||||
$factory: mod_facet.control_buttons_widget,
|
||||
name: 'control-buttons',
|
||||
css_class: 'control-buttons',
|
||||
buttons: spec.control_buttons
|
||||
};
|
||||
|
||||
this.control_buttons = builder.build(null, buttons_spec);
|
||||
this.control_buttons.init(this);
|
||||
|
||||
this.action_dropdown = builder.build(null, {
|
||||
$ctor: ActionDropdownWidget,
|
||||
action_names: this.header_actions,
|
||||
name: 'facet_actions',
|
||||
'class': 'dropdown facet-actions',
|
||||
right_aligned: true,
|
||||
toggle_text: text.get('@i18n:actions.title') + ' ',
|
||||
toggle_class: 'btn btn-default',
|
||||
toggle_icon: 'fa fa-angle-down'
|
||||
});
|
||||
this.action_dropdown.init(this);
|
||||
}
|
||||
});
|
||||
|
||||
return HeaderMixin;
|
||||
});
|
||||
1954
install/ui/src/freeipa/field.js
Normal file
1954
install/ui/src/freeipa/field.js
Normal file
File diff suppressed because it is too large
Load Diff
19
install/ui/src/freeipa/freeipa.profile.js
Normal file
19
install/ui/src/freeipa/freeipa.profile.js
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Dojo builder profile file
|
||||
//
|
||||
|
||||
|
||||
var profile = (function(){
|
||||
|
||||
var js_files = /\.js$/;
|
||||
|
||||
return {
|
||||
resourceTags: {
|
||||
|
||||
// all JavaScript files are AMD modules
|
||||
amd: function(filename, mid) {
|
||||
return js_files.test(filename);
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
||||
301
install/ui/src/freeipa/group.js
Normal file
301
install/ui/src/freeipa/group.js
Normal file
@@ -0,0 +1,301 @@
|
||||
/* Authors:
|
||||
* Pavel Zuna <pzuna@redhat.com>
|
||||
* Endi Dewata <edewata@redhat.com>
|
||||
* Adam Young <ayoung@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'dojo/on',
|
||||
'./ipa',
|
||||
'./jquery',
|
||||
'./phases',
|
||||
'./reg',
|
||||
'./details',
|
||||
'./search',
|
||||
'./association',
|
||||
'./entity'],
|
||||
function(on, IPA, $, phases, reg) {
|
||||
|
||||
var exp = IPA.group = {
|
||||
search_facet_group: {
|
||||
name: 'search',
|
||||
label: '@i18n:objects.group.group_categories',
|
||||
facets: {
|
||||
search_group: 'group_search',
|
||||
search_hostgroup: 'hostgroup_search',
|
||||
search_netgroup: 'netgroup_search'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var make_spec = function() {
|
||||
return {
|
||||
name: 'group',
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
tab_label: '@i18n:objects.group.user_groups',
|
||||
facet_groups: [IPA.group.search_facet_group],
|
||||
tabs_in_sidebar: true,
|
||||
disable_facet_tabs: false,
|
||||
columns: [
|
||||
'cn',
|
||||
'gidnumber',
|
||||
'description'
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
sections: [
|
||||
{
|
||||
name: 'details',
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
},
|
||||
{
|
||||
$type: 'value_map',
|
||||
name: 'external',
|
||||
param: 'objectclass',
|
||||
label: '@i18n:objects.group.type',
|
||||
default_label: '@i18n:objects.group.nonposix',
|
||||
value_map: {
|
||||
ipaexternalgroup: '@i18n:objects.group.external',
|
||||
posixgroup: '@i18n:objects.group.posix'
|
||||
}
|
||||
},
|
||||
'gidnumber',
|
||||
{
|
||||
$type: 'link',
|
||||
name: 'pwpolicy',
|
||||
param: 'cn',
|
||||
label: '@mo:pwpolicy.label_singular',
|
||||
other_entity: 'pwpolicy',
|
||||
require_link: true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
actions: [
|
||||
'select',
|
||||
'make_posix',
|
||||
'make_external',
|
||||
'delete'
|
||||
],
|
||||
header_actions: ['make_posix', 'make_external', 'delete'],
|
||||
state: {
|
||||
evaluators: [
|
||||
IPA.object_class_evaluator
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
$type: 'association',
|
||||
name: 'member_user',
|
||||
columns:[
|
||||
'uid',
|
||||
'uidnumber',
|
||||
'mail',
|
||||
'telephonenumber',
|
||||
'title'
|
||||
],
|
||||
adder_columns:[
|
||||
{
|
||||
name: 'uid',
|
||||
primary_key: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'association',
|
||||
name: 'member_group'
|
||||
},
|
||||
{
|
||||
$type: 'attribute',
|
||||
name: 'member_external',
|
||||
attribute: 'ipaexternalmember',
|
||||
tab_label: 'External',
|
||||
facet_group: 'member',
|
||||
columns: [
|
||||
{
|
||||
name: 'ipaexternalmember',
|
||||
label: '@mc-opt:group_add_member:ipaexternalmember:label'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'association',
|
||||
name: 'memberof_group',
|
||||
associator: IPA.serial_associator
|
||||
},
|
||||
{
|
||||
$type: 'association',
|
||||
name: 'memberof_netgroup',
|
||||
associator: IPA.serial_associator
|
||||
},
|
||||
{
|
||||
$type: 'association',
|
||||
name: 'memberof_role',
|
||||
associator: IPA.serial_associator
|
||||
},
|
||||
{
|
||||
$type: 'association',
|
||||
name: 'memberof_hbacrule',
|
||||
associator: IPA.serial_associator,
|
||||
add_method: 'add_user',
|
||||
remove_method: 'remove_user'
|
||||
},
|
||||
{
|
||||
$type: 'association',
|
||||
name: 'memberof_sudorule',
|
||||
associator: IPA.serial_associator,
|
||||
add_method: 'add_user',
|
||||
remove_method: 'remove_user'
|
||||
}
|
||||
],
|
||||
standard_association_facets: true,
|
||||
adder_dialog: {
|
||||
$factory: IPA.group_adder_dialog,
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
},
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'type',
|
||||
label: '@i18n:objects.group.type',
|
||||
flags: ['no_command'],
|
||||
default_value: 'posix',
|
||||
options: [
|
||||
{
|
||||
value: 'nonposix',
|
||||
label: '@i18n:objects.group.nonposix'
|
||||
},
|
||||
{
|
||||
value: 'external',
|
||||
label: '@i18n:objects.group.external'
|
||||
},
|
||||
{
|
||||
value: 'posix',
|
||||
label: '@i18n:objects.group.posix'
|
||||
}
|
||||
]
|
||||
},
|
||||
'gidnumber'
|
||||
]
|
||||
}
|
||||
};};
|
||||
|
||||
IPA.group_adder_dialog = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.entity_adder_dialog(spec);
|
||||
|
||||
var init = function() {
|
||||
|
||||
var type_field = that.fields.get_field('type');
|
||||
on(type_field, 'value-change', that.on_type_change);
|
||||
};
|
||||
|
||||
that.on_type_change = function() {
|
||||
|
||||
var type_field = that.fields.get_field('type');
|
||||
var gid_field = that.fields.get_field('gidnumber');
|
||||
var posix = type_field.get_value()[0] === 'posix';
|
||||
|
||||
if (!posix) {
|
||||
gid_field.reset();
|
||||
}
|
||||
|
||||
gid_field.set_enabled(posix);
|
||||
};
|
||||
|
||||
that.create_add_command = function(record) {
|
||||
|
||||
var command = that.entity_adder_dialog_create_add_command(record);
|
||||
|
||||
var type_field = that.fields.get_field('type');
|
||||
var type = type_field.save()[0];
|
||||
|
||||
if (type === 'nonposix' || type === 'external') {
|
||||
command.set_option(type, true);
|
||||
}
|
||||
|
||||
return command;
|
||||
};
|
||||
|
||||
init();
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.group.make_posix_action = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
spec.name = spec.name || 'make_posix';
|
||||
spec.method = spec.method || 'mod';
|
||||
spec.label = spec.label || '@i18n:objects.group.make_posix';
|
||||
spec.needs_confirm = spec.needs_confirm !== undefined ? spec.needs_confirm : true;
|
||||
spec.disable_cond = spec.disable_cond || ['oc_posixgroup', 'oc_ipaexternalgroup'];
|
||||
spec.options = spec.options || {
|
||||
posix: true
|
||||
};
|
||||
|
||||
var that = IPA.object_action(spec);
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.group.make_external_action = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
spec.name = spec.name || 'make_external';
|
||||
spec.method = spec.method || 'mod';
|
||||
spec.label = spec.label || '@i18n:objects.group.make_external';
|
||||
spec.needs_confirm = spec.needs_confirm !== undefined ? spec.needs_confirm : true;
|
||||
spec.disable_cond = spec.disable_cond || ['oc_posixgroup','oc_ipaexternalgroup'];
|
||||
spec.options = spec.options || {
|
||||
external: true
|
||||
};
|
||||
|
||||
var that = IPA.object_action(spec);
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
exp.entity_spec = make_spec();
|
||||
exp.register = function() {
|
||||
var e = reg.entity;
|
||||
var a = reg.action;
|
||||
|
||||
e.register({ type: 'group', spec: exp.entity_spec });
|
||||
|
||||
a.register('make_posix', exp.make_posix_action);
|
||||
a.register('make_external', exp.make_external_action);
|
||||
};
|
||||
|
||||
phases.on('registration', exp.register);
|
||||
|
||||
return exp;
|
||||
});
|
||||
506
install/ui/src/freeipa/hbac.js
Normal file
506
install/ui/src/freeipa/hbac.js
Normal file
@@ -0,0 +1,506 @@
|
||||
/* Authors:
|
||||
* Endi Sukma Dewata <edewata@redhat.com>
|
||||
* Adam Young <ayoung@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'./ipa',
|
||||
'./jquery',
|
||||
'./phases',
|
||||
'./reg',
|
||||
'./rpc',
|
||||
'./association',
|
||||
'./details',
|
||||
'./entity',
|
||||
'./rule',
|
||||
'./search'
|
||||
],
|
||||
function(IPA, $, phases, reg, rpc) {
|
||||
|
||||
var exp = IPA.hbac = {
|
||||
//priority of commands in details facet
|
||||
remove_method_priority: IPA.config.default_priority - 1
|
||||
};
|
||||
|
||||
var make_rule_spec = function() {
|
||||
var spec = {
|
||||
name: 'hbacrule',
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
row_enabled_attribute: 'ipaenabledflag',
|
||||
columns: [
|
||||
'cn',
|
||||
{
|
||||
name: 'ipaenabledflag',
|
||||
label: '@i18n:status.label',
|
||||
formatter: 'boolean_status'
|
||||
},
|
||||
'description'
|
||||
],
|
||||
actions: [
|
||||
'batch_disable',
|
||||
'batch_enable'
|
||||
],
|
||||
control_buttons: [
|
||||
{
|
||||
name: 'disable',
|
||||
label: '@i18n:buttons.disable',
|
||||
icon: 'fa-minus'
|
||||
},
|
||||
{
|
||||
name: 'enable',
|
||||
label: '@i18n:buttons.enable',
|
||||
icon: 'fa-check'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
$factory: IPA.hbacrule_details_facet,
|
||||
command_mode: 'info',
|
||||
actions: [
|
||||
'select',
|
||||
'enable',
|
||||
'disable',
|
||||
'delete'
|
||||
],
|
||||
header_actions: ['enable', 'disable', 'delete'],
|
||||
state: {
|
||||
evaluators: [
|
||||
{
|
||||
$factory: IPA.enable_state_evaluator,
|
||||
field: 'ipaenabledflag'
|
||||
}
|
||||
],
|
||||
summary_conditions: [
|
||||
IPA.enabled_summary_cond,
|
||||
IPA.disabled_summary_cond
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
adder_dialog: {
|
||||
fields: [ 'cn' ]
|
||||
}
|
||||
};
|
||||
|
||||
add_hbacrule_details_facet_widgets(spec.facets[1]);
|
||||
return spec;
|
||||
};
|
||||
|
||||
var make_service_spec = function() {
|
||||
return {
|
||||
name: 'hbacsvc',
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
columns: [
|
||||
'cn',
|
||||
'description'
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
sections: [
|
||||
{
|
||||
name: 'general',
|
||||
label: '@i18n:details.general',
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'association',
|
||||
name: 'memberof_hbacsvcgroup',
|
||||
associator: IPA.serial_associator,
|
||||
columns:[
|
||||
'cn',
|
||||
'description'
|
||||
],
|
||||
adder_columns: [
|
||||
{
|
||||
name: 'cn',
|
||||
primary_key: true,
|
||||
width: '100px'
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
width: '100px'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
standard_association_facets: true,
|
||||
adder_dialog: {
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
};};
|
||||
|
||||
var make_service_group_spec = function() {
|
||||
return {
|
||||
name: 'hbacsvcgroup',
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
columns: [
|
||||
'cn',
|
||||
'description'
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
sections: [
|
||||
{
|
||||
name: 'general',
|
||||
label: '@i18n:details.general',
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'association',
|
||||
name: 'member_hbacsvc',
|
||||
columns:[
|
||||
'cn',
|
||||
'description'
|
||||
],
|
||||
adder_columns: [
|
||||
{
|
||||
name: 'cn',
|
||||
primary_key: true,
|
||||
width: '100px'
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
width: '100px'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
standard_association_facets: true,
|
||||
adder_dialog: {
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
};};
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
* @param {Object} facet spec
|
||||
*/
|
||||
var add_hbacrule_details_facet_widgets = function (spec) {
|
||||
|
||||
//
|
||||
// General
|
||||
//
|
||||
|
||||
spec.fields = [
|
||||
{
|
||||
name: 'cn',
|
||||
read_only: true,
|
||||
widget: 'general.cn'
|
||||
},
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description',
|
||||
widget: 'general.description'
|
||||
}
|
||||
];
|
||||
|
||||
spec.widgets = [
|
||||
{
|
||||
$type: 'details_section',
|
||||
name: 'general',
|
||||
label: '@i18n:details.general',
|
||||
widgets: [
|
||||
{
|
||||
name: 'cn'
|
||||
},
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
//
|
||||
// Users
|
||||
//
|
||||
|
||||
spec.fields.push(
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'usercategory',
|
||||
widget: 'user.rule.usercategory'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberuser_user',
|
||||
widget: 'user.rule.memberuser_user',
|
||||
priority: IPA.hbac.remove_method_priority
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberuser_group',
|
||||
widget: 'user.rule.memberuser_group',
|
||||
priority: IPA.hbac.remove_method_priority
|
||||
}
|
||||
);
|
||||
|
||||
spec.widgets.push(
|
||||
{
|
||||
$factory: IPA.section,
|
||||
name: 'user',
|
||||
label: '@i18n:objects.hbacrule.user',
|
||||
widgets: [
|
||||
{
|
||||
$factory: IPA.rule_details_widget,
|
||||
name: 'rule',
|
||||
radio_name: 'usercategory',
|
||||
options: [
|
||||
{ value: 'all',
|
||||
label: '@i18n:objects.hbacrule.anyone' },
|
||||
{ value: '',
|
||||
label: '@i18n:objects.hbacrule.specified_users' }
|
||||
],
|
||||
tables: [
|
||||
{ name: 'memberuser_user' },
|
||||
{ name: 'memberuser_group' }
|
||||
],
|
||||
widgets: [
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'hbacrule-memberuser_user',
|
||||
name: 'memberuser_user',
|
||||
add_method: 'add_user',
|
||||
remove_method: 'remove_user',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'hbacrule-memberuser_group',
|
||||
name: 'memberuser_group',
|
||||
add_method: 'add_user',
|
||||
remove_method: 'remove_user',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
//
|
||||
// Hosts
|
||||
//
|
||||
|
||||
spec.fields.push(
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'hostcategory',
|
||||
widget: 'host.rule.hostcategory'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberhost_host',
|
||||
widget: 'host.rule.memberhost_host',
|
||||
priority: IPA.hbac.remove_method_priority
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberhost_hostgroup',
|
||||
widget: 'host.rule.memberhost_hostgroup',
|
||||
priority: IPA.hbac.remove_method_priority
|
||||
}
|
||||
);
|
||||
|
||||
spec.widgets.push(
|
||||
{
|
||||
$factory: IPA.section,
|
||||
name: 'host',
|
||||
label: '@i18n:objects.hbacrule.host',
|
||||
widgets: [
|
||||
{
|
||||
$factory: IPA.rule_details_widget,
|
||||
name: 'rule',
|
||||
radio_name: 'hostcategory',
|
||||
options: [
|
||||
{
|
||||
'value': 'all',
|
||||
'label': '@i18n:objects.hbacrule.any_host'
|
||||
},
|
||||
{
|
||||
'value': '',
|
||||
'label': '@i18n:objects.hbacrule.specified_hosts'
|
||||
}
|
||||
],
|
||||
tables: [
|
||||
{ 'name': 'memberhost_host' },
|
||||
{ 'name': 'memberhost_hostgroup' }
|
||||
],
|
||||
widgets: [
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'hbacrule-memberuser_user',
|
||||
name: 'memberhost_host',
|
||||
add_method: 'add_host',
|
||||
remove_method: 'remove_host',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'hbacrule-memberuser_group',
|
||||
name: 'memberhost_hostgroup',
|
||||
add_method: 'add_host',
|
||||
remove_method: 'remove_host',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
//
|
||||
// Service
|
||||
//
|
||||
|
||||
spec.fields.push(
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'servicecategory',
|
||||
widget: 'service.rule.servicecategory'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberservice_hbacsvc',
|
||||
widget: 'service.rule.memberservice_hbacsvc',
|
||||
priority: IPA.hbac.remove_method_priority
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberservice_hbacsvcgroup',
|
||||
widget: 'service.rule.memberservice_hbacsvcgroup',
|
||||
priority: IPA.hbac.remove_method_priority
|
||||
}
|
||||
);
|
||||
|
||||
spec.widgets.push(
|
||||
{
|
||||
$factory: IPA.section,
|
||||
name: 'service',
|
||||
label: '@i18n:objects.hbacrule.service',
|
||||
widgets: [
|
||||
{
|
||||
$factory: IPA.rule_details_widget,
|
||||
name: 'rule',
|
||||
radio_name: 'servicecategory',
|
||||
options: [
|
||||
{ 'value': 'all', 'label': '@i18n:objects.hbacrule.any_service' },
|
||||
{ 'value': '', 'label': '@i18n:objects.hbacrule.specified_services' }
|
||||
],
|
||||
tables: [
|
||||
{ 'name': 'memberservice_hbacsvc' },
|
||||
{ 'name': 'memberservice_hbacsvcgroup' }
|
||||
],
|
||||
widgets: [
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'hbacrule-memberuser_user',
|
||||
name: 'memberservice_hbacsvc',
|
||||
add_method: 'add_service',
|
||||
remove_method: 'remove_service',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'hbacrule-memberuser_group',
|
||||
name: 'memberservice_hbacsvcgroup',
|
||||
add_method: 'add_service',
|
||||
remove_method: 'remove_service',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
IPA.hbacrule_details_facet = function(spec) {
|
||||
|
||||
var that = IPA.details_facet(spec);
|
||||
|
||||
that.update_on_success = function(data, text_status, xhr) {
|
||||
that.refresh();
|
||||
that.on_update.notify();
|
||||
that.nofify_update_success();
|
||||
};
|
||||
|
||||
that.update_on_error = function(xhr, text_status, error_thrown) {
|
||||
that.refresh();
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
exp.rule_spec = make_rule_spec();
|
||||
exp.svc_spec = make_service_spec();
|
||||
exp.svcgroup_spec = make_service_group_spec();
|
||||
exp.register = function() {
|
||||
var e = reg.entity;
|
||||
e.register({type: 'hbacrule', spec: exp.rule_spec});
|
||||
e.register({type: 'hbacsvc', spec: exp.svc_spec});
|
||||
e.register({type: 'hbacsvcgroup', spec: exp.svcgroup_spec});
|
||||
};
|
||||
phases.on('registration', exp.register);
|
||||
|
||||
return exp;
|
||||
});
|
||||
822
install/ui/src/freeipa/hbactest.js
Normal file
822
install/ui/src/freeipa/hbactest.js
Normal file
@@ -0,0 +1,822 @@
|
||||
/* Authors:
|
||||
* Endi Sukma Dewata <edewata@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'./metadata',
|
||||
'./ipa',
|
||||
'./jquery',
|
||||
'./navigation',
|
||||
'./phases',
|
||||
'./reg',
|
||||
'./rpc',
|
||||
'./text',
|
||||
'./details',
|
||||
'./search',
|
||||
'./association',
|
||||
'./entity',
|
||||
'./hbac'],
|
||||
function(metadata_provider, IPA, $, navigation, phases, reg, rpc, text) {
|
||||
|
||||
var exp = {};
|
||||
|
||||
var make_spec = function() {
|
||||
return {
|
||||
name: 'hbactest',
|
||||
facet_groups: [ 'default' ],
|
||||
facets: [
|
||||
{
|
||||
$factory: IPA.hbac.test_select_facet,
|
||||
name: 'user',
|
||||
label: '@i18n:objects.hbacrule.user',
|
||||
managed_entity: 'user',
|
||||
disable_breadcrumb: true,
|
||||
facet_group: 'default',
|
||||
row_disabled_attribute: 'nsaccountlock',
|
||||
columns: [
|
||||
'uid',
|
||||
'givenname',
|
||||
'sn',
|
||||
{
|
||||
name: 'nsaccountlock',
|
||||
label: '@i18n:status.label',
|
||||
formatter: {
|
||||
$type: 'boolean_status',
|
||||
invert_value: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$factory: IPA.hbac.test_select_facet,
|
||||
name: 'targethost',
|
||||
label: '@i18n:objects.hbacrule.host',
|
||||
managed_entity: 'host',
|
||||
disable_breadcrumb: true,
|
||||
facet_group: 'default',
|
||||
columns: [
|
||||
'fqdn',
|
||||
'description',
|
||||
{
|
||||
name: 'has_keytab',
|
||||
label: '@i18n:objects.host.enrolled',
|
||||
formatter: 'boolean'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$factory: IPA.hbac.test_select_facet,
|
||||
name: 'service',
|
||||
label: '@i18n:objects.hbacrule.service',
|
||||
managed_entity: 'hbacsvc',
|
||||
disable_breadcrumb: true,
|
||||
facet_group: 'default',
|
||||
columns: [
|
||||
'cn',
|
||||
'description'
|
||||
]
|
||||
},
|
||||
{
|
||||
$factory: IPA.hbac.test_rules_facet,
|
||||
name: 'rules',
|
||||
label: '@i18n:objects.hbactest.rules',
|
||||
managed_entity: 'hbacrule',
|
||||
disable_breadcrumb: true,
|
||||
facet_group: 'default',
|
||||
row_enabled_attribute: 'ipaenabledflag',
|
||||
columns: [
|
||||
'cn',
|
||||
{
|
||||
name: 'ipaenabledflag',
|
||||
label: '@i18n:status.label',
|
||||
formatter: 'boolean_status'
|
||||
},
|
||||
'description'
|
||||
]
|
||||
},
|
||||
{
|
||||
$factory: IPA.hbac.test_run_facet,
|
||||
name: 'run_test',
|
||||
label: '@i18n:objects.hbactest.run_test',
|
||||
managed_entity: 'hbacrule',
|
||||
disable_breadcrumb: true,
|
||||
facet_group: 'default',
|
||||
row_enabled_attribute: 'ipaenabledflag',
|
||||
columns: [
|
||||
'cn',
|
||||
{
|
||||
name: 'matched',
|
||||
label: '@i18n:objects.hbactest.matched',
|
||||
formatter: 'boolean'
|
||||
},
|
||||
{
|
||||
name: 'ipaenabledflag',
|
||||
label: '@i18n:status.label',
|
||||
formatter: 'boolean_status'
|
||||
},
|
||||
'description'
|
||||
]
|
||||
}
|
||||
]
|
||||
};};
|
||||
|
||||
IPA.hbac.test_entity = function(spec) {
|
||||
|
||||
var that = IPA.entity(spec);
|
||||
that.label = text.get('@i18n:objects.hbactest.label');
|
||||
|
||||
that.get_default_metadata = function() {
|
||||
return metadata_provider.get('@mc:'+that.name);
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.hbac.test_facet = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.table_facet(spec);
|
||||
|
||||
var init = function() {
|
||||
|
||||
that.managed_entity = IPA.get_entity(that.managed_entity);
|
||||
|
||||
var columns = that.columns.values;
|
||||
for (var i=0; i<columns.length; i++) {
|
||||
var column = columns[i];
|
||||
|
||||
var metadata = IPA.get_entity_param(that.managed_entity.name, column.name);
|
||||
column.primary_key = metadata && metadata.primary_key;
|
||||
column.link = column.primary_key;
|
||||
}
|
||||
|
||||
that.init_table(that.managed_entity);
|
||||
};
|
||||
|
||||
that.create_buttons = function(container) {
|
||||
|
||||
var buttons = $('<div/>', {
|
||||
'class': 'hbac-test-navigation-buttons'
|
||||
}).appendTo(container);
|
||||
|
||||
var facet_group = that.entity.get_facet_group('default');
|
||||
var index = facet_group.get_facet_index(that.name);
|
||||
|
||||
if (index > 0) {
|
||||
that.prev_button = IPA.button({
|
||||
name: 'prev',
|
||||
label: '@i18n:widget.prev',
|
||||
icon: 'fa-chevron-left',
|
||||
click: that.prev
|
||||
}).appendTo(buttons);
|
||||
|
||||
buttons.append(' ');
|
||||
}
|
||||
|
||||
that.next_button = IPA.button({
|
||||
name: 'next',
|
||||
label: '@i18n:widget.next',
|
||||
icon: 'fa-chevron-right',
|
||||
click: that.next
|
||||
}).appendTo(buttons);
|
||||
};
|
||||
|
||||
that.prev = function() {
|
||||
var facet_group = that.entity.get_facet_group('default');
|
||||
var index = facet_group.get_facet_index(that.name);
|
||||
if (index <= 0) return;
|
||||
|
||||
var facet = facet_group.get_facet_by_index(index - 1);
|
||||
|
||||
navigation.show(facet);
|
||||
};
|
||||
|
||||
that.next = function() {
|
||||
var facet_group = that.entity.get_facet_group('default');
|
||||
var index = facet_group.get_facet_index(that.name);
|
||||
if (index >= facet_group.get_facet_count() - 1) return;
|
||||
|
||||
var facet = facet_group.get_facet_by_index(index + 1);
|
||||
|
||||
navigation.show(facet);
|
||||
};
|
||||
|
||||
that.get_search_command_name = function() {
|
||||
return that.managed_entity.name + '_find' + (that.pagination ? '_pkeys' : '');
|
||||
};
|
||||
|
||||
that.refresh = function() {
|
||||
|
||||
var filter = that.state.filter;
|
||||
|
||||
var command = rpc.command({
|
||||
name: that.get_search_command_name(),
|
||||
entity: that.managed_entity.name,
|
||||
method: 'find',
|
||||
args: [filter]
|
||||
});
|
||||
|
||||
if (that.pagination) {
|
||||
command.set_option('pkey_only', true);
|
||||
command.set_option('sizelimit', 0);
|
||||
}
|
||||
|
||||
command.on_success = function(data, text_status, xhr) {
|
||||
that.load(data);
|
||||
that.show_content();
|
||||
};
|
||||
|
||||
command.on_error = function(xhr, text_status, error_thrown) {
|
||||
that.report_error(error_thrown);
|
||||
};
|
||||
|
||||
command.execute();
|
||||
};
|
||||
|
||||
init();
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.hbac.test_select_facet = function(spec) {
|
||||
|
||||
var that = IPA.hbac.test_facet(spec);
|
||||
|
||||
var init = function() {
|
||||
that.table.multivalued = false;
|
||||
|
||||
that.table.set_values = function(values) {
|
||||
if (values && values.length && values[0] === '__external__') {
|
||||
if (that.external_radio) that.external_radio.prop('checked', true);
|
||||
} else {
|
||||
that.table.table_set_values(values);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
that.create_content = function(container) {
|
||||
|
||||
var header = $('<div/>', {
|
||||
'class': 'hbac-test-header'
|
||||
}).appendTo(container);
|
||||
|
||||
var title = $('<span/>', {
|
||||
text: that.label,
|
||||
'class': 'hbac-test-title'
|
||||
}).appendTo(header);
|
||||
|
||||
var filter_container = $('<div/>', {
|
||||
'class': 'search-filter'
|
||||
}).appendTo(header);
|
||||
|
||||
that.filter = $('<input/>', {
|
||||
type: 'text',
|
||||
'class': 'form-control',
|
||||
name: 'filter'
|
||||
}).appendTo(filter_container);
|
||||
|
||||
that.filter.keypress(function(e) {
|
||||
/* if the key pressed is the enter key */
|
||||
if (e.which == 13) {
|
||||
that.find();
|
||||
}
|
||||
});
|
||||
|
||||
that.find_button = IPA.action_button({
|
||||
name: 'find',
|
||||
icon: 'fa-search',
|
||||
click: function() {
|
||||
that.find();
|
||||
return false;
|
||||
}
|
||||
}).appendTo(filter_container);
|
||||
|
||||
var content = $('<div/>', {
|
||||
'class': 'hbac-test-content'
|
||||
}).appendTo(container);
|
||||
|
||||
that.table.create(content);
|
||||
|
||||
var id = that.entity.name+'-'+that.name+'-external';
|
||||
var pkey_name = that.managed_entity.metadata.primary_key;
|
||||
|
||||
var tr = $('<tr/>').appendTo(that.table.tfoot);
|
||||
|
||||
var td = $('<td/>', {
|
||||
name: 'external',
|
||||
colspan: that.columns.length + 1
|
||||
}).appendTo(tr);
|
||||
|
||||
that.external_radio = $('<input/>', {
|
||||
id: id,
|
||||
type: 'radio',
|
||||
name: pkey_name,
|
||||
value: '__external__',
|
||||
click: function() {
|
||||
that.selected_values = [ that.external_radio.val() ];
|
||||
}
|
||||
}).appendTo(td);
|
||||
|
||||
var message = text.get('@i18n:objects.hbactest.specify_external');
|
||||
message = message.replace('${entity}', that.managed_entity.metadata.label_singular);
|
||||
|
||||
$('<label/>', {
|
||||
text: message+':',
|
||||
'for': id
|
||||
}).appendTo(td);
|
||||
|
||||
td.append(' ');
|
||||
|
||||
that.external_text = $('<input/>', {
|
||||
name: id,
|
||||
focus: function() {
|
||||
that.external_radio.click();
|
||||
}
|
||||
}).appendTo(td);
|
||||
|
||||
var footer = $('<div/>', {
|
||||
'class': 'hbac-test-footer'
|
||||
}).appendTo(container);
|
||||
|
||||
that.create_buttons(footer);
|
||||
};
|
||||
|
||||
that.find = function() {
|
||||
|
||||
var old_filter = that.state.filter;
|
||||
var filter = that.filter.val();
|
||||
|
||||
that.set_expired_flag();
|
||||
|
||||
if (old_filter === filter) {
|
||||
that.refresh();
|
||||
} else {
|
||||
that.state.set({filter: filter});
|
||||
}
|
||||
};
|
||||
|
||||
that.get_selected_values = function() {
|
||||
var values = that.table.get_selected_values();
|
||||
if (values && values.length) return values;
|
||||
|
||||
if (that.external_radio && that.external_radio.is(':checked')) {
|
||||
return [ that.external_radio.val() ];
|
||||
}
|
||||
|
||||
return [];
|
||||
};
|
||||
|
||||
that.reset = function() {
|
||||
delete that.selected_values;
|
||||
if (that.external_radio) that.external_radio.prop('checked', false);
|
||||
if (that.external_text) that.external_text.val('');
|
||||
};
|
||||
|
||||
that.save = function(record) {
|
||||
if (that.selected_values && that.selected_values.length) {
|
||||
var value = that.selected_values[0];
|
||||
if (that.external_radio && value === that.external_radio.val()) {
|
||||
record[that.name] = that.external_text.val();
|
||||
} else {
|
||||
record[that.name] = value;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
that.validate = function(record) {
|
||||
if (record[that.name]) return true;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
init();
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.hbac.test_rules_facet = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.hbac.test_facet(spec);
|
||||
|
||||
var init = function() {
|
||||
};
|
||||
|
||||
that.create_content = function(container) {
|
||||
|
||||
var header = $('<div/>', {
|
||||
'class': 'hbac-test-header'
|
||||
}).appendTo(container);
|
||||
|
||||
var title = $('<span/>', {
|
||||
text: that.label,
|
||||
'class': 'hbac-test-title'
|
||||
}).appendTo(header);
|
||||
|
||||
header.append(' ');
|
||||
|
||||
that.enabled = $('<input/>', {
|
||||
id: 'hbactest-rules-include-enabled',
|
||||
type: 'checkbox',
|
||||
name: 'enabled'
|
||||
}).appendTo(header);
|
||||
|
||||
$('<label/>', {
|
||||
'for': 'hbactest-rules-include-enabled',
|
||||
text: text.get('@i18n:objects.hbactest.include_enabled')
|
||||
}).appendTo(header);
|
||||
|
||||
that.disabled = $('<input/>', {
|
||||
id: 'hbactest-rules-include-disabled',
|
||||
type: 'checkbox',
|
||||
name: 'disabled'
|
||||
}).appendTo(header);
|
||||
|
||||
$('<label/>', {
|
||||
'for': 'hbactest-rules-include-disabled',
|
||||
text: text.get('@i18n:objects.hbactest.include_disabled')
|
||||
}).appendTo(header);
|
||||
|
||||
var content = $('<div/>', {
|
||||
'class': 'hbac-test-content'
|
||||
}).appendTo(container);
|
||||
|
||||
that.table.create(content);
|
||||
|
||||
var footer = $('<div/>', {
|
||||
'class': 'hbac-test-footer'
|
||||
}).appendTo(container);
|
||||
|
||||
that.create_buttons(footer);
|
||||
};
|
||||
|
||||
that.get_selected_values = function() {
|
||||
return that.table.get_selected_values();
|
||||
};
|
||||
|
||||
that.reset = function() {
|
||||
delete that.selected_values;
|
||||
if (that.enabled) that.enabled.prop('checked', false);
|
||||
if (that.disabled) that.disabled.prop('checked', false);
|
||||
};
|
||||
|
||||
that.save = function(record) {
|
||||
if (that.selected_values && that.selected_values.length) {
|
||||
record[that.name] = that.selected_values;
|
||||
}
|
||||
if (that.enabled && that.enabled.is(':checked')) {
|
||||
record['enabled'] = true;
|
||||
}
|
||||
if (that.disabled && that.disabled.is(':checked')) {
|
||||
record['disabled'] = true;
|
||||
}
|
||||
};
|
||||
|
||||
init();
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.hbac.test_run_facet = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.hbac.test_facet(spec);
|
||||
|
||||
var init = function() {
|
||||
that.table.selectable = false;
|
||||
that.show_matched = true;
|
||||
that.show_unmatched = true;
|
||||
};
|
||||
|
||||
that.create_content = function(container) {
|
||||
|
||||
var header = $('<div/>', {
|
||||
'class': 'hbac-test-header'
|
||||
}).appendTo(container);
|
||||
|
||||
var top_panel = $('<div/>', {
|
||||
'class': 'hbac-test-top-panel row'
|
||||
}).appendTo(header);
|
||||
|
||||
var button_panel = $('<div/>', {
|
||||
'class': 'hbac-test-button-panel col-sm-2'
|
||||
}).appendTo(top_panel);
|
||||
|
||||
that.run_button = IPA.button({
|
||||
name: 'run_test',
|
||||
label: '@i18n:objects.hbactest.run_test',
|
||||
icon: 'fa-gear',
|
||||
click: that.run
|
||||
}).appendTo(button_panel);
|
||||
|
||||
var result_panel = $('<div/>', {
|
||||
'class': 'hbac-test-result-panel col-sm-10'
|
||||
}).appendTo(top_panel);
|
||||
|
||||
that.test_result = $('<p/>', {
|
||||
'class': 'hbac-test-title'
|
||||
}).appendTo(result_panel);
|
||||
|
||||
var title = $('<span/>', {
|
||||
text: text.get('@i18n:objects.hbactest.rules'),
|
||||
'class': 'hbac-test-title'
|
||||
}).appendTo(header);
|
||||
|
||||
header.append(' ');
|
||||
|
||||
that.matched_checkbox = $('<input/>', {
|
||||
id: 'hbactest-rules-matched',
|
||||
type: 'checkbox',
|
||||
name: 'matched',
|
||||
checked: true,
|
||||
change: function() {
|
||||
that.show_matched = that.matched_checkbox.is(':checked');
|
||||
that.refresh();
|
||||
}
|
||||
}).appendTo(header);
|
||||
|
||||
$('<label/>', {
|
||||
'for': 'hbactest-rules-matched',
|
||||
text: text.get('@i18n:objects.hbactest.matched')
|
||||
}).appendTo(header);
|
||||
|
||||
that.unmatched_checkbox = $('<input/>', {
|
||||
id: 'hbactest-rules-unmatched',
|
||||
type: 'checkbox',
|
||||
name: 'unmatched',
|
||||
checked: true,
|
||||
change: function() {
|
||||
that.show_unmatched = that.unmatched_checkbox.is(':checked');
|
||||
that.refresh();
|
||||
}
|
||||
}).appendTo(header);
|
||||
|
||||
$('<label/>', {
|
||||
'for': 'hbactest-rules-unmatched',
|
||||
text: text.get('@i18n:objects.hbactest.unmatched')
|
||||
}).appendTo(header);
|
||||
|
||||
var content = $('<div/>', {
|
||||
'class': 'hbac-test-content'
|
||||
}).appendTo(container);
|
||||
|
||||
that.table.create(content);
|
||||
|
||||
var footer = $('<div/>', {
|
||||
'class': 'hbac-test-footer'
|
||||
}).appendTo(container);
|
||||
|
||||
var buttons = $('<div/>', {
|
||||
'class': 'hbac-test-navigation-buttons'
|
||||
}).appendTo(footer);
|
||||
|
||||
that.prev_button = IPA.button({
|
||||
name: 'prev',
|
||||
label: '@i18n:widget.prev',
|
||||
icon: 'fa-chevron-left',
|
||||
click: that.prev
|
||||
}).appendTo(buttons);
|
||||
|
||||
buttons.append(' ');
|
||||
|
||||
that.new_test_button = IPA.button({
|
||||
name: 'new_test',
|
||||
label: '@i18n:objects.hbactest.new_test',
|
||||
icon: 'fa-repeat',
|
||||
click: that.new_test
|
||||
}).appendTo(buttons);
|
||||
};
|
||||
|
||||
that.new_test = function() {
|
||||
var facet = that.entity.get_facet('user');
|
||||
facet.reset();
|
||||
var entry_point = facet;
|
||||
|
||||
facet = that.entity.get_facet('targethost');
|
||||
facet.reset();
|
||||
|
||||
facet = that.entity.get_facet('service');
|
||||
facet.reset();
|
||||
|
||||
facet = that.entity.get_facet('rules');
|
||||
facet.reset();
|
||||
|
||||
facet = that.entity.get_facet('run_test');
|
||||
facet.reset();
|
||||
|
||||
navigation.show(entry_point);
|
||||
};
|
||||
|
||||
that.reset = function() {
|
||||
delete that.data;
|
||||
that.show_matched = true;
|
||||
that.show_unmatched = true;
|
||||
if (that.matched_checkbox) that.matched_checkbox.prop('checked', true);
|
||||
if (that.unmatched_checkbox) that.unmatched_checkbox.prop('checked', true);
|
||||
that.refresh();
|
||||
};
|
||||
|
||||
that.refresh = function() {
|
||||
if (that.data) {
|
||||
var message = that.data.result.value ?
|
||||
text.get('@i18n:objects.hbactest.access_granted') :
|
||||
text.get('@i18n:objects.hbactest.access_denied');
|
||||
that.test_result.text(message);
|
||||
|
||||
} else {
|
||||
that.test_result.text('');
|
||||
}
|
||||
|
||||
that.load(that.data);
|
||||
};
|
||||
|
||||
that.run = function() {
|
||||
|
||||
var command = rpc.command({ method: 'hbactest' });
|
||||
|
||||
var options = {};
|
||||
var validation_results = {
|
||||
valid: true,
|
||||
invalid_facets: []
|
||||
};
|
||||
|
||||
var facet = that.entity.get_facet('user');
|
||||
facet.save(options);
|
||||
that.validate_facet(facet, options, validation_results);
|
||||
|
||||
facet = that.entity.get_facet('targethost');
|
||||
facet.save(options);
|
||||
that.validate_facet(facet, options, validation_results);
|
||||
|
||||
facet = that.entity.get_facet('service');
|
||||
facet.save(options);
|
||||
that.validate_facet(facet, options, validation_results);
|
||||
|
||||
if (!validation_results.valid) {
|
||||
var dialog = IPA.hbac.validation_dialog({
|
||||
validation_results: validation_results
|
||||
});
|
||||
dialog.open();
|
||||
return;
|
||||
}
|
||||
|
||||
facet = that.entity.get_facet('rules');
|
||||
facet.save(options);
|
||||
|
||||
command.set_options(options);
|
||||
|
||||
command.on_success = function(data, text_status, xhr) {
|
||||
that.data = data;
|
||||
that.refresh();
|
||||
};
|
||||
|
||||
command.execute();
|
||||
};
|
||||
|
||||
that.validate_facet = function(facet, options, validation_results) {
|
||||
|
||||
var facet_valid = facet.validate(options);
|
||||
|
||||
validation_results.valid = facet_valid && validation_results.valid;
|
||||
|
||||
if (!facet_valid) {
|
||||
validation_results.invalid_facets.push(facet);
|
||||
}
|
||||
};
|
||||
|
||||
that.get_records_map = function(data) {
|
||||
|
||||
var records_map = $.ordered_map();
|
||||
var pkeys_map = $.ordered_map();
|
||||
|
||||
var matched = data.result.matched;
|
||||
if (that.show_matched && matched) {
|
||||
for (var i=0; i<matched.length; i++) {
|
||||
var pkey = matched[i];
|
||||
var compound_pkey = pkey + i;
|
||||
records_map.put(compound_pkey, { matched: true });
|
||||
pkeys_map.put(compound_pkey, pkey);
|
||||
}
|
||||
}
|
||||
|
||||
var notmatched = data.result.notmatched;
|
||||
if (that.show_unmatched && notmatched) {
|
||||
for (i=0; i<notmatched.length; i++) {
|
||||
pkey = notmatched[i];
|
||||
compound_pkey = pkey + i;
|
||||
records_map.put(compound_pkey, { matched: false });
|
||||
pkeys_map.put(compound_pkey, pkey);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
records_map: records_map,
|
||||
pkeys_map: pkeys_map
|
||||
};
|
||||
};
|
||||
|
||||
that.get_records_command_name = function() {
|
||||
if (that.show_matched && !that.show_unmatched) {
|
||||
return 'hbactest_matched';
|
||||
}
|
||||
if (!that.show_matched && that.show_unmatched) {
|
||||
return 'hbactest_unmatched';
|
||||
}
|
||||
return that.managed_entity.name+'_get_records';
|
||||
};
|
||||
|
||||
init();
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.hbac.validation_dialog = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
spec.title = spec.title || '@i18n:dialogs.validation_title';
|
||||
spec.message = spec.message || '@i18n:dialogs.validation_message';
|
||||
|
||||
var that = IPA.message_dialog(spec);
|
||||
|
||||
that.validation_results = spec.validation_results;
|
||||
|
||||
that.create_content = function() {
|
||||
|
||||
if (that.message) {
|
||||
that.message_dialog_create_content();
|
||||
}
|
||||
|
||||
if (that.validation_results && that.validation_results.invalid_facets) {
|
||||
var invalid_facets = that.validation_results.invalid_facets;
|
||||
|
||||
var ul;
|
||||
|
||||
if (invalid_facets.length > 0) {
|
||||
var div = $('<div/>',{
|
||||
text: text.get('@i18n:objects.hbactest.missing_values')
|
||||
}).appendTo(that.container);
|
||||
ul = $('<ul/>').appendTo(that.container);
|
||||
}
|
||||
|
||||
for (var i=0; i<invalid_facets.length; i++) {
|
||||
|
||||
var facet = invalid_facets[i];
|
||||
|
||||
var li = $('<li />').appendTo(ul);
|
||||
|
||||
var metadata = IPA.get_command_option('hbactest', facet.name);
|
||||
|
||||
$('<a />', {
|
||||
href: '#'+facet.name,
|
||||
text: metadata.label,
|
||||
click: function(facet) {
|
||||
return function() {
|
||||
that.redirect_to_facet(facet);
|
||||
return false;
|
||||
};
|
||||
}(facet)
|
||||
}).appendTo(li);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
that.redirect_to_facet = function(facet) {
|
||||
that.close();
|
||||
navigation.show(facet);
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
exp.entity_spec = make_spec();
|
||||
exp.register = function() {
|
||||
var e = reg.entity;
|
||||
e.register({
|
||||
type: 'hbactest',
|
||||
factory: IPA.hbac.test_entity,
|
||||
spec: exp.entity_spec
|
||||
});
|
||||
};
|
||||
phases.on('registration', exp.register);
|
||||
|
||||
return exp;
|
||||
});
|
||||
1133
install/ui/src/freeipa/host.js
Normal file
1133
install/ui/src/freeipa/host.js
Normal file
File diff suppressed because it is too large
Load Diff
112
install/ui/src/freeipa/hostgroup.js
Normal file
112
install/ui/src/freeipa/hostgroup.js
Normal file
@@ -0,0 +1,112 @@
|
||||
/* Authors:
|
||||
* Pavel Zuna <pzuna@redhat.com>
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'./ipa',
|
||||
'./jquery',
|
||||
'./phases',
|
||||
'./reg',
|
||||
'./details',
|
||||
'./search',
|
||||
'./association',
|
||||
'./entity'],
|
||||
function(IPA, $, phases, reg) {
|
||||
|
||||
var exp = IPA.hostgroup = {};
|
||||
|
||||
var make_spec = function() {
|
||||
return {
|
||||
name: 'hostgroup',
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
tab_label: '@i18n:objects.hostgroup.host_group',
|
||||
facet_groups: [IPA.group.search_facet_group],
|
||||
tabs_in_sidebar: true,
|
||||
disable_facet_tabs: false,
|
||||
columns: [
|
||||
'cn',
|
||||
'description'
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
sections: [
|
||||
{
|
||||
name: 'identity',
|
||||
label: '@i18n:objects.hostgroup.identity',
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'association',
|
||||
name: 'memberof_hostgroup',
|
||||
associator: IPA.serial_associator
|
||||
},
|
||||
{
|
||||
$type: 'association',
|
||||
name: 'memberof_netgroup',
|
||||
associator: IPA.serial_associator
|
||||
},
|
||||
{
|
||||
$type: 'association',
|
||||
name: 'memberof_hbacrule',
|
||||
associator: IPA.serial_associator,
|
||||
add_method: 'add_host',
|
||||
remove_method: 'remove_host'
|
||||
},
|
||||
{
|
||||
$type: 'association',
|
||||
name: 'memberof_sudorule',
|
||||
associator: IPA.serial_associator,
|
||||
add_method: 'add_host',
|
||||
remove_method: 'remove_host'
|
||||
}
|
||||
],
|
||||
standard_association_facets: true,
|
||||
adder_dialog: {
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
};};
|
||||
|
||||
|
||||
exp.entity_spec = make_spec();
|
||||
exp.register = function() {
|
||||
var e = reg.entity;
|
||||
e.register({type: 'hostgroup', spec: exp.entity_spec});
|
||||
};
|
||||
phases.on('registration', exp.register);
|
||||
|
||||
return exp;
|
||||
});
|
||||
282
install/ui/src/freeipa/idrange.js
Normal file
282
install/ui/src/freeipa/idrange.js
Normal file
@@ -0,0 +1,282 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'dojo/on',
|
||||
'./ipa',
|
||||
'./jquery',
|
||||
'./phases',
|
||||
'./reg',
|
||||
'./details',
|
||||
'./search',
|
||||
'./association',
|
||||
'./entity'],
|
||||
function(on, IPA, $, phases, reg) {
|
||||
|
||||
var exp = IPA.idrange = {};
|
||||
|
||||
var make_spec = function() {
|
||||
return {
|
||||
name: 'idrange',
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
columns: [
|
||||
'cn',
|
||||
'ipabaseid',
|
||||
'ipaidrangesize',
|
||||
'iparangetype'
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
sections: [
|
||||
{
|
||||
name: 'details',
|
||||
fields: [
|
||||
'cn',
|
||||
'iparangetype',
|
||||
{
|
||||
name: 'iparangetyperaw',
|
||||
read_only: true,
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
name: 'ipabaseid',
|
||||
label: '@i18n:objects.idrange.ipabaseid',
|
||||
title: '@mo-param:idrange:ipabaseid:label'
|
||||
},
|
||||
{
|
||||
name: 'ipaidrangesize',
|
||||
label: '@i18n:objects.idrange.ipaidrangesize',
|
||||
title: '@mo-param:idrange:ipaidrangesize:label'
|
||||
},
|
||||
{
|
||||
name: 'ipabaserid',
|
||||
label: '@i18n:objects.idrange.ipabaserid',
|
||||
title: '@mo-param:idrange:ipabaserid:label'
|
||||
},
|
||||
{
|
||||
name: 'ipasecondarybaserid',
|
||||
label: '@i18n:objects.idrange.ipasecondarybaserid',
|
||||
title: '@mo-param:idrange:ipasecondarybaserid:label'
|
||||
},
|
||||
{
|
||||
name: 'ipanttrusteddomainsid',
|
||||
label: '@i18n:objects.idrange.ipanttrusteddomainsid',
|
||||
title: '@mo-param:idrange:ipanttrusteddomainsid:label'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
policies: [
|
||||
exp.idrange_policy
|
||||
]
|
||||
}
|
||||
],
|
||||
adder_dialog: {
|
||||
fields: [
|
||||
{
|
||||
name: 'cn'
|
||||
},
|
||||
{
|
||||
name: 'iparangetype',
|
||||
$type: 'radio',
|
||||
label: '@i18n:objects.idrange.type',
|
||||
layout: 'vertical',
|
||||
default_value: 'ipa-local',
|
||||
options: [
|
||||
{
|
||||
value: 'ipa-local',
|
||||
label: '@i18n:objects.idrange.type_local'
|
||||
},
|
||||
{
|
||||
value: 'ipa-ad-trust',
|
||||
label: '@i18n:objects.idrange.type_ad'
|
||||
},
|
||||
{
|
||||
value: 'ipa-ad-trust-posix',
|
||||
label: '@i18n:objects.idrange.type_ad_posix'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'ipabaseid',
|
||||
label: '@i18n:objects.idrange.ipabaseid',
|
||||
title: '@mo-param:idrange:ipabaseid:label'
|
||||
},
|
||||
{
|
||||
name: 'ipaidrangesize',
|
||||
label: '@i18n:objects.idrange.ipaidrangesize',
|
||||
title: '@mo-param:idrange:ipaidrangesize:label'
|
||||
},
|
||||
{
|
||||
name: 'ipabaserid',
|
||||
label: '@i18n:objects.idrange.ipabaserid',
|
||||
title: '@mo-param:idrange:ipabaserid:label'
|
||||
},
|
||||
{
|
||||
name: 'ipasecondarybaserid',
|
||||
label: '@i18n:objects.idrange.ipasecondarybaserid',
|
||||
title: '@mo-param:idrange:ipasecondarybaserid:label'
|
||||
},
|
||||
{
|
||||
name: 'ipanttrusteddomainname',
|
||||
enabled: false
|
||||
}
|
||||
],
|
||||
policies: [
|
||||
IPA.idrange_adder_policy
|
||||
]
|
||||
}
|
||||
};};
|
||||
|
||||
IPA.idrange_adder_policy = function(spec) {
|
||||
/*
|
||||
The logic for enabling/requiring ipabaserid, ipasecondarybaserid and
|
||||
ipanttrusteddomainname is as follows:
|
||||
1) for AD ranges (range type is ipa-ad-trust or ipa-ad-trust-posix):
|
||||
* ipanttrusteddomainname is required
|
||||
* ipabaserid is required for ipa-ad-trust but disabled for
|
||||
ipa-ad-trust-posix
|
||||
* ipasecondarybaserid is disabled
|
||||
2) for local ranges
|
||||
* ipanttrusteddomainname is disabled
|
||||
A) if server has AD trust support:
|
||||
* both ipabaserid and ipasecondarybaserid are required
|
||||
B) if server does not have AD trust support:
|
||||
* ipabaserid and ipasecondarybaserid may only be used together
|
||||
(if one is set, other is required and vice versa)
|
||||
*/
|
||||
|
||||
function require(field) {
|
||||
field.set_enabled(true);
|
||||
field.set_required(true);
|
||||
}
|
||||
|
||||
function disable(field) {
|
||||
field.set_value(['']); // avoid usage of reset() to break event handler loop
|
||||
field.set_required(false);
|
||||
field.set_enabled(false);
|
||||
}
|
||||
|
||||
function enable(field) {
|
||||
field.set_enabled(true);
|
||||
field.set_required(false);
|
||||
}
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.facet_policy(spec);
|
||||
|
||||
that.init = function() {
|
||||
var type_f = that.container.fields.get_field('iparangetype');
|
||||
var baserid_f = that.container.fields.get_field('ipabaserid');
|
||||
var secondarybaserid_f = that.container.fields.get_field('ipasecondarybaserid');
|
||||
|
||||
if (IPA.trust_enabled) {
|
||||
require(baserid_f);
|
||||
require(secondarybaserid_f);
|
||||
}
|
||||
|
||||
on(type_f, 'value-change', that.on_input_change);
|
||||
on(baserid_f, 'value-change', that.on_input_change);
|
||||
on(secondarybaserid_f, 'value-change', that.on_input_change);
|
||||
};
|
||||
|
||||
that.on_input_change = function() {
|
||||
var type_f = that.container.fields.get_field('iparangetype');
|
||||
var baserid_f = that.container.fields.get_field('ipabaserid');
|
||||
var secondarybaserid_f = that.container.fields.get_field('ipasecondarybaserid');
|
||||
var trusteddomainname_f = that.container.fields.get_field('ipanttrusteddomainname');
|
||||
|
||||
var type_v = type_f.get_value()[0];
|
||||
var baserid_v = baserid_f.get_value()[0] || '';
|
||||
var secondarybaserid_v = secondarybaserid_f.get_value()[0] || '';
|
||||
|
||||
var is_ad_range = (type_v === 'ipa-ad-trust' || type_v === 'ipa-ad-trust-posix');
|
||||
|
||||
if (is_ad_range) {
|
||||
if (type_v === 'ipa-ad-trust') {
|
||||
require(baserid_f);
|
||||
} else {
|
||||
disable(baserid_f);
|
||||
}
|
||||
require(trusteddomainname_f);
|
||||
disable(secondarybaserid_f);
|
||||
} else {
|
||||
disable(trusteddomainname_f);
|
||||
|
||||
if (IPA.trust_enabled) {
|
||||
require(baserid_f);
|
||||
require(secondarybaserid_f);
|
||||
} else {
|
||||
if (baserid_v || secondarybaserid_v) {
|
||||
require(baserid_f);
|
||||
require(secondarybaserid_f);
|
||||
} else {
|
||||
enable(baserid_f);
|
||||
enable(secondarybaserid_f);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
exp.idrange_policy = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
var that = IPA.facet_policy(spec);
|
||||
|
||||
that.post_load = function() {
|
||||
var type_f = that.container.fields.get_field('iparangetyperaw');
|
||||
var widgets = that.container.widgets;
|
||||
var type_v = type_f.get_value()[0];
|
||||
|
||||
var baserid = true;
|
||||
var secrid = true;
|
||||
var sid = true;
|
||||
|
||||
if (type_v === 'ipa-local') {
|
||||
sid = false;
|
||||
} else if (type_v === 'ipa-ad-trust-posix') {
|
||||
baserid = secrid = false;
|
||||
} else if (type_v === 'ipa-ad-trust') {
|
||||
secrid = false;
|
||||
}
|
||||
|
||||
widgets.get_widget('details.ipabaserid').set_visible(baserid);
|
||||
widgets.get_widget('details.ipasecondarybaserid').set_visible(secrid);
|
||||
widgets.get_widget('details.ipanttrusteddomainsid').set_visible(sid);
|
||||
};
|
||||
return that;
|
||||
};
|
||||
|
||||
exp.entity_spec = make_spec();
|
||||
exp.register = function() {
|
||||
var e = reg.entity;
|
||||
e.register({type: 'idrange', spec: exp.entity_spec});
|
||||
};
|
||||
phases.on('registration', exp.register);
|
||||
|
||||
return {};
|
||||
});
|
||||
989
install/ui/src/freeipa/idviews.js
Normal file
989
install/ui/src/freeipa/idviews.js
Normal file
@@ -0,0 +1,989 @@
|
||||
/*
|
||||
* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2014 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'dojo/on',
|
||||
'./ipa',
|
||||
'./builder',
|
||||
'./jquery',
|
||||
'./menu',
|
||||
'./phases',
|
||||
'./reg',
|
||||
'./rpc',
|
||||
'./text',
|
||||
'./details',
|
||||
'./facet',
|
||||
'./search',
|
||||
'./entity'],
|
||||
function(on, IPA, builder, $, menu, phases, reg, rpc, text,
|
||||
mod_details, mod_facet) {
|
||||
/**
|
||||
* ID Views module
|
||||
* @class
|
||||
* @singleton
|
||||
*/
|
||||
var idviews = IPA.idviews = {
|
||||
DEFAULT_TRUST_VIEW: 'Default Trust View'
|
||||
};
|
||||
|
||||
var make_spec = function() {
|
||||
return {
|
||||
name: 'idview',
|
||||
enable_test: function() {
|
||||
return true;
|
||||
},
|
||||
facet_groups: [
|
||||
{
|
||||
name: 'overrides',
|
||||
label: '@i18n:objects.idview.overrides_tab'
|
||||
},
|
||||
{
|
||||
name: 'appliedto',
|
||||
label: '@i18n:objects.idview.appliesto_tab'
|
||||
},
|
||||
'settings'
|
||||
],
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
columns: [
|
||||
'cn',
|
||||
'description'
|
||||
],
|
||||
actions: [
|
||||
'idview_unapply_host',
|
||||
'idview_unapply_hostgroups'
|
||||
],
|
||||
control_buttons: [
|
||||
{
|
||||
name: 'idview_unapply_host',
|
||||
label: '@i18n:objects.idview.unapply_hosts_all',
|
||||
icon: 'fa-trash-o'
|
||||
},
|
||||
{
|
||||
name: 'idview_unapply_hostgroups',
|
||||
label: '@i18n:objects.idview.unapply_hostgroups',
|
||||
icon: 'fa-trash-o'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
header: idviews.idview_facet_header,
|
||||
actions: [
|
||||
'delete'
|
||||
],
|
||||
header_actions: ['delete'],
|
||||
state: {
|
||||
},
|
||||
sections: [
|
||||
{
|
||||
name: 'details',
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
name: 'ipadomainresolutionorder',
|
||||
flags: ['w_if_no_aci'],
|
||||
tooltip: '@mc-opt:idview_mod:ipadomainresolutionorder:doc'
|
||||
},
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'nested_search',
|
||||
facet_group: 'overrides',
|
||||
header: idviews.idview_facet_header,
|
||||
nested_entity: 'idoverrideuser',
|
||||
search_all_entries: true,
|
||||
label: '@mo:idoverrideuser.label',
|
||||
tab_label: '@mo:user.label',
|
||||
name: 'idoverrideuser',
|
||||
columns: [
|
||||
{
|
||||
name: 'ipaanchoruuid',
|
||||
label: '@i18n:objects.idoverrideuser.anchor_label'
|
||||
},
|
||||
'uid',
|
||||
'uidnumber',
|
||||
'homedirectory',
|
||||
'description'
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'nested_search',
|
||||
facet_group: 'overrides',
|
||||
header: idviews.idview_facet_header,
|
||||
nested_entity: 'idoverridegroup',
|
||||
search_all_entries: true,
|
||||
label: '@mo:idoverridegroup.label',
|
||||
tab_label: '@mo:group.label',
|
||||
name: 'idoverridegroup',
|
||||
columns: [
|
||||
{
|
||||
name: 'ipaanchoruuid',
|
||||
label: '@i18n:objects.idoverridegroup.anchor_label'
|
||||
},
|
||||
'cn',
|
||||
'gidnumber',
|
||||
'description'
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'idview_appliedtohosts',
|
||||
name: 'appliedtohosts',
|
||||
attribute: 'appliedtohosts',
|
||||
tab_label: '@mo:host.label',
|
||||
facet_group: 'appliedto',
|
||||
actions: [
|
||||
'idview_apply',
|
||||
'idview_apply_hostgroups',
|
||||
'idview_unapply',
|
||||
'idview_unapply_hostgroups'
|
||||
],
|
||||
control_buttons: [
|
||||
{
|
||||
name: 'idview_unapply',
|
||||
label: '@i18n:objects.idview.unapply_hosts',
|
||||
icon: 'fa-trash-o'
|
||||
},
|
||||
{
|
||||
name: 'idview_unapply_hostgroups',
|
||||
label: '@i18n:objects.idview.unapply_hostgroups',
|
||||
icon: 'fa-trash-o'
|
||||
},
|
||||
{
|
||||
name: 'idview_apply',
|
||||
label: '@i18n:objects.idview.apply_hosts',
|
||||
icon: 'fa-plus'
|
||||
},
|
||||
{
|
||||
name: 'idview_apply_hostgroups',
|
||||
label: '@i18n:objects.idview.apply_hostgroups',
|
||||
icon: 'fa-plus'
|
||||
}
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
name: 'appliedtohosts',
|
||||
label: '@mo:host.label_singular',
|
||||
link: true,
|
||||
target_entity: 'host',
|
||||
target_facet: 'details'
|
||||
}
|
||||
],
|
||||
state: {
|
||||
evaluators: [
|
||||
{
|
||||
$factory: mod_details.value_state_evaluator,
|
||||
attribute: 'cn',
|
||||
value: idviews.DEFAULT_TRUST_VIEW,
|
||||
representation: 'cn_default_trust_view'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
adder_dialog: {
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
};};
|
||||
|
||||
var make_idoverrideuser_spec = function() {
|
||||
return {
|
||||
name: 'idoverrideuser',
|
||||
enable_test: function() {
|
||||
return true;
|
||||
},
|
||||
policies:[
|
||||
{
|
||||
$factory: IPA.facet_update_policy,
|
||||
source_facet: 'details',
|
||||
dest_entity: 'idview',
|
||||
dest_facet: 'idoverrideuser'
|
||||
},
|
||||
{
|
||||
$factory: IPA.cert.cert_update_policy,
|
||||
source_facet: 'details',
|
||||
dest_entity: 'cert',
|
||||
dest_facet: 'search'
|
||||
}
|
||||
],
|
||||
containing_entity: 'idview',
|
||||
facets: [
|
||||
{
|
||||
$factory: idviews.id_override_user_details_facet,
|
||||
$type: 'details',
|
||||
disable_breadcrumb: false,
|
||||
containing_facet: 'idoverrideuser',
|
||||
actions: [
|
||||
'delete'
|
||||
],
|
||||
header_actions: ['delete'],
|
||||
state: {
|
||||
},
|
||||
sections: [
|
||||
{
|
||||
name: 'details',
|
||||
fields: [
|
||||
{
|
||||
$type: 'link',
|
||||
name: 'ipaanchoruuid',
|
||||
label: '@i18n:objects.idoverrideuser.anchor_label',
|
||||
other_entity: 'user'
|
||||
},
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
},
|
||||
'uid',
|
||||
'gecos',
|
||||
'uidnumber',
|
||||
'gidnumber',
|
||||
'loginshell',
|
||||
'homedirectory',
|
||||
{
|
||||
$type: 'sshkeys',
|
||||
name: 'ipasshpubkey',
|
||||
label: '@i18n:objects.sshkeystore.keys'
|
||||
},
|
||||
{
|
||||
$type: 'idviews_certs',
|
||||
name: 'usercertificate',
|
||||
label: '@i18n:objects.cert.certificates'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
adder_dialog: {
|
||||
policies: [
|
||||
{ $factory: idviews.idoverride_adder_policy }
|
||||
],
|
||||
fields: [
|
||||
{
|
||||
$type: 'entity_select',
|
||||
label: '@i18n:objects.idoverrideuser.anchor_label',
|
||||
name: 'ipaanchoruuid',
|
||||
other_entity: 'user',
|
||||
other_field: 'uid',
|
||||
editable: true,
|
||||
tooltip: '@i18n:objects.idoverrideuser.anchor_tooltip'
|
||||
},
|
||||
{
|
||||
label: '@i18n:objects.idoverrideuser.anchor_label',
|
||||
name: 'ipaanchoruuid_default',
|
||||
param: 'ipaanchoruuid',
|
||||
tooltip: '@i18n:objects.idoverrideuser.anchor_tooltip_ad',
|
||||
visible: false,
|
||||
enabled: false
|
||||
},
|
||||
'uid',
|
||||
'gecos',
|
||||
'uidnumber',
|
||||
'gidnumber',
|
||||
{
|
||||
$type: 'cert_textarea',
|
||||
name: 'usercertificate'
|
||||
},
|
||||
'loginshell',
|
||||
'homedirectory',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
};};
|
||||
|
||||
var make_idoverridegroup_spec = function() {
|
||||
return {
|
||||
name: 'idoverridegroup',
|
||||
enable_test: function() {
|
||||
return true;
|
||||
},
|
||||
policies:[
|
||||
{
|
||||
$factory: IPA.facet_update_policy,
|
||||
source_facet: 'details',
|
||||
dest_entity: 'idview',
|
||||
dest_facet: 'idoverridegroup'
|
||||
}
|
||||
],
|
||||
containing_entity: 'idview',
|
||||
facets: [
|
||||
{
|
||||
$type: 'details',
|
||||
disable_breadcrumb: false,
|
||||
containing_facet: 'idoverridegroup',
|
||||
actions: [
|
||||
'delete'
|
||||
],
|
||||
header_actions: ['delete'],
|
||||
state: {
|
||||
},
|
||||
sections: [
|
||||
{
|
||||
name: 'details',
|
||||
fields: [
|
||||
{
|
||||
$type: 'link',
|
||||
name: 'ipaanchoruuid',
|
||||
label: '@i18n:objects.idoverridegroup.anchor_label',
|
||||
other_entity: 'group'
|
||||
},
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
},
|
||||
'cn',
|
||||
'gidnumber'
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
adder_dialog: {
|
||||
policies: [
|
||||
{ $factory: idviews.idoverride_adder_policy }
|
||||
],
|
||||
fields: [
|
||||
{
|
||||
$type: 'entity_select',
|
||||
label: '@i18n:objects.idoverridegroup.anchor_label',
|
||||
name: 'ipaanchoruuid',
|
||||
other_entity: 'group',
|
||||
other_field: 'cn',
|
||||
editable: true,
|
||||
tooltip: '@i18n:objects.idoverridegroup.anchor_tooltip'
|
||||
},
|
||||
{
|
||||
label: '@i18n:objects.idoverridegroup.anchor_label',
|
||||
name: 'ipaanchoruuid_default',
|
||||
param: 'ipaanchoruuid',
|
||||
tooltip: '@i18n:objects.idoverridegroup.anchor_tooltip_ad',
|
||||
visible: false,
|
||||
enabled: false
|
||||
},
|
||||
'cn',
|
||||
'gidnumber',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
};};
|
||||
|
||||
|
||||
/**
|
||||
* Facet for User ID override, uses batch command to fetch certificates.
|
||||
*
|
||||
* @class
|
||||
* @extends IPA.details_facet
|
||||
*/
|
||||
idviews.id_override_user_details_facet = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.details_facet(spec);
|
||||
|
||||
that.certificate_updated = IPA.observer();
|
||||
|
||||
that.create_refresh_command = function() {
|
||||
|
||||
var user_command = that.details_facet_create_refresh_command();
|
||||
|
||||
var batch = rpc.batch_command({
|
||||
name: that.entity.name + "_details_refresh"
|
||||
});
|
||||
|
||||
batch.add_command(user_command);
|
||||
|
||||
var pkey = that.get_pkey();
|
||||
|
||||
var certs = rpc.command({
|
||||
entity: 'cert',
|
||||
method: 'find',
|
||||
retry: false,
|
||||
options: {
|
||||
idoverrideuser: [ pkey ],
|
||||
sizelimit: 0,
|
||||
all: true
|
||||
}
|
||||
});
|
||||
|
||||
batch.add_command(certs);
|
||||
|
||||
return batch;
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
|
||||
idviews.aduser_idoverrideuser_pre_op = function(spec, context) {
|
||||
spec = spec || [];
|
||||
|
||||
if (!IPA.is_aduser_selfservice) return spec;
|
||||
|
||||
var facet = spec.facets[0];
|
||||
facet.label = '@i18n:objects.idoverrideuser.profile';
|
||||
facet.actions = [];
|
||||
facet.header_actions = [];
|
||||
facet.disable_breadcrumb = true;
|
||||
|
||||
return spec;
|
||||
};
|
||||
|
||||
/**
|
||||
* @extends IPA.cert.certs_widget
|
||||
*/
|
||||
idviews.idviews_certs_widget = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
spec.child_spec = {
|
||||
$factory: idviews.idviews_cert_widget,
|
||||
css_class: 'certificate-widget',
|
||||
facet: spec.facet
|
||||
};
|
||||
|
||||
var that = IPA.cert.certs_widget(spec);
|
||||
|
||||
/* Adds two args to add command - special nested entities. */
|
||||
that.create_add_args = function() {
|
||||
return that.facet.get_pkeys();
|
||||
};
|
||||
|
||||
/* Adds two args to remove command - special nested entities. */
|
||||
that.create_remove_args = function() {
|
||||
return that.facet.get_pkeys();
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* This widget uses cert_find instead of cert_show, because cert_show does not
|
||||
* support nested entities.
|
||||
*
|
||||
* @extends IPA.cert.cert_widget
|
||||
*/
|
||||
idviews.idviews_cert_widget = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.cert.cert_widget(spec);
|
||||
|
||||
that.adapter = builder.build('adapter', spec.adapter || 'object_adapter', {});
|
||||
|
||||
that.fetch_certificate_data = function(cert) {
|
||||
var result = {};
|
||||
var adapter = that.adapter;
|
||||
|
||||
if (!cert) return;
|
||||
|
||||
var command = rpc.command({
|
||||
entity: 'cert',
|
||||
method: 'find',
|
||||
options: {
|
||||
certificate: cert,
|
||||
all: true
|
||||
},
|
||||
hide_activity_icon: true,
|
||||
on_success: function(data) {
|
||||
var normalized_data = adapter.load(data);
|
||||
that.certificate = $.extend(normalized_data[0], {});
|
||||
that.update_displayed_data();
|
||||
that.spinner.emit('hide-spinner');
|
||||
},
|
||||
on_error: function() {
|
||||
that.update_displayed_data();
|
||||
that.spinner.emit('hide-spinner');
|
||||
}
|
||||
}).execute();
|
||||
};
|
||||
|
||||
that.update = function(values) {
|
||||
that.spinner.emit('display-spinner');
|
||||
|
||||
var certificate = values[0];
|
||||
|
||||
that.fetch_certificate_data(certificate);
|
||||
};
|
||||
|
||||
that.save = function() {
|
||||
if (!that.certificate) return '';
|
||||
return that.certificate.certificate;
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
idviews.cert_textarea_widget = function(spec) {
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.textarea_widget(spec);
|
||||
|
||||
that.save = function() {
|
||||
var value = that.input.val();
|
||||
var blob = IPA.cert.get_base64(value);
|
||||
|
||||
return [blob];
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* Facet for hosts which have current id view applied on
|
||||
*
|
||||
* @class idviews.appliedtohosts_facet
|
||||
* @extends IPA.attribute_facet
|
||||
*/
|
||||
idviews.appliedtohosts_facet = function(spec, no_init) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.attribute_facet(spec, no_init);
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
that.get_refresh_command = function() {
|
||||
var command = that.attribute_get_refresh_command();
|
||||
command.set_option('show_hosts', true);
|
||||
return command;
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
idviews.idview_facet_header = function(spec) {
|
||||
|
||||
var that = mod_facet.facet_header(spec);
|
||||
|
||||
/**
|
||||
* Set pkeys and hides 'appliedtohosts' facet for 'Default Trust View'
|
||||
* @param {string} value pkey
|
||||
*/
|
||||
that.set_pkey = function(value) {
|
||||
|
||||
that.facet_header_set_pkey(value);
|
||||
var display = value === idviews.DEFAULT_TRUST_VIEW ? 'none' : '';
|
||||
$('.facet-group[name="appliedto"]', that.facet_tabs).
|
||||
css('display', display);
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* Switches between combobox and textbox for ipaanchoruuid, depending on if
|
||||
* current view is Default Trust View
|
||||
* @class idviews.idoverride_adder_policy
|
||||
* @extends IPA.facet_policy
|
||||
*/
|
||||
idviews.idoverride_adder_policy = function (spec) {
|
||||
var that = IPA.facet_policy(spec);
|
||||
that.init = function() {
|
||||
on(that.container, 'open', that.on_open);
|
||||
};
|
||||
|
||||
that.on_open = function() {
|
||||
var d = that.container; // dialog
|
||||
var default_view = d.pkey_prefix.slice(-1)[0] === idviews.DEFAULT_TRUST_VIEW;
|
||||
var f1 = d.fields.get_field('ipaanchoruuid');
|
||||
var f2 = d.fields.get_field('ipaanchoruuid_default');
|
||||
f1.set_enabled(!default_view);
|
||||
f1.widget.set_visible(!default_view);
|
||||
f2.set_enabled(default_view);
|
||||
f2.widget.set_visible(default_view);
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* Apply Id view on hosts on hostgroup action base class
|
||||
*
|
||||
* @class idviews.apply_action
|
||||
* @extends IPA.action
|
||||
*/
|
||||
idviews.apply_action = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
spec.name = spec.name || 'idview_apply';
|
||||
spec.label = spec.label || '@i18n:objects.idview.apply_hosts';
|
||||
spec.hide_cond = spec.hide_cond || ['cn_default_trust_view'];
|
||||
|
||||
var that = IPA.action(spec);
|
||||
|
||||
/**
|
||||
* Confirm button label
|
||||
* @property {string}
|
||||
*/
|
||||
that.confirm_button_label = spec.confirm_button_label || '@i18n:buttons.apply';
|
||||
|
||||
/**
|
||||
* Entity to apply
|
||||
* @property {entity.entity|string}
|
||||
*/
|
||||
that.other_entity = spec.other_entity || 'host';
|
||||
|
||||
/**
|
||||
* Dialog title
|
||||
* @property {string}
|
||||
*/
|
||||
that.dialog_title = spec.dialog_title || '@i18n:objects.idview.apply_hosts_title';
|
||||
|
||||
/**
|
||||
* Method
|
||||
* @property {string}
|
||||
*/
|
||||
that.method = spec.method || 'apply';
|
||||
|
||||
/**
|
||||
* Success message
|
||||
* @property {string}
|
||||
*/
|
||||
that.success_msg = spec.success_msg || '@i18n:association.added';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
that.execute_action = function(facet, on_success, on_error) {
|
||||
|
||||
that.show_dialog(facet);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create and open dialog
|
||||
*/
|
||||
that.show_dialog = function(facet) {
|
||||
|
||||
var pkey = facet.get_pkey();
|
||||
var other_entity = reg.entity.get(that.other_entity);
|
||||
var other_entity_label = other_entity.metadata.label;
|
||||
var exclude = that.get_exclude(facet);
|
||||
var title = text.get(that.dialog_title);
|
||||
title = title.replace('${entity}', other_entity_label);
|
||||
title = title.replace('${primary_key}', pkey);
|
||||
|
||||
var dialog = IPA.association_adder_dialog({
|
||||
title: title,
|
||||
entity: facet.entity,
|
||||
pkey: pkey,
|
||||
other_entity: other_entity,
|
||||
attribute_member: that.attribute_member,
|
||||
exclude: exclude,
|
||||
add_button_label: that.confirm_button_label
|
||||
});
|
||||
|
||||
dialog.execute = function() {
|
||||
var values = dialog.get_selected_values();
|
||||
var command = that.get_command(
|
||||
facet,
|
||||
values,
|
||||
function(data) {
|
||||
that.notify_change(facet);
|
||||
dialog.close();
|
||||
var succeeded = IPA.get_succeeded(data);
|
||||
var msg = text.get(that.success_msg).replace('${count}', succeeded);
|
||||
IPA.notify_success(msg);
|
||||
},
|
||||
function() {
|
||||
that.notify_change(facet);
|
||||
dialog.close();
|
||||
});
|
||||
command.execute();
|
||||
return command;
|
||||
};
|
||||
|
||||
dialog.open();
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct action command
|
||||
*/
|
||||
that.get_command = function(facet, values, on_success, on_error) {
|
||||
var other_entity = reg.entity.get(that.other_entity);
|
||||
var pkey = facet.get_pkey();
|
||||
var args = pkey ? [pkey] : [];
|
||||
var command = rpc.command({
|
||||
entity: 'idview',
|
||||
method: that.method,
|
||||
args: args,
|
||||
options: {},
|
||||
on_success: on_success,
|
||||
on_error: on_error
|
||||
});
|
||||
|
||||
command.set_option(other_entity.name, values);
|
||||
return command;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get pkeys which should be excluded from offered pkeys in the dialog
|
||||
*
|
||||
* By default it works only for 'host' of 'appliedtohosts' facet since
|
||||
* other facets might contain completely different values or might have
|
||||
* different API.
|
||||
*
|
||||
* @param {facet.facet} facet
|
||||
* @return {string[]}
|
||||
*/
|
||||
that.get_exclude = function(facet) {
|
||||
if (facet && facet.name === 'appliedtohosts' &&
|
||||
that.other_entity === 'host') {
|
||||
var records = facet.get_records_map(facet.data);
|
||||
return records.keys;
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
/**
|
||||
* Notify idview.appliedtohosts facet that there were possible changes
|
||||
* and a refresh is needed.
|
||||
*/
|
||||
that.notify_change = function(current_facet) {
|
||||
|
||||
if (current_facet && current_facet.name === 'appliedtohosts') {
|
||||
current_facet.refresh();
|
||||
} else {
|
||||
reg.entity.get('idview').
|
||||
get_facet('appliedtohosts').
|
||||
set_expired_flag();
|
||||
}
|
||||
};
|
||||
|
||||
that.apply_action_get_command = that.get_command;
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Apply Id view on hosts of a hostgroup
|
||||
*
|
||||
* @class idviews.apply_hostgroup_action
|
||||
* @extends idviews.apply_action
|
||||
*/
|
||||
idviews.apply_hostgroups_action = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
spec.name = spec.name || 'idview_apply_hostgroups';
|
||||
spec.label = spec.label || '@i18n:objects.idview.apply_hostgroups';
|
||||
spec.other_entity = spec.other_entity || 'hostgroup';
|
||||
spec.dialog_title = spec.dialog_title || '@i18n:objects.idview.apply_hostgroups_title';
|
||||
|
||||
var that = idviews.apply_action(spec);
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* Unapply Id view from hosts
|
||||
*
|
||||
* @class idviews.unapply_host_action
|
||||
* @extends idviews.apply_action
|
||||
*/
|
||||
idviews.unapply_host_action = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
spec.name = spec.name || 'idview_unapply_host';
|
||||
spec.label = spec.label || '@i18n:objects.idview.unapply_hosts_all';
|
||||
spec.other_entity = spec.other_entity || 'host';
|
||||
spec.method = spec.method || 'unapply';
|
||||
spec.dialog_title = spec.dialog_title || '@i18n:objects.idview.unapply_hosts_all_title';
|
||||
spec.confirm_button_label = spec.confirm_button_label || '@i18n:buttons.unapply';
|
||||
spec.success_msg = spec.success_msg || '@i18n:association.removed';
|
||||
|
||||
var that = idviews.apply_action(spec);
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
that.get_command = function(facet, values, on_success, on_error) {
|
||||
var command = that.apply_action_get_command(facet, values, on_success, on_error);
|
||||
// idview_unapply doesn't support primary keys to narrow down idviews
|
||||
// to un-apply yet
|
||||
command.args = [];
|
||||
return command;
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* Unapply Id view from all hosts of a hostgroup
|
||||
*
|
||||
* @class idviews.unapply_hostgroups_action
|
||||
* @extends idviews.unapply_host_action
|
||||
*/
|
||||
idviews.unapply_hostgroups_action = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
spec.name = spec.name || 'idview_unapply_hostgroups';
|
||||
spec.label = spec.label || '@i18n:objects.idview.unapply_hostgroups';
|
||||
spec.other_entity = spec.other_entity || 'hostgroup';
|
||||
spec.dialog_title = spec.dialog_title || '@i18n:objects.idview.unapply_hostgroups_all_title';
|
||||
|
||||
var that = idviews.unapply_host_action(spec);
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* Unapply Id view from selected hosts
|
||||
*
|
||||
* @class idviews.unapply_action
|
||||
* @extends idviews.unapply_host_action
|
||||
*/
|
||||
idviews.unapply_action = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
spec.name = spec.name || 'idview_unapply';
|
||||
spec.label = spec.label || '@i18n:objects.idview.unapply_hosts';
|
||||
spec.enable_cond = spec.enable_cond || ['item-selected'];
|
||||
spec.enabled = spec.enabled === undefined ? false : spec.enabled;
|
||||
spec.confirm_button_label = spec.confirm_button_label || '@i18n:buttons.unapply';
|
||||
spec.method = spec.method || 'unapply';
|
||||
spec.dialog_title = spec.dialog_title || '@i18n:objects.idview.unapply_hosts_title';
|
||||
|
||||
var that = idviews.unapply_host_action(spec);
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
that.show_dialog = function(facet, current_pkeys) {
|
||||
|
||||
var selected_values = facet.get_selected_values();
|
||||
|
||||
if (!selected_values.length) {
|
||||
var message = text.get('@i18n:dialogs.remove_empty');
|
||||
IPA.notify(message, 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
var pkey = facet.get_pkey();
|
||||
var other_entity = reg.entity.get('host');
|
||||
var title = text.get(that.dialog_title);
|
||||
title = title.replace('${primary_key}', pkey);
|
||||
|
||||
var dialog = IPA.association_deleter_dialog({
|
||||
title: title,
|
||||
entity: facet.entity,
|
||||
pkey: pkey,
|
||||
other_entity: other_entity,
|
||||
values: selected_values,
|
||||
method: that.method,
|
||||
ok_label: that.confirm_button_label,
|
||||
message: '@i18n:objects.idview.unapply_hosts_confirm'
|
||||
});
|
||||
|
||||
dialog.execute = function() {
|
||||
var command = that.get_command(
|
||||
facet,
|
||||
selected_values,
|
||||
function(data) {
|
||||
that.notify_change(facet);
|
||||
var succeeded = IPA.get_succeeded(data);
|
||||
var msg = text.get('@i18n:association.removed').replace('${count}', succeeded);
|
||||
IPA.notify_success(msg);
|
||||
},
|
||||
function() {
|
||||
that.notify_change(facet);
|
||||
}
|
||||
);
|
||||
command.execute();
|
||||
};
|
||||
|
||||
dialog.open();
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* ID View entity specification object
|
||||
* @member idviews
|
||||
*/
|
||||
idviews.spec = make_spec();
|
||||
|
||||
/**
|
||||
* ID user override entity specification object
|
||||
* @member idviews
|
||||
*/
|
||||
idviews.idoverrideuser_spec = make_idoverrideuser_spec();
|
||||
|
||||
/**
|
||||
* ID group override entity specification object
|
||||
* @member idviews
|
||||
*/
|
||||
idviews.idoverridegroup_spec = make_idoverridegroup_spec();
|
||||
|
||||
/**
|
||||
* Register entity
|
||||
* @member idviews
|
||||
*/
|
||||
idviews.register = function() {
|
||||
var e = reg.entity;
|
||||
var f = reg.facet;
|
||||
var a = reg.action;
|
||||
var w = reg.widget;
|
||||
|
||||
e.register({type: 'idview', spec: idviews.spec});
|
||||
e.register({
|
||||
type: 'idoverrideuser',
|
||||
spec: idviews.idoverrideuser_spec,
|
||||
pre_ops: [idviews.aduser_idoverrideuser_pre_op]
|
||||
});
|
||||
e.register({type: 'idoverridegroup', spec: idviews.idoverridegroup_spec});
|
||||
f.copy('attribute', 'idview_appliedtohosts', {
|
||||
factory: idviews.appliedtohosts_facet
|
||||
});
|
||||
a.register('idview_apply', idviews.apply_action);
|
||||
a.register('idview_apply_hostgroups', idviews.apply_hostgroups_action);
|
||||
a.register('idview_unapply', idviews.unapply_action);
|
||||
a.register('idview_unapply_host', idviews.unapply_host_action);
|
||||
a.register('idview_unapply_hostgroups', idviews.unapply_hostgroups_action);
|
||||
|
||||
w.register('idviews_certs', idviews.idviews_certs_widget);
|
||||
w.register('cert_textarea', idviews.cert_textarea_widget);
|
||||
};
|
||||
|
||||
phases.on('registration', idviews.register);
|
||||
|
||||
return idviews;
|
||||
});
|
||||
1251
install/ui/src/freeipa/ipa.js
Normal file
1251
install/ui/src/freeipa/ipa.js
Normal file
File diff suppressed because it is too large
Load Diff
95
install/ui/src/freeipa/jquery.js
vendored
Normal file
95
install/ui/src/freeipa/jquery.js
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//
|
||||
// AMD Wrapper for jQuery
|
||||
//
|
||||
define(function() {
|
||||
|
||||
$ = jQuery;
|
||||
|
||||
//
|
||||
// Following code taken from jQuery UI library, MIT license, see
|
||||
// README-LICENSES.txt
|
||||
//
|
||||
|
||||
$.fn.extend({
|
||||
focus: (function( orig ) {
|
||||
return function( delay, fn ) {
|
||||
return typeof delay === "number" ?
|
||||
this.each(function() {
|
||||
var elem = this;
|
||||
window.setTimeout(function() {
|
||||
$( elem ).focus();
|
||||
if ( fn ) {
|
||||
fn.call( elem );
|
||||
}
|
||||
}, delay );
|
||||
}) :
|
||||
orig.apply( this, arguments );
|
||||
};
|
||||
})( $.fn.focus )
|
||||
});
|
||||
|
||||
// selectors
|
||||
function focusable( element, isTabIndexNotNaN ) {
|
||||
var map, mapName, img,
|
||||
nodeName = element.nodeName.toLowerCase();
|
||||
if ( "area" === nodeName ) {
|
||||
map = element.parentNode;
|
||||
mapName = map.name;
|
||||
if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
|
||||
return false;
|
||||
}
|
||||
img = $( "img[usemap=#" + mapName + "]" )[0];
|
||||
return !!img && visible( img );
|
||||
}
|
||||
return ( /input|select|textarea|button|object/.test( nodeName ) ?
|
||||
!element.disabled :
|
||||
"a" === nodeName ?
|
||||
element.href || isTabIndexNotNaN :
|
||||
isTabIndexNotNaN) &&
|
||||
// the element and all of its ancestors must be visible
|
||||
visible( element );
|
||||
}
|
||||
|
||||
function visible( element ) {
|
||||
return $.expr.filters.visible( element ) &&
|
||||
!$( element ).parents().addBack().filter(function() {
|
||||
return $.css( this, "visibility" ) === "hidden";
|
||||
}).length;
|
||||
}
|
||||
|
||||
$.extend( $.expr[ ":" ], {
|
||||
|
||||
focusable: function( element ) {
|
||||
return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
|
||||
},
|
||||
|
||||
tabbable: function( element ) {
|
||||
var tabIndex = $.attr( element, "tabindex" ),
|
||||
isTabIndexNaN = isNaN( tabIndex );
|
||||
return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return $;
|
||||
});
|
||||
27
install/ui/src/freeipa/json2.js
Normal file
27
install/ui/src/freeipa/json2.js
Normal file
@@ -0,0 +1,27 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//
|
||||
// AMD Wrapper for json2 library
|
||||
//
|
||||
|
||||
define(function() {
|
||||
return JSON;
|
||||
});
|
||||
107
install/ui/src/freeipa/menu.js
Normal file
107
install/ui/src/freeipa/menu.js
Normal file
@@ -0,0 +1,107 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
define([
|
||||
'dojo/_base/lang',
|
||||
'./app_container',
|
||||
'./ipa',
|
||||
'exports' // for handling circular dependency
|
||||
],
|
||||
function(lang, app_container, IPA, exports) {
|
||||
|
||||
|
||||
var get_menu = function() {
|
||||
return app_container.app.menu;
|
||||
},
|
||||
|
||||
/**
|
||||
* Menu proxy.
|
||||
*
|
||||
* Exports public interface for dealing with menu items.
|
||||
* @class menu
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds menu item.
|
||||
* Takes a spec of menu item.
|
||||
* Normalizes item's name, parent, adds children if specified
|
||||
*
|
||||
* @method add_item
|
||||
* @param {navigation.MenuItem} item
|
||||
* @param {string|navigation.MenuItem} parent
|
||||
* @param {Object} options
|
||||
*/
|
||||
add_item = function(item, parent, options) {
|
||||
var menu = get_menu();
|
||||
return menu.add_item(item, parent, options);
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes menu item
|
||||
*
|
||||
* @method remove_item
|
||||
* @param {string|navigation.MenuItem} name or menu item to remove
|
||||
*/
|
||||
remove_item = function(item) {
|
||||
|
||||
var menu = get_menu();
|
||||
return menu.items.remove(item);
|
||||
},
|
||||
|
||||
/**
|
||||
* Query internal data store by using default search options or supplied
|
||||
* search options.
|
||||
*
|
||||
* @method query
|
||||
* @param {Object} query
|
||||
* @param {Object} [search_options] Search options, overrides default
|
||||
* @return {QueryResult}
|
||||
*/
|
||||
query = function(query, search_options) {
|
||||
|
||||
var menu = get_menu();
|
||||
|
||||
if (search_options) {
|
||||
return menu.items.query(query, search_options);
|
||||
} else {
|
||||
return menu.query(query);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get current instance of menu
|
||||
* @method get
|
||||
* @return {navigation.Menu}
|
||||
*/
|
||||
get = function() {
|
||||
return get_menu();
|
||||
};
|
||||
|
||||
// Module export
|
||||
exports = {
|
||||
add_item: add_item,
|
||||
remove_item: remove_item,
|
||||
query: query,
|
||||
get: get
|
||||
};
|
||||
|
||||
return exports;
|
||||
});
|
||||
81
install/ui/src/freeipa/metadata.js
Normal file
81
install/ui/src/freeipa/metadata.js
Normal file
@@ -0,0 +1,81 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'dojo/_base/lang',
|
||||
'./_base/Provider',
|
||||
'./_base/Search_provider'
|
||||
], function(lang, Provider, Search_provider) {
|
||||
|
||||
/**
|
||||
* Metadata provider
|
||||
*
|
||||
* Contains multiple providers for specific metadata searches:
|
||||
*
|
||||
* - `@m:`: provider for whole metadata
|
||||
* - `@mo:`: provider for objects (entities)
|
||||
* - `@mc:`: provider for commands
|
||||
* - `@mo-param:`: search provider for object params
|
||||
* - `@mc-arg:`: search provider for command arguments
|
||||
* - `@mc-opt:`: search provider for command options
|
||||
*
|
||||
* @class metadata
|
||||
* @singleton
|
||||
* @extends _base.Provider
|
||||
*/
|
||||
var metadata = new Provider({
|
||||
code: '@m:'
|
||||
});
|
||||
var objects = new Provider({
|
||||
code: '@mo:',
|
||||
source: metadata,
|
||||
path: 'objects'
|
||||
});
|
||||
var commands = new Provider({
|
||||
code: '@mc:',
|
||||
source: metadata,
|
||||
path: 'commands'
|
||||
});
|
||||
var object_param = new Search_provider({
|
||||
code: '@mo-param:',
|
||||
source: metadata,
|
||||
path: 'objects',
|
||||
base_query: '%1.takes_params',
|
||||
array_attr: 'name'
|
||||
});
|
||||
var cmd_arg = new Search_provider({
|
||||
code: '@mc-arg:',
|
||||
source: metadata,
|
||||
path: 'commands',
|
||||
base_query: '%1.takes_args',
|
||||
array_attr: 'name'
|
||||
});
|
||||
var cmd_option = new Search_provider({
|
||||
code: '@mc-opt:',
|
||||
source: metadata,
|
||||
path: 'commands',
|
||||
base_query: '%1.takes_options',
|
||||
array_attr: 'name'
|
||||
});
|
||||
|
||||
metadata.providers.push(objects, commands, object_param, cmd_arg, cmd_option);
|
||||
|
||||
return metadata;
|
||||
});
|
||||
162
install/ui/src/freeipa/navigation.js
Normal file
162
install/ui/src/freeipa/navigation.js
Normal file
@@ -0,0 +1,162 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
define([
|
||||
'dojo/_base/lang',
|
||||
'./navigation/routing'
|
||||
],
|
||||
function(lang, routing) {
|
||||
|
||||
|
||||
var navigation = {
|
||||
/**
|
||||
* Navigation tells application to show certain facet.
|
||||
*
|
||||
* It's proxy for navigation/Router instance in current running
|
||||
* application.
|
||||
*
|
||||
* Modules just use the interface, they don't have to care about the logic in
|
||||
* the background.
|
||||
* @class navigation
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets property of params depending on arg type following way:
|
||||
* for String sets params.facet
|
||||
* for Facet sets params.facet (based on show function)
|
||||
* for Object sets params.args
|
||||
* for Array sets params.pkeys
|
||||
* @ignore
|
||||
* @param Object params
|
||||
* @param {Object|facet.facet|string|Function} arg
|
||||
*/
|
||||
set_params: function(params, arg) {
|
||||
if (lang.isArray(arg)) {
|
||||
params.pkeys = arg;
|
||||
} else if (typeof arg === 'object') {
|
||||
|
||||
if (typeof arg.show === 'function') params.facet = arg;
|
||||
else params.args = arg;
|
||||
} else if (typeof arg === 'string') {
|
||||
params.facet = arg;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Show facet.
|
||||
*
|
||||
* Takes 3 arguments:
|
||||
* * facet(String or Facet)
|
||||
* * pkeys (Array)
|
||||
* * args (Object)
|
||||
*
|
||||
* Argument order is not defined. They are recognized based on their
|
||||
* type.
|
||||
*
|
||||
* When facet is defined as a string it has to be registered in
|
||||
* facet register.
|
||||
*
|
||||
* When it's an object (Facet) and has an entity set it will be
|
||||
* dealt as entity facet.
|
||||
* @method show
|
||||
* @param {Object|facet.facet|string|Function} arg1
|
||||
* @param {Object|facet.facet|string|Function} arg2
|
||||
* @param {Object|facet.facet|string|Function} arg3
|
||||
*/
|
||||
show: function(arg1, arg2, arg3) {
|
||||
|
||||
var params = {};
|
||||
|
||||
this.set_params(params, arg1);
|
||||
this.set_params(params, arg2);
|
||||
this.set_params(params, arg3);
|
||||
|
||||
var facet = params.facet;
|
||||
|
||||
if (typeof facet === 'string') {
|
||||
return routing.navigate(['generic', facet, params.args]);
|
||||
}
|
||||
|
||||
if (!facet) throw 'Argument exception: missing facet';
|
||||
|
||||
if (facet && facet.entity) {
|
||||
return routing.navigate([
|
||||
'entity',
|
||||
facet.entity.name,
|
||||
facet.name,
|
||||
params.pkeys,
|
||||
params.args]);
|
||||
} else {
|
||||
return routing.navigate(['generic', facet.name, params.args]);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Show entity facet
|
||||
*
|
||||
* arg1,arg2,arg3 are:
|
||||
* facet name as String
|
||||
* pkeys as Array
|
||||
* args as Object
|
||||
* @method show_entity
|
||||
* @param String Enity name
|
||||
* @param {Object|facet.facet|string|Function} arg1
|
||||
* @param {Object|facet.facet|string|Function} arg2
|
||||
* @param {Object|facet.facet|string|Function} arg3
|
||||
*/
|
||||
show_entity: function(entity_name, arg1, arg2, arg3) {
|
||||
var params = {};
|
||||
this.set_params(params, arg1);
|
||||
this.set_params(params, arg2);
|
||||
this.set_params(params, arg3);
|
||||
return routing.navigate(['entity', entity_name, params.facet,
|
||||
params.pkeys, params.args]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Uses lower level access
|
||||
*
|
||||
* `experimental`
|
||||
*
|
||||
* Navigates to generic page by changing hash.
|
||||
*
|
||||
* @param {string} hash Hash of the change
|
||||
* @param {Object} [facet] Facet we are navigating to. Usually used for
|
||||
* notification purposes
|
||||
*/
|
||||
show_generic: function(hash, facet) {
|
||||
routing.router.navigate_to_hash(hash, facet);
|
||||
},
|
||||
|
||||
/**
|
||||
* Show default facet
|
||||
* @method show_default
|
||||
*/
|
||||
show_default: function() {
|
||||
routing.navigate(routing.default_path);
|
||||
},
|
||||
|
||||
create_hash: function(facet, option) {
|
||||
return routing.create_hash(facet, option);
|
||||
}
|
||||
};
|
||||
return navigation;
|
||||
});
|
||||
250
install/ui/src/freeipa/navigation/Menu.js
Normal file
250
install/ui/src/freeipa/navigation/Menu.js
Normal file
@@ -0,0 +1,250 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define(['dojo/_base/declare',
|
||||
'dojo/store/Memory',
|
||||
'dojo/_base/array',
|
||||
'dojo/_base/lang',
|
||||
'dojo/store/Observable',
|
||||
'dojo/Evented',
|
||||
'../reg',
|
||||
'../text'
|
||||
], function(declare, Memory_store, array, lang, Observable, Evented, reg, text) {
|
||||
|
||||
|
||||
return declare([Evented],
|
||||
/**
|
||||
* Menu store
|
||||
*
|
||||
* Maintains menu hierarchy and selection state.
|
||||
*
|
||||
* @class navigation.Menu
|
||||
*
|
||||
*/
|
||||
{
|
||||
/**
|
||||
* Menu name
|
||||
* @property {String}
|
||||
*/
|
||||
name: null,
|
||||
|
||||
/**
|
||||
* Dojo Store of menu items
|
||||
* @property {Store}
|
||||
*/
|
||||
items: null,
|
||||
|
||||
/**
|
||||
* Delimiter used in name creation
|
||||
* To avoid having multiple menu items with the same name.
|
||||
* @property {String}
|
||||
*/
|
||||
path_delimiter: '/',
|
||||
|
||||
/**
|
||||
* Selected menu items
|
||||
* @property {Array}
|
||||
*/
|
||||
selected: [],
|
||||
|
||||
/**
|
||||
* Default search options: sort by position
|
||||
* @property {Object}
|
||||
*/
|
||||
search_options: { sort: [{attribute:'position'}]},
|
||||
|
||||
/**
|
||||
* Takes a spec of menu item.
|
||||
* Normalizes item's name, parent, adds children if specified
|
||||
*
|
||||
* @param {Object} item - spec
|
||||
* @param {string/Object} parent - name or menu item
|
||||
* @param {Object} options
|
||||
*/
|
||||
add_item: function(item, parent, options) {
|
||||
|
||||
item = lang.clone(item); //don't modify original spec
|
||||
|
||||
// each item must have a name and a label
|
||||
// FIXME: consider to move entity and facet stuff outside of this object
|
||||
if (!item.name) {
|
||||
if (item.facet && item.entity) {
|
||||
item.name = item.entity + '_' + item.facet;
|
||||
} else {
|
||||
item.name = item.facet || item.entity;
|
||||
}
|
||||
}
|
||||
if (!item.name) {
|
||||
window.console.error('Missing menu item property: \'name\'', item);
|
||||
return false;
|
||||
}
|
||||
if (item.label) item.label = text.get(item.label);
|
||||
if (item.title) item.title = text.get(item.title);
|
||||
|
||||
if (item.entity) {
|
||||
var entity = reg.entity.get(item.entity);
|
||||
if (!entity) {
|
||||
return false; //quit
|
||||
}
|
||||
if (!item.label) item.label = entity.label;
|
||||
if (!item.title) item.title = entity.title;
|
||||
} else if (item.facet) {
|
||||
var facet = reg.facet.get(item.facet);
|
||||
if (!facet) {
|
||||
return false; //quit
|
||||
}
|
||||
if (!item.label) item.label = facet.label;
|
||||
if (!item.title) item.title = facet.title;
|
||||
}
|
||||
|
||||
item.hidden = !!item.hidden;
|
||||
item.selected = false;
|
||||
|
||||
// check parent
|
||||
if (typeof parent === 'string') {
|
||||
parent = this.items.get(parent);
|
||||
if (!parent) throw 'Menu item\'s parent doesn\t exist';
|
||||
} else if (typeof parent === 'object') {
|
||||
if (!this.items.getIdentity(parent)) {
|
||||
throw 'Supplied parent isn\'t menu item';
|
||||
}
|
||||
}
|
||||
|
||||
var parent_name = parent ? parent.name : null;
|
||||
var siblings = this.items.query({ parent: parent_name });
|
||||
if (!item.position) item.position = siblings.total;
|
||||
// TODO: add reordering of siblings when position set
|
||||
|
||||
item.parent = parent_name;
|
||||
if (parent) {
|
||||
// names have to be unique
|
||||
item.name = parent.name + this.path_delimiter + item.name;
|
||||
}
|
||||
|
||||
// children will be added separately
|
||||
var children = item.children;
|
||||
delete item.children;
|
||||
|
||||
// finally add the item
|
||||
try {
|
||||
this.items.add(item);
|
||||
} catch(e) {
|
||||
window.console.error("Unable to add menu item", item);
|
||||
throw e;
|
||||
}
|
||||
|
||||
// add children
|
||||
if (children) {
|
||||
array.forEach(children, function(child) {
|
||||
this.add_item(child, item);
|
||||
}, this);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Add multiple items
|
||||
* @param {Array} items - spec of items
|
||||
*/
|
||||
add_items: function(/* Array */ items) {
|
||||
array.forEach(items, function(item) {
|
||||
this.add_item(item);
|
||||
}, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Query internal data store by using default search options.
|
||||
*
|
||||
* @param {Object} Query filter
|
||||
* @return {QueryResult}
|
||||
*/
|
||||
query: function(query) {
|
||||
return this.items.query(query, this.search_options);
|
||||
},
|
||||
|
||||
/**
|
||||
* Marks item and all its parents as selected.
|
||||
* @private
|
||||
*/
|
||||
_select: function(item) {
|
||||
|
||||
item.selected = true;
|
||||
this.selected.push(item);
|
||||
this.items.put(item);
|
||||
|
||||
if (item.parent) {
|
||||
var parent = this.items.get(item.parent);
|
||||
parent.selected_child = item.name;
|
||||
this._select(parent);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Selects a menu item and all it's ancestors.
|
||||
* @param {string/navigation.MenuItem} item menu item to select
|
||||
*/
|
||||
select: function(item) {
|
||||
|
||||
if (typeof item == 'string') {
|
||||
item = this.items.get(item);
|
||||
}
|
||||
|
||||
// FIXME: consider to raise an exception
|
||||
if (!item || !this.items.getIdentity(item)) return false;
|
||||
|
||||
// deselect previous
|
||||
var old_selection = lang.clone(this.selected);
|
||||
array.forEach(this.selected, function(mi) {
|
||||
mi.selected = false;
|
||||
this.items.put(mi);
|
||||
}, this);
|
||||
this.selected = [];
|
||||
|
||||
// select new
|
||||
this._select(item);
|
||||
|
||||
var select_state = {
|
||||
item: item,
|
||||
new_selection: this.selected,
|
||||
old_selection: old_selection
|
||||
};
|
||||
|
||||
this.emit('selected', select_state);
|
||||
return select_state;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Object} spec - Specification object
|
||||
* @param {Array} spec.items - Menu items
|
||||
* @param {string} spec.name - Name
|
||||
*/
|
||||
constructor: function(spec) {
|
||||
spec = spec || {};
|
||||
this.items = new Observable( new Memory_store({
|
||||
idProperty: 'name'
|
||||
}));
|
||||
|
||||
spec = lang.clone(spec);
|
||||
this.add_items(spec.items || []);
|
||||
delete spec.items;
|
||||
declare.safeMixin(this, spec);
|
||||
}
|
||||
}); //declare freeipa.menu
|
||||
}); //define
|
||||
98
install/ui/src/freeipa/navigation/MenuItem.js
Normal file
98
install/ui/src/freeipa/navigation/MenuItem.js
Normal file
@@ -0,0 +1,98 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is a virtual object which serves only for documentation purposes. It
|
||||
* describes what properties has the created menu item and what can be part
|
||||
* of menu item object specification.
|
||||
*
|
||||
* Following properties are not in created in menu item:
|
||||
*
|
||||
* - children
|
||||
*
|
||||
* Following properties may be part of menu item at runtime:
|
||||
*
|
||||
* - selected
|
||||
* - parent
|
||||
* - selected_child
|
||||
*
|
||||
* @class navigation.MenuItem
|
||||
* @abstract
|
||||
*/
|
||||
var MenuItem = {
|
||||
/**
|
||||
* Name - menu item identifier
|
||||
*/
|
||||
name: '',
|
||||
|
||||
/**
|
||||
* Visible text
|
||||
*/
|
||||
label: '',
|
||||
|
||||
/**
|
||||
* Title
|
||||
*/
|
||||
title: '',
|
||||
|
||||
/**
|
||||
* Position for ordering
|
||||
*/
|
||||
position: 0,
|
||||
|
||||
/**
|
||||
* Children
|
||||
*
|
||||
* - next navigation level
|
||||
* @property {Array.<navigation.MenuItem>}
|
||||
*/
|
||||
children: null,
|
||||
|
||||
/**
|
||||
* Entity name
|
||||
*/
|
||||
entity: '',
|
||||
|
||||
/**
|
||||
* Facet name
|
||||
*/
|
||||
facet: '',
|
||||
|
||||
/**
|
||||
* Control item visibility but can serve for other evaluations (nested entities)
|
||||
*/
|
||||
hidden: '',
|
||||
|
||||
/**
|
||||
* Runtime property
|
||||
* Should not be set by hand. Indicates whether item is selected.
|
||||
*/
|
||||
selected: false,
|
||||
|
||||
/**
|
||||
* Parent menu item's name
|
||||
*/
|
||||
parent: null,
|
||||
|
||||
/**
|
||||
* Some child is selectd. Runtime property.
|
||||
*/
|
||||
selected_child: null
|
||||
};
|
||||
164
install/ui/src/freeipa/navigation/Router.js
Normal file
164
install/ui/src/freeipa/navigation/Router.js
Normal file
@@ -0,0 +1,164 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define(['dojo/_base/declare',
|
||||
'dojo/Evented',
|
||||
'dojo/router'
|
||||
],
|
||||
function(declare, Evented, router) {
|
||||
|
||||
/**
|
||||
* Router
|
||||
*
|
||||
* This component keeps menu and routes in sync. It signalizes
|
||||
* other components to display facet by sending 'show-facet' event.
|
||||
* Other components can use navigate_to_* methods to change currently
|
||||
* displayed facet. This change can be canceled in 'facet-change'
|
||||
* event handler.
|
||||
* @class navigation.Router
|
||||
*/
|
||||
var navigation = declare([Evented], {
|
||||
|
||||
/**
|
||||
* Holds references to register route handlers.
|
||||
* Can be used for unregistering routes.
|
||||
* @property {Array.<Function>}
|
||||
*/
|
||||
route_handlers: [],
|
||||
|
||||
/**
|
||||
* Prefix of all routes for this navigation. Useful for multiple
|
||||
* navigation objects in one application.
|
||||
* @property {string}
|
||||
*/
|
||||
route_prefix: '',
|
||||
|
||||
/**
|
||||
* Used during facet changing. Set it to true in 'facet-change'
|
||||
* event handler to stop the change.
|
||||
* @property {boolean}
|
||||
*/
|
||||
canceled: false,
|
||||
|
||||
/**
|
||||
* Flag to indicate that next hash change should not invoke showing a
|
||||
* facet.
|
||||
* Main purpose: updating hash.
|
||||
* @property {boolean}
|
||||
*/
|
||||
ignore_next: false,
|
||||
|
||||
/**
|
||||
* Register a route-handler pair to a dojo.router
|
||||
* Handler will be run in context of this object
|
||||
*
|
||||
* @param {string|Array.<string>} route or routes to register
|
||||
* @param {Function} handler to be associated with the route(s)
|
||||
*/
|
||||
register_route: function(route, handler) {
|
||||
|
||||
if (route instanceof Array) {
|
||||
for (var i=0, l=route.length; i<l; i++) {
|
||||
this.register_route(route[i], handler);
|
||||
}
|
||||
} else {
|
||||
var r = this.route_prefix + route;
|
||||
this.route_handlers.push(router.register(r, handler.bind(this)));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Navigate to given hash
|
||||
*
|
||||
* @fires facet-change
|
||||
* @fires facet-change-canceled
|
||||
*/
|
||||
navigate_to_hash: function(hash, facet) {
|
||||
|
||||
this.canceled = false;
|
||||
this.emit('facet-change', { facet: facet, hash: hash });
|
||||
if (this.canceled) {
|
||||
this.emit('facet-change-canceled', { facet: facet, hash : hash });
|
||||
return false;
|
||||
}
|
||||
this.update_hash(hash, false);
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes hash to supplied
|
||||
*
|
||||
* @param {string} Hash to set
|
||||
* @param {boolean} Whether to suppress following hash change handler
|
||||
*/
|
||||
update_hash: function(hash, ignore_change) {
|
||||
if (window.location.hash === "#" + hash) return;
|
||||
this.ignore_next = !!ignore_change;
|
||||
router.go(hash);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns and resets `ignore_next` property.
|
||||
*/
|
||||
check_clear_ignore: function() {
|
||||
var ignore = this.ignore_next;
|
||||
this.ignore_next = false;
|
||||
return ignore;
|
||||
},
|
||||
|
||||
/**
|
||||
* Tells other component to show given facet.
|
||||
*/
|
||||
show_facet: function(facet) {
|
||||
|
||||
this.emit('facet-show', {
|
||||
facet: facet
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Raise 'error'
|
||||
* @protected
|
||||
* @fires error
|
||||
*/
|
||||
_error: function(msg, type, context) {
|
||||
|
||||
this.emit('error', {
|
||||
message: msg,
|
||||
type: type,
|
||||
context: context
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Starts routing
|
||||
*/
|
||||
startup: function() {
|
||||
router.startup();
|
||||
},
|
||||
|
||||
constructor: function(spec) {
|
||||
spec = spec || {};
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return navigation;
|
||||
});
|
||||
368
install/ui/src/freeipa/navigation/menu_spec.js
Normal file
368
install/ui/src/freeipa/navigation/menu_spec.js
Normal file
@@ -0,0 +1,368 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([], function() {
|
||||
|
||||
/**
|
||||
* Specification of menu
|
||||
* @singleton
|
||||
* @class navigation.menu_spec
|
||||
*/
|
||||
var nav = {};
|
||||
/**
|
||||
* Admin menu
|
||||
*/
|
||||
nav.admin = {
|
||||
name: 'admin',
|
||||
items: [
|
||||
{
|
||||
name: 'identity',
|
||||
label: '@i18n:tabs.identity',
|
||||
children: [
|
||||
{
|
||||
entity: 'user',
|
||||
facet: 'search',
|
||||
children: [
|
||||
{
|
||||
entity: 'stageuser',
|
||||
facet: 'search',
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
entity: 'user',
|
||||
facet: 'search_preserved',
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{ entity: 'host' },
|
||||
{ entity: 'service' },
|
||||
{
|
||||
entity: 'group',
|
||||
label: '@i18n:objects.group.groups',
|
||||
facet: 'search',
|
||||
children: [
|
||||
{
|
||||
entity: 'hostgroup',
|
||||
facet: 'search',
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
entity: 'netgroup',
|
||||
facet: 'search',
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{ entity: 'idview' },
|
||||
{
|
||||
name: 'automember',
|
||||
label: '@i18n:tabs.automember',
|
||||
children: [
|
||||
{
|
||||
name: 'amgroup',
|
||||
entity: 'automember',
|
||||
facet: 'searchgroup',
|
||||
label: '@i18n:objects.automember.usergrouprules',
|
||||
children: [
|
||||
{
|
||||
entity: 'automember',
|
||||
facet: 'usergrouprule',
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'amhostgroup',
|
||||
entity: 'automember',
|
||||
facet: 'searchhostgroup',
|
||||
label: '@i18n:objects.automember.hostgrouprules',
|
||||
children: [
|
||||
{
|
||||
entity: 'automember',
|
||||
facet: 'hostgrouprule',
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'policy',
|
||||
label: '@i18n:tabs.policy',
|
||||
children: [
|
||||
{
|
||||
name: 'hbac',
|
||||
label: '@i18n:tabs.hbac',
|
||||
children: [
|
||||
{ entity: 'hbacrule' },
|
||||
{ entity: 'hbacsvc' },
|
||||
{ entity: 'hbacsvcgroup' },
|
||||
{ entity: 'hbactest' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'sudo',
|
||||
label: '@i18n:tabs.sudo',
|
||||
children: [
|
||||
{ entity: 'sudorule' },
|
||||
{ entity: 'sudocmd' },
|
||||
{ entity: 'sudocmdgroup' }
|
||||
]
|
||||
},
|
||||
{ entity: 'selinuxusermap' },
|
||||
{ entity: 'pwpolicy' },
|
||||
{ entity: 'krbtpolicy' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'authentication',
|
||||
label: '@i18n:tabs.authentication',
|
||||
children: [
|
||||
{
|
||||
entity: 'cert',
|
||||
facet: 'search',
|
||||
label: '@i18n:tabs.cert',
|
||||
children: [
|
||||
{
|
||||
entity: 'certprofile',
|
||||
facet: 'search',
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
entity: 'cert',
|
||||
facet: 'search',
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
entity: 'caacl',
|
||||
facet: 'search',
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
entity: 'ca',
|
||||
facet: 'search',
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{ entity: 'otptoken' },
|
||||
{ entity: 'radiusproxy' },
|
||||
{
|
||||
entity: 'certmaprule',
|
||||
facet: 'search',
|
||||
children: [
|
||||
{
|
||||
entity: 'certmaprule',
|
||||
facet: 'search'
|
||||
},
|
||||
{
|
||||
entity: 'certmapconfig',
|
||||
facet: 'details'
|
||||
},
|
||||
{
|
||||
label: '@i18n:objects.certmap_match.facet_label',
|
||||
entity: 'certmap_match'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'network_services',
|
||||
label: '@i18n:tabs.network_services',
|
||||
children: [
|
||||
{
|
||||
name:'automount',
|
||||
label: '@i18n:tabs.automount',
|
||||
entity: 'automountlocation',
|
||||
children: [
|
||||
{ entity: 'automountlocation', hidden: true },
|
||||
{ entity: 'automountmap', hidden: true },
|
||||
{ entity: 'automountkey', hidden: true }
|
||||
]
|
||||
},
|
||||
{
|
||||
name:'dns',
|
||||
label: '@i18n:tabs.dns',
|
||||
children: [
|
||||
{
|
||||
entity: 'dnszone',
|
||||
children: [
|
||||
{ entity: 'dnsrecord', hidden: true }
|
||||
]
|
||||
},
|
||||
{ entity: 'dnsforwardzone' },
|
||||
{ entity: 'dnsserver' },
|
||||
{ entity: 'dnsconfig' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'vault',
|
||||
entity: 'vault',
|
||||
facet: 'search',
|
||||
children: [
|
||||
{
|
||||
entity: 'vault',
|
||||
facet: 'user_search',
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
entity: 'vault',
|
||||
facet: 'service_search',
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
entity: 'vault',
|
||||
facet: 'shared_search',
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
entity: 'vaultconfig',
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'ipaserver',
|
||||
label: '@i18n:tabs.ipaserver',
|
||||
children: [
|
||||
{
|
||||
name: 'rbac',
|
||||
label: '@i18n:tabs.role',
|
||||
children: [
|
||||
{ entity: 'role' },
|
||||
{ entity: 'privilege' },
|
||||
{ entity: 'permission' },
|
||||
{ entity: 'selfservice' },
|
||||
{ entity: 'delegation' }
|
||||
]
|
||||
},
|
||||
{ entity: 'idrange' },
|
||||
{ entity: 'realmdomains' },
|
||||
{
|
||||
name: 'trusts',
|
||||
label: '@i18n:tabs.trust',
|
||||
children: [
|
||||
{ entity: 'trust' },
|
||||
{ entity: 'trustconfig' }
|
||||
]
|
||||
},
|
||||
{
|
||||
entity: 'server',
|
||||
label: '@i18n:tabs.topology',
|
||||
facet: 'search',
|
||||
children: [
|
||||
{
|
||||
entity: 'topologysuffix',
|
||||
facet: 'search',
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
entity: 'server',
|
||||
facet: 'search',
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
entity: 'server_role',
|
||||
facet: 'search',
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
entity: 'domainlevel',
|
||||
facet: 'details',
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
entity: 'location',
|
||||
facet: 'search',
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
facet: 'topology-graph',
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'apibrowser',
|
||||
label: '@i18n:widget.api_browser',
|
||||
facet: 'apibrowser',
|
||||
args: { 'type': 'command' }
|
||||
},
|
||||
{ entity: 'config' }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
/**
|
||||
* Self-service menu
|
||||
*/
|
||||
nav.self_service = {
|
||||
name: 'self-service',
|
||||
items: [
|
||||
{ entity: 'user' },
|
||||
{ entity: 'otptoken' },
|
||||
{
|
||||
name: 'vault',
|
||||
entity: 'vault',
|
||||
facet: 'search',
|
||||
children: [
|
||||
{
|
||||
entity: 'vault',
|
||||
facet: 'user_search',
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
entity: 'vault',
|
||||
facet: 'service_search',
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
entity: 'vault',
|
||||
facet: 'shared_search',
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
entity: 'vaultconfig',
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
nav.ad_self_service = {
|
||||
name: 'ad_self_service',
|
||||
items: [
|
||||
{
|
||||
entity: 'idoverrideuser',
|
||||
label: 'Profile'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
return nav;
|
||||
});
|
||||
505
install/ui/src/freeipa/navigation/routing.js
Normal file
505
install/ui/src/freeipa/navigation/routing.js
Normal file
@@ -0,0 +1,505 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2014 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'dojo/_base/declare',
|
||||
'dojo/_base/lang',
|
||||
'dojo/_base/array',
|
||||
'dojo/io-query',
|
||||
'../reg',
|
||||
'../util'
|
||||
],
|
||||
function(declare, lang, array, ioquery, reg, util) {
|
||||
|
||||
/**
|
||||
* Routing mechanism
|
||||
* @class navigation.routing
|
||||
* @singleton
|
||||
*/
|
||||
var routing = {
|
||||
|
||||
/**
|
||||
* Router instance
|
||||
* @property {navigation.Router}
|
||||
*/
|
||||
router: null,
|
||||
|
||||
/**
|
||||
* Map of router handlers
|
||||
* @property {Object}
|
||||
*/
|
||||
route_handlers: {},
|
||||
|
||||
/**
|
||||
* Map of hash creators
|
||||
* @property {Object}
|
||||
*/
|
||||
hash_creators: {},
|
||||
|
||||
/**
|
||||
* Facet name to hash creator map
|
||||
*
|
||||
* - Key: facet name
|
||||
* - Value: hash creator
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
hc_facet_map: {},
|
||||
|
||||
/**
|
||||
* Hash creator priority queue
|
||||
*
|
||||
* First item == highest priority
|
||||
*
|
||||
* @type {Array}
|
||||
*/
|
||||
hc_queue: [],
|
||||
|
||||
/**
|
||||
* Map of navigators
|
||||
* @type {Object}
|
||||
*/
|
||||
navigators: {},
|
||||
|
||||
/**
|
||||
* Add hash creator at the beginning of hash creator queue
|
||||
* @param {navigation.routing.HashCreator} hash_creator
|
||||
* @param {Number} [position]
|
||||
*/
|
||||
add_hash_creator: function(hash_creator, position) {
|
||||
|
||||
if (position !== undefined) {
|
||||
this.hc_queue.splice(position, 0, hash_creator);
|
||||
} else {
|
||||
this.hc_queue.unshift(hash_creator);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Add hash creator to hash creator map
|
||||
* @param {string} facet_name
|
||||
* @param {navigation.routing.HashCreator} hash_creator
|
||||
*/
|
||||
assign_hash_creator: function (facet_name, hash_creator) {
|
||||
this.hc_facet_map[facet_name] = hash_creator;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get hash creator for given facet
|
||||
*
|
||||
* Lookup priority:
|
||||
*
|
||||
* - facet -> hash creator map
|
||||
* - hash creator queue
|
||||
*
|
||||
* @param {facets.Facet} facet [description]
|
||||
* @return {navigation.routing.HashCreator}
|
||||
*/
|
||||
get_hash_creator: function(facet) {
|
||||
|
||||
var name = facet.name;
|
||||
var hc = this.hc_facet_map[name];
|
||||
if (!hc) {
|
||||
for (var i=0, l=this.hc_queue.length; i<l; i++) {
|
||||
if (this.hc_queue[i].handles(facet)) {
|
||||
hc = this.hc_queue[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return hc || null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Create hash for given facet
|
||||
*
|
||||
* @param {facets.Facet} facet
|
||||
* @param {Object|null} options
|
||||
* @return {string} hash
|
||||
*/
|
||||
create_hash: function(facet, options) {
|
||||
var hc = this.get_hash_creator(facet);
|
||||
if (!hc) return '';
|
||||
return hc.create_hash(this.router, facet, options);
|
||||
},
|
||||
|
||||
/**
|
||||
* Navigate by a Navigator
|
||||
*
|
||||
* Expects path as argument. Path is an array where
|
||||
* first element is name of the Navigator, rest are
|
||||
* navigators params.
|
||||
*
|
||||
* @param {Array} path
|
||||
* @return {boolean}
|
||||
*/
|
||||
navigate: function(path) {
|
||||
|
||||
path = path.slice(0);
|
||||
var nav_name = path.shift();
|
||||
var nav = this.get_navigator(nav_name);
|
||||
return nav.navigate.apply(nav, path);
|
||||
},
|
||||
|
||||
/**
|
||||
* Navigate to specific facet with give options
|
||||
* @param {facets.Facet} facet
|
||||
* @param {Object} options Options for hash creator
|
||||
* @return {boolean}
|
||||
*/
|
||||
navigate_to_facet: function(facet, options) {
|
||||
var hash = this.create_hash(facet, options);
|
||||
return this.router.navigate_to_hash(hash, facet);
|
||||
},
|
||||
|
||||
update_hash: function(facet, options) {
|
||||
|
||||
var hash = this.create_hash(facet, options);
|
||||
this.router.update_hash(hash, true);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add route handler to router
|
||||
* @param {string|string[]} route Route or routes.
|
||||
* @param {navigation.routing.RouteHandler} handler Handler
|
||||
*/
|
||||
add_route: function(route, handler) {
|
||||
this.route_handlers[handler.name] = handler;
|
||||
this.router.register_route(route, handler.get_handler());
|
||||
},
|
||||
|
||||
/**
|
||||
* Add navigator
|
||||
* @param {navigation.routing.Navigator} navigator
|
||||
*/
|
||||
add_navigator: function(navigator) {
|
||||
this.navigators[navigator.name] = navigator;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get navigator by name
|
||||
* @param {string} name Navigator's name
|
||||
* @return {navigation.routing.Navigator}
|
||||
*/
|
||||
get_navigator: function(name) {
|
||||
return this.navigators[name];
|
||||
},
|
||||
|
||||
/**
|
||||
* Path for default facet
|
||||
* @type {Array}
|
||||
*/
|
||||
default_path: ['entity', 'user', 'search'],
|
||||
|
||||
/**
|
||||
* Variations of entity routes
|
||||
* @property {string[]}
|
||||
*/
|
||||
entity_routes: [
|
||||
'/e/:entity/:facet/:pkeys/*args',
|
||||
'/e/:entity/:facet//*args',
|
||||
'/e/:entity/:facet/:pkeys',
|
||||
'/e/:entity/:facet',
|
||||
'/e/:entity'
|
||||
],
|
||||
|
||||
/**
|
||||
* Variations of simple page routes
|
||||
* @property {string[]}
|
||||
*/
|
||||
page_routes: [
|
||||
'/p/:page/*args',
|
||||
'/p/:page'
|
||||
]
|
||||
};
|
||||
|
||||
/**
|
||||
* General route handler
|
||||
*
|
||||
* @class navigation.routing.RouteHandler
|
||||
*/
|
||||
routing.RouteHandler = declare([], {
|
||||
|
||||
handler: null,
|
||||
|
||||
name: 'generic',
|
||||
|
||||
/**
|
||||
* Handle router event
|
||||
* @param {Object} event
|
||||
* @param {navigation.Router} router
|
||||
*/
|
||||
handle: function (event, router) {
|
||||
if (router.check_clear_ignore()) return;
|
||||
|
||||
var facet_name = event.params.page;
|
||||
var args;
|
||||
try {
|
||||
args = ioquery.queryToObject(event.params.args || '');
|
||||
} catch (e) {
|
||||
router._error('URI error', 'route', event.params);
|
||||
return;
|
||||
}
|
||||
|
||||
// set new facet state
|
||||
var facet = reg.facet.get(facet_name);
|
||||
if (!facet) {
|
||||
router._error('Unknown facet', 'route', event.params);
|
||||
return;
|
||||
}
|
||||
facet.reset_state(args);
|
||||
router.show_facet(facet);
|
||||
},
|
||||
|
||||
/**
|
||||
* Create handler callback for router
|
||||
* @return {Function} callback
|
||||
*/
|
||||
get_handler: function() {
|
||||
|
||||
if (!this.handler) {
|
||||
var self = this;
|
||||
this.handler = function(event) {
|
||||
self.handle(event, this);
|
||||
};
|
||||
}
|
||||
return this.handler;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Entity route handler
|
||||
*
|
||||
* @class navigation.routing.EntityRouteHandler
|
||||
* @extends {navigation.routing.RouteHandler}
|
||||
*/
|
||||
routing.EntityRouteHandler = declare([routing.RouteHandler], {
|
||||
|
||||
name: 'entity',
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
handle: function (event, router) {
|
||||
if (router.check_clear_ignore()) return;
|
||||
|
||||
var entity_name = event.params.entity;
|
||||
var facet_name = event.params.facet;
|
||||
var pkeys, args;
|
||||
try {
|
||||
pkeys = this._decode_pkeys(event.params.pkeys || '');
|
||||
args = ioquery.queryToObject(event.params.args || '');
|
||||
} catch (e) {
|
||||
router._error('URI error', 'route', event.params);
|
||||
return;
|
||||
}
|
||||
args.pkeys = pkeys;
|
||||
|
||||
// set new facet state
|
||||
var entity = reg.entity.get(entity_name);
|
||||
if (!entity) {
|
||||
router._error('Unknown entity', 'route', event.params);
|
||||
return;
|
||||
}
|
||||
var facet = entity.get_facet(facet_name);
|
||||
if (!facet) {
|
||||
router._error('Unknown facet', 'route', event.params);
|
||||
return;
|
||||
}
|
||||
facet.reset_state(args);
|
||||
router.show_facet(facet);
|
||||
},
|
||||
|
||||
/**
|
||||
* Splits strings by '&' and return an array of URI decoded parts.
|
||||
* Example: 'foo%20&bar' => ['foo ', 'bar']
|
||||
*/
|
||||
_decode_pkeys: function(str) {
|
||||
|
||||
if (!str) return [];
|
||||
|
||||
var keys = str.split('&');
|
||||
for (var i=0; i<keys.length; i++) {
|
||||
keys[i] = decodeURIComponent(keys[i]);
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Hash creator creates a hash string from given facet and options
|
||||
*
|
||||
* This is default hash creator for generic facets.
|
||||
*
|
||||
* @class navigation.routing.HashCreator
|
||||
*/
|
||||
routing.HashCreator = declare([], {
|
||||
|
||||
prefix: 'p',
|
||||
|
||||
name: 'generic',
|
||||
|
||||
create_hash: function(router, facet, options) {
|
||||
|
||||
var path = [router.route_prefix, this.prefix, facet.name];
|
||||
var args = ioquery.objectToQuery(options || {});
|
||||
if (!util.is_empty(args)) path.push(args);
|
||||
var hash = path.join('/');
|
||||
return hash;
|
||||
},
|
||||
|
||||
handles: function(facet) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Hash creator for entity facets
|
||||
* @class navigation.routing.EntityHashCreator
|
||||
* @extends navigation.routing.HashCreator
|
||||
*/
|
||||
routing.EntityHashCreator = declare([routing.HashCreator], {
|
||||
|
||||
prefix: 'e',
|
||||
|
||||
name: 'entity',
|
||||
|
||||
create_hash: function(router, facet, options) {
|
||||
|
||||
options = lang.clone(options);
|
||||
var entity_name = facet.entity.name;
|
||||
var pkeys = this._encode_pkeys(options.pkeys || []);
|
||||
delete options.pkeys;
|
||||
var args = ioquery.objectToQuery(options || {});
|
||||
|
||||
var path = [router.route_prefix, this.prefix, entity_name, facet.name];
|
||||
if (!util.is_empty(args)) path.push(pkeys, args);
|
||||
else if (!util.is_empty(pkeys)) path.push(pkeys);
|
||||
|
||||
var hash = path.join('/');
|
||||
return hash;
|
||||
},
|
||||
|
||||
handles: function(facet) {
|
||||
return !!facet.entity;
|
||||
},
|
||||
|
||||
/**
|
||||
* URI Encodes array items and delimits them by '&'
|
||||
* Example: ['foo ', 'bar'] => 'foo%20&bar'
|
||||
*/
|
||||
_encode_pkeys: function(pkeys) {
|
||||
|
||||
var ret = [];
|
||||
array.forEach(pkeys, function(pkey) {
|
||||
ret.push(encodeURIComponent(pkey));
|
||||
});
|
||||
return ret.join('&');
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Navigate to other facet.
|
||||
*
|
||||
* @class navigation.routing.Navigator
|
||||
*/
|
||||
routing.Navigator = declare([], {
|
||||
|
||||
name: 'generic',
|
||||
|
||||
navigate: function(facet_name, args) {
|
||||
|
||||
var facet = reg.facet.get(facet_name);
|
||||
if (!facet) {
|
||||
routing.router._error('Unknown facet', 'navigation', { facet: facet_name});
|
||||
return false;
|
||||
}
|
||||
if (!args) args = facet.get_state();
|
||||
|
||||
return routing.navigate_to_facet(facet, args);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Used for switching to entities' facets. Current target facet
|
||||
* state is used as params (pkeys, args) when none of pkeys and args
|
||||
* are used (useful for switching to previous page with keeping the context).
|
||||
*
|
||||
* @class navigation.routing.EntityNavigator
|
||||
* @extends navigation.routing.Navigator
|
||||
*/
|
||||
routing.EntityNavigator = declare([routing.Navigator], {
|
||||
|
||||
name: 'entity',
|
||||
|
||||
navigate: function(entity_name, facet_name, pkeys, args) {
|
||||
|
||||
var entity = reg.entity.get(entity_name);
|
||||
if (!entity) {
|
||||
routing.router._error('Unknown entity', 'navigation', { entity: entity_name});
|
||||
return false;
|
||||
}
|
||||
|
||||
var facet = entity.get_facet(facet_name);
|
||||
if (!facet) {
|
||||
routing.router._error('Unknown facet', 'navigation', { facet: facet_name});
|
||||
return false;
|
||||
}
|
||||
|
||||
// Use current state if none supplied
|
||||
if (!pkeys && !args) {
|
||||
args = facet.get_state();
|
||||
}
|
||||
args = args || {};
|
||||
|
||||
// Facets may be nested and require more pkeys than supplied.
|
||||
args.pkeys = facet.get_pkeys(pkeys);
|
||||
|
||||
return routing.navigate_to_facet(facet, args);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Init routing
|
||||
*
|
||||
* Sets default routes, handlers, hash creators and navigators
|
||||
*
|
||||
* @param {navigation.Router} router
|
||||
*/
|
||||
routing.init = function(router) {
|
||||
|
||||
if (router) this.router = router;
|
||||
var generic_hc = new routing.HashCreator();
|
||||
var entity_hc = new routing.EntityHashCreator();
|
||||
var generic_rh = new routing.RouteHandler();
|
||||
var entity_rh = new routing.EntityRouteHandler();
|
||||
var generic_n = new routing.Navigator();
|
||||
var entity_n = new routing.EntityNavigator();
|
||||
this.add_hash_creator(generic_hc);
|
||||
this.add_hash_creator(entity_hc);
|
||||
this.add_route(this.page_routes, generic_rh);
|
||||
this.add_route(this.entity_routes, entity_rh);
|
||||
this.add_navigator(generic_n);
|
||||
this.add_navigator(entity_n);
|
||||
};
|
||||
|
||||
return routing;
|
||||
|
||||
});
|
||||
399
install/ui/src/freeipa/net.js
Normal file
399
install/ui/src/freeipa/net.js
Normal file
@@ -0,0 +1,399 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define(['./ipa', './jquery'], function(IPA, $) {
|
||||
|
||||
var NET = {};
|
||||
|
||||
NET.ip_address = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
if (typeof spec === 'string') {
|
||||
spec = {
|
||||
address: spec
|
||||
};
|
||||
}
|
||||
|
||||
var that = IPA.object();
|
||||
|
||||
that.input = spec.address;
|
||||
|
||||
that.type = spec.type;
|
||||
that.parts = spec.parts;
|
||||
that.reverse_address = '';
|
||||
that.only_decimal = spec.only_decimal !== undefined? spec.only_decimal :
|
||||
false; //for parsing IPv4 address
|
||||
|
||||
that.parse = function() {
|
||||
|
||||
if (!that.input && !that.parts) {
|
||||
that.set_error('no input');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!that.type) {
|
||||
that.type = that.detect_type();
|
||||
}
|
||||
|
||||
if (that.type === 'v4-quads') {
|
||||
return that.parse_v4_quads();
|
||||
} else if (that.type === 'v4-int') {
|
||||
return that.parse_v4_int();
|
||||
} else if (that.type === 'v6') {
|
||||
return that.parse_v6();
|
||||
}
|
||||
|
||||
that.set_error('not an ip address');
|
||||
return false;
|
||||
};
|
||||
|
||||
that.detect_type = function() {
|
||||
|
||||
var type;
|
||||
|
||||
if (!that.input) return null;
|
||||
|
||||
if (that.input.indexOf(':') > -1) type = 'v6';
|
||||
else if (that.input.indexOf('.') > -1) type = 'v4-quads';
|
||||
else type = 'v4-int';
|
||||
|
||||
return type;
|
||||
};
|
||||
|
||||
that.parse_v4_int = function() {
|
||||
|
||||
var part = { value: that.input };
|
||||
if(!that.is_part_valid_v4(part, 32, that.only_decimal)) return false;
|
||||
|
||||
that.parts = [];
|
||||
that.make_quads(part.decimal_value, that.parts);
|
||||
|
||||
that.valid = true;
|
||||
return true;
|
||||
};
|
||||
|
||||
that.parse_v4_quads = function() {
|
||||
|
||||
if (!that.parts) {
|
||||
that.parts = that.input.split('.');
|
||||
}
|
||||
|
||||
if (that.parts.length !== 4) {
|
||||
return that.set_error('invalid number of parts');
|
||||
}
|
||||
|
||||
for (var i=0; i<4; i++) {
|
||||
|
||||
var part = { value: that.parts[i] };
|
||||
|
||||
if (!that.is_part_valid_v4(part, 8, that.only_decimal)) {
|
||||
return false;
|
||||
}
|
||||
that.parts[i] = part.decimal_value.toString(10);
|
||||
}
|
||||
|
||||
that.valid = true;
|
||||
return true;
|
||||
};
|
||||
|
||||
that.parse_v6 = function() {
|
||||
|
||||
if (!that.parts) {
|
||||
that.parts = that.input.split(':');
|
||||
}
|
||||
|
||||
var total_parts = that.parts.length;
|
||||
var ipv4_present = false;
|
||||
var double_colon = false;
|
||||
var double_colon_position;
|
||||
|
||||
var i;
|
||||
|
||||
//usecases like ':'
|
||||
if (that.parts.length <= 2) {
|
||||
return that.set_error('invalid format');
|
||||
}
|
||||
|
||||
for (i=0; i<that.parts.length; i++) {
|
||||
var part = that.parts[i];
|
||||
|
||||
if (i === that.parts.length -1 && part.indexOf('.') > -1) {
|
||||
ipv4_present = true;
|
||||
total_parts++; //ipv4 part consists of 4 octects (two parts)
|
||||
}
|
||||
|
||||
//checking for ::
|
||||
if (part.length === 0) {
|
||||
|
||||
if (!double_colon || //first occurance
|
||||
(double_colon && i === 1) || //still at the beginning
|
||||
(double_colon && i === that.parts.length - 1 &&
|
||||
double_colon_position === i -1)) { //still at the end
|
||||
|
||||
part = '0000';
|
||||
that.parts[i] = part;
|
||||
double_colon = true;
|
||||
double_colon_position = i;
|
||||
} else { //second occurance of ::
|
||||
return that.set_error('invalid format: mupltiple ::');
|
||||
}
|
||||
}
|
||||
|
||||
//add missing zeros for not empty parts
|
||||
if (part.length !== 0 && part.length < 4) {
|
||||
part = add_leading_zeros(part, 4 - part.length);
|
||||
that.parts[i] = part;
|
||||
}
|
||||
}
|
||||
|
||||
//add missing empty parts
|
||||
if (double_colon) {
|
||||
var parts_to_add = 8 - total_parts;
|
||||
|
||||
for (i=0; i<parts_to_add; i++) {
|
||||
that.parts.splice(double_colon_position, 0, '0000');
|
||||
}
|
||||
}
|
||||
|
||||
//change ipv4 part
|
||||
if (ipv4_present) {
|
||||
var ipv4_address = NET.ip_address();
|
||||
ipv4_address.input = that.parts[that.parts.length -1];
|
||||
ipv4_address.only_decimal = true;
|
||||
if (ipv4_address.parse() && ipv4_address.type === 'v4-quads') {
|
||||
var v4_parts = ipv4_address.parts;
|
||||
var oct1 = dec_2_hex(v4_parts[0]);
|
||||
var oct2 = dec_2_hex(v4_parts[1]);
|
||||
var oct3 = dec_2_hex(v4_parts[2]);
|
||||
var oct4 = dec_2_hex(v4_parts[3]);
|
||||
|
||||
//replace IPv4 part with two IPv6 parts (4 octets)
|
||||
that.parts[that.parts.length -1] = oct1+oct2;
|
||||
that.parts.push(oct3+oct4);
|
||||
} else {
|
||||
return that.set_error('invalid IPv4 part');
|
||||
}
|
||||
}
|
||||
|
||||
//validate length after modifications
|
||||
if (that.parts.length !== 8) {
|
||||
return that.set_error('invalid number of parts');
|
||||
}
|
||||
|
||||
//validate each part
|
||||
for (i=0; i<8; i++) {
|
||||
|
||||
if (!that.is_part_valid_v6(that.parts[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
that.valid = true;
|
||||
return true;
|
||||
};
|
||||
|
||||
function dec_2_hex(val) {
|
||||
var dec = parseInt(val, 10);
|
||||
var hex = dec.toString(16);
|
||||
hex = add_leading_zeros(hex, 2 - hex.length);
|
||||
return hex;
|
||||
}
|
||||
|
||||
function add_leading_zeros(val, num) {
|
||||
for (var i=0; i<num; i++) {
|
||||
val='0'+val;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
that.get_reverse = function() {
|
||||
|
||||
if (!that.valid) return 'invalid input address';
|
||||
|
||||
if (that.type === 'v4-quads' || that.type === 'v4-int') {
|
||||
return that.get_v4_reverse();
|
||||
} else if (that.type === 'v6') {
|
||||
return that.get_v6_reverse();
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
|
||||
that.get_v4_reverse = function() {
|
||||
|
||||
that.reverse_parts = [];
|
||||
|
||||
for (var i=3; i>=0; i--) {
|
||||
that.reverse_parts.push(that.parts[i]);
|
||||
}
|
||||
|
||||
that.reverse_parts.push('in-addr');
|
||||
that.reverse_parts.push('arpa');
|
||||
|
||||
return that.reverse_parts.join('.');
|
||||
};
|
||||
|
||||
that.get_v6_reverse = function() {
|
||||
|
||||
that.reverse_parts = [];
|
||||
|
||||
var address = that.parts.join('');
|
||||
|
||||
for (var i=31; i>=0; i--) {
|
||||
that.reverse_parts.push(address[i]);
|
||||
}
|
||||
|
||||
that.reverse_parts.push('ip6');
|
||||
that.reverse_parts.push('arpa');
|
||||
|
||||
return that.reverse_parts.join('.');
|
||||
};
|
||||
|
||||
that.set_error = function(msg) {
|
||||
that.valid = false;
|
||||
that.error = msg;
|
||||
return false;
|
||||
};
|
||||
|
||||
that.is_part_valid_v6 = function(str) {
|
||||
|
||||
if (str.length === 0) {
|
||||
return that.set_error('not a number');
|
||||
}
|
||||
|
||||
if (str.length > 4) {
|
||||
return that.set_error('wrong format - too long');
|
||||
}
|
||||
|
||||
for (var i=0; i<str.length; i++) {
|
||||
|
||||
var digit = parseInt(str[i], 16);
|
||||
|
||||
//check if character is digit
|
||||
if (isNaN(digit)) {
|
||||
return that.set_error('invalid format: \''+digit+'\'');
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/*
|
||||
* Checks if part.value is valid IPv4 integer of given size (in bits).
|
||||
* Validation can be limited only to decimal values by only_decimal argument.
|
||||
* Sets its decimal representation to part.decimal_value.
|
||||
*/
|
||||
that.is_part_valid_v4 = function(part, bits, only_decimal) {
|
||||
|
||||
if (!part.value || part.value.length === 0) {
|
||||
return that.set_error('not a number');
|
||||
}
|
||||
|
||||
var radix = that.get_radix(part.value);
|
||||
|
||||
var number = part.value;
|
||||
|
||||
if (radix === 16) number = part.value.substring(2);
|
||||
else if (radix === 8) number = part.value.substring(1);
|
||||
|
||||
if (radix !== 10 && only_decimal) {
|
||||
return that.set_error('not a decimal number');
|
||||
}
|
||||
|
||||
for (var i=0; i<number.length; i++) {
|
||||
|
||||
var digit = parseInt(number[i], radix);
|
||||
|
||||
//check if character is digit in its radix
|
||||
if (isNaN(digit)) {
|
||||
return that.set_error('invalid format: \''+digit+'\'');
|
||||
}
|
||||
|
||||
//check for leading zeros
|
||||
if (i === 0 && digit === 0 && number.length > 1) {
|
||||
return that.set_error('invalid format: leading zeros');
|
||||
}
|
||||
}
|
||||
|
||||
var max_value = Math.pow(2, bits) - 1;
|
||||
|
||||
part.decimal_value = parseInt(part.value, radix);
|
||||
|
||||
if (part.decimal_value > max_value) {
|
||||
return that.set_error('value out of range');
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
that.get_radix = function(str) {
|
||||
|
||||
var normalized = str.toLowerCase();
|
||||
|
||||
if (normalized.length > 2 &&
|
||||
normalized[0] === '0' &&
|
||||
normalized[1] === 'x') {
|
||||
return 16;
|
||||
|
||||
} else if (normalized.length > 1 && normalized[0] === '0') {
|
||||
return 8;
|
||||
}
|
||||
|
||||
return 10;
|
||||
};
|
||||
|
||||
that.make_quads = function(integer, quads) {
|
||||
|
||||
var hex_str = integer.toString(16);
|
||||
if (hex_str.length < 8) {
|
||||
hex_str = add_leading_zeros(hex_str, 8 - hex_str.length);
|
||||
}
|
||||
|
||||
for (var i=0; i<hex_str.length; i+=2) {
|
||||
var quad_hex = hex_str.substring(i,i+2);
|
||||
var quad = parseInt(quad_hex, 16);
|
||||
quads.push(quad.toString(10));
|
||||
}
|
||||
};
|
||||
|
||||
that.get_radix = function(str) {
|
||||
|
||||
var normalized = str.toLowerCase();
|
||||
|
||||
if (normalized.length > 2 &&
|
||||
normalized[0] === '0' &&
|
||||
normalized[1] === 'x') {
|
||||
return 16;
|
||||
|
||||
} else if (normalized.length > 1 && normalized[0] === '0') {
|
||||
return 8;
|
||||
}
|
||||
|
||||
return 10;
|
||||
};
|
||||
|
||||
that.parse();
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
return NET;
|
||||
});
|
||||
335
install/ui/src/freeipa/netgroup.js
Normal file
335
install/ui/src/freeipa/netgroup.js
Normal file
@@ -0,0 +1,335 @@
|
||||
/* Authors:
|
||||
* Pavel Zuna <pzuna@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'./ipa',
|
||||
'./jquery',
|
||||
'./phases',
|
||||
'./reg',
|
||||
'./association',
|
||||
'./entity',
|
||||
'./details',
|
||||
'./rule',
|
||||
'./search'
|
||||
],
|
||||
function(IPA, $, phases, reg) {
|
||||
|
||||
var exp = IPA.netgroup = {
|
||||
remove_method_priority: IPA.config.default_priority - 1,
|
||||
enable_priority: IPA.config.default_priority + 1
|
||||
};
|
||||
|
||||
var make_spec = function() {
|
||||
var spec = {
|
||||
name: 'netgroup',
|
||||
facet_groups: ['settings', 'member', 'memberof'],
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
tab_label: '@i18n:objects.netgroup.netgroups',
|
||||
facet_groups: [IPA.group.search_facet_group],
|
||||
tabs_in_sidebar: true,
|
||||
disable_facet_tabs: false,
|
||||
columns: [
|
||||
'cn',
|
||||
'description'
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
$factory: IPA.netgroup.details_facet,
|
||||
command_mode: 'info'
|
||||
},
|
||||
{
|
||||
$type: 'association',
|
||||
name: 'memberof_netgroup',
|
||||
associator: IPA.serial_associator
|
||||
}
|
||||
],
|
||||
standard_association_facets: true,
|
||||
adder_dialog: {
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
add_netgroup_details_facet_widgets(spec.facets[1]);
|
||||
return spec;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
* @param {Object} facet spec
|
||||
*/
|
||||
var add_netgroup_details_facet_widgets = function (spec) {
|
||||
|
||||
//
|
||||
// Identity
|
||||
//
|
||||
|
||||
spec.fields = [
|
||||
{
|
||||
name: 'cn',
|
||||
widget: 'identity.cn'
|
||||
},
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description',
|
||||
widget: 'identity.description'
|
||||
},
|
||||
{
|
||||
name: 'nisdomainname',
|
||||
widget: 'identity.nisdomainname'
|
||||
}
|
||||
];
|
||||
|
||||
spec.widgets = [
|
||||
{
|
||||
$type: 'details_section',
|
||||
name: 'identity',
|
||||
label: '@i18n:details.general',
|
||||
widgets: [
|
||||
{
|
||||
name: 'cn'
|
||||
},
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
},
|
||||
{
|
||||
name: 'nisdomainname',
|
||||
widget: 'general.nisdomainname'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
//
|
||||
// Users
|
||||
//
|
||||
|
||||
spec.fields.push(
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'usercategory',
|
||||
widget: 'user.rule.usercategory'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberuser_user',
|
||||
widget: 'user.rule.memberuser_user',
|
||||
priority: IPA.netgroup.remove_method_priority
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberuser_group',
|
||||
widget: 'user.rule.memberuser_group',
|
||||
priority: IPA.netgroup.remove_method_priority
|
||||
}
|
||||
);
|
||||
|
||||
spec.widgets.push(
|
||||
{
|
||||
$factory: IPA.section,
|
||||
name: 'user',
|
||||
label: '@i18n:objects.netgroup.user',
|
||||
widgets: [
|
||||
{
|
||||
$factory: IPA.rule_details_widget,
|
||||
name: 'rule',
|
||||
radio_name: 'usercategory',
|
||||
options: [
|
||||
{ value: 'all',
|
||||
label: '@i18n:objects.netgroup.anyone' },
|
||||
{ value: '',
|
||||
label: '@i18n:objects.netgroup.specified_users' }
|
||||
],
|
||||
tables: [
|
||||
{ name: 'memberuser_user' },
|
||||
{ name: 'memberuser_group' }
|
||||
],
|
||||
widgets: [
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'netgroup-memberuser_user',
|
||||
name: 'memberuser_user',
|
||||
add_method: 'add_member',
|
||||
remove_method: 'remove_member',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member',
|
||||
columns: [
|
||||
{
|
||||
name: 'memberuser_user',
|
||||
label: '@i18n:objects.netgroup.users',
|
||||
link: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'netgroup-memberuser_group',
|
||||
name: 'memberuser_group',
|
||||
add_method: 'add_member',
|
||||
remove_method: 'remove_member',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member',
|
||||
columns: [
|
||||
{
|
||||
name: 'memberuser_group',
|
||||
label: '@i18n:objects.netgroup.usergroups',
|
||||
link: true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
//
|
||||
// Hosts
|
||||
//
|
||||
|
||||
spec.fields.push(
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'hostcategory',
|
||||
widget: 'host.rule.hostcategory'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberhost_host',
|
||||
widget: 'host.rule.memberhost_host',
|
||||
priority: IPA.netgroup.remove_method_priority,
|
||||
external: 'externalhost'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberhost_hostgroup',
|
||||
widget: 'host.rule.memberhost_hostgroup',
|
||||
priority: IPA.netgroup.remove_method_priority
|
||||
}
|
||||
);
|
||||
|
||||
spec.widgets.push(
|
||||
{
|
||||
$factory: IPA.section,
|
||||
name: 'host',
|
||||
label: '@i18n:objects.netgroup.host',
|
||||
widgets: [
|
||||
{
|
||||
$factory: IPA.rule_details_widget,
|
||||
name: 'rule',
|
||||
radio_name: 'hostcategory',
|
||||
options: [
|
||||
{
|
||||
'value': 'all',
|
||||
label: '@i18n:objects.netgroup.any_host'
|
||||
},
|
||||
{
|
||||
'value': '',
|
||||
label: '@i18n:objects.netgroup.specified_hosts'
|
||||
}
|
||||
],
|
||||
tables: [
|
||||
{ 'name': 'memberhost_host' },
|
||||
{ 'name': 'memberhost_hostgroup' }
|
||||
],
|
||||
widgets: [
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'netgroup-memberhost_host',
|
||||
name: 'memberhost_host',
|
||||
add_method: 'add_member',
|
||||
remove_method: 'remove_member',
|
||||
external: 'externalhost',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member',
|
||||
columns: [
|
||||
{
|
||||
name: 'memberhost_host',
|
||||
label: '@i18n:objects.netgroup.hosts',
|
||||
link: true
|
||||
},
|
||||
{
|
||||
name: 'externalhost',
|
||||
label: '@i18n:objects.netgroup.external',
|
||||
formatter: 'boolean',
|
||||
width: '200px'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'netgroup-memberhost_hostgroup',
|
||||
name: 'memberhost_hostgroup',
|
||||
add_method: 'add_member',
|
||||
remove_method: 'remove_member',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member',
|
||||
columns: [
|
||||
{
|
||||
name: 'memberhost_hostgroup',
|
||||
label: '@i18n:objects.netgroup.hostgroups',
|
||||
link: true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
IPA.netgroup.details_facet = function(spec) {
|
||||
|
||||
var that = IPA.details_facet(spec);
|
||||
|
||||
that.update_on_success = function(data, text_status, xhr) {
|
||||
that.refresh();
|
||||
that.on_update.notify();
|
||||
that.nofify_update_success();
|
||||
};
|
||||
|
||||
that.update_on_error = function(xhr, text_status, error_thrown) {
|
||||
that.refresh();
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
exp.entity_spec = make_spec();
|
||||
exp.register = function() {
|
||||
var e = reg.entity;
|
||||
|
||||
e.register({type: 'netgroup', spec: exp.entity_spec});
|
||||
};
|
||||
phases.on('registration', exp.register);
|
||||
|
||||
return exp;
|
||||
});
|
||||
30
install/ui/src/freeipa/ordered-map.js
Normal file
30
install/ui/src/freeipa/ordered-map.js
Normal file
@@ -0,0 +1,30 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
define([
|
||||
'./jquery'
|
||||
], function($) {
|
||||
/**
|
||||
* Wrapper for jquery.ordered_map
|
||||
* @class ordered_map
|
||||
*/
|
||||
return $.ordered_map;
|
||||
});
|
||||
568
install/ui/src/freeipa/otptoken.js
Normal file
568
install/ui/src/freeipa/otptoken.js
Normal file
@@ -0,0 +1,568 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'dojo/on',
|
||||
'./ipa',
|
||||
'./jquery',
|
||||
'./menu',
|
||||
'./phases',
|
||||
'./reg',
|
||||
'./details',
|
||||
'./facet',
|
||||
'./qrcode',
|
||||
'./text',
|
||||
'./search',
|
||||
'./entity'],
|
||||
function(on, IPA, $, menu, phases, reg, mod_details, mod_facet, QRCode, text) {
|
||||
/**
|
||||
* OTP tokens module
|
||||
* @class
|
||||
* @singleton
|
||||
*/
|
||||
var otptoken = IPA.otptoken = {
|
||||
app_link: 'https://fedorahosted.org/freeotp/',
|
||||
app_link_text: '@i18n:objects.otptoken.app_link'
|
||||
};
|
||||
|
||||
var make_spec = function() {
|
||||
return {
|
||||
name: 'otptoken',
|
||||
enable_test: function() {
|
||||
return true;
|
||||
},
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
$pre_ops: [
|
||||
// redefining 'add' and 'remove' actions to be shown in
|
||||
// self service
|
||||
{
|
||||
$replace: [ [ 'actions', [
|
||||
[
|
||||
'add',
|
||||
{
|
||||
$type:'add',
|
||||
name: 'add',
|
||||
hide_cond: []
|
||||
}
|
||||
],
|
||||
[
|
||||
'batch_remove',
|
||||
{
|
||||
$type: 'batch_remove',
|
||||
name: 'remove',
|
||||
hide_cond: []
|
||||
}
|
||||
]
|
||||
] ] ]
|
||||
}
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
$type: 'batch_items',
|
||||
name: 'enable',
|
||||
method: 'mod',
|
||||
options: { ipatokendisabled: false },
|
||||
needs_confirm: true,
|
||||
enable_cond: ['item-selected'],
|
||||
enabled: false,
|
||||
success_msg: '@i18n:search.enabled',
|
||||
confirm_msg: '@i18n:search.enable_confirm'
|
||||
},
|
||||
{
|
||||
$type: 'batch_items',
|
||||
name: 'disable',
|
||||
method: 'mod',
|
||||
options: { ipatokendisabled: true },
|
||||
needs_confirm: true,
|
||||
enable_cond: ['item-selected'],
|
||||
enabled: false,
|
||||
success_msg: '@i18n:search.disabled',
|
||||
confirm_msg: '@i18n:search.disable_confirm'
|
||||
},
|
||||
'delete'
|
||||
],
|
||||
control_buttons: [
|
||||
{
|
||||
name: 'disable',
|
||||
label: '@i18n:buttons.disable',
|
||||
icon: 'fa-minus'
|
||||
},
|
||||
{
|
||||
name: 'enable',
|
||||
label: '@i18n:buttons.enable',
|
||||
icon: 'fa-check'
|
||||
}
|
||||
],
|
||||
columns: [
|
||||
'ipatokenuniqueid',
|
||||
'ipatokenowner',
|
||||
{
|
||||
name: 'ipatokendisabled',
|
||||
label: '@i18n:status.label',
|
||||
formatter: {
|
||||
$type: 'boolean_status',
|
||||
invert_value: true,
|
||||
empty_value: false
|
||||
}
|
||||
},
|
||||
'description'
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
actions: [
|
||||
'select',
|
||||
{
|
||||
$type: 'object',
|
||||
name: 'otp_enable',
|
||||
label: '@i18n:objects.otptoken.enable',
|
||||
method: 'mod',
|
||||
needs_confirm: true,
|
||||
confirm_msg: '@i18n:actions.enable_confirm',
|
||||
options: { ipatokendisabled: false },
|
||||
enable_cond: ['disabled'],
|
||||
hide_cond: ['self-service']
|
||||
},
|
||||
{
|
||||
$type: 'object',
|
||||
name: 'otp_disable',
|
||||
label: '@i18n:objects.otptoken.disable',
|
||||
method: 'mod',
|
||||
needs_confirm: true,
|
||||
confirm_msg: '@i18n:actions.disable_confirm',
|
||||
options: { ipatokendisabled: true },
|
||||
enable_cond: ['enabled'],
|
||||
hide_cond: ['self-service']
|
||||
},
|
||||
'delete'
|
||||
],
|
||||
header_actions: ['otp_enable', 'otp_disable', 'delete'],
|
||||
state: {
|
||||
evaluators: [
|
||||
{
|
||||
$factory: mod_details.enable_state_evaluator,
|
||||
field: 'ipatokendisabled',
|
||||
parser: {
|
||||
$factory: IPA.boolean_formatter,
|
||||
invert_value: true,
|
||||
empty_value: false
|
||||
}
|
||||
},
|
||||
mod_facet.self_service_state_evaluator
|
||||
],
|
||||
summary_conditions: [
|
||||
mod_details.enabled_summary_cond,
|
||||
mod_details.disabled_summary_cond
|
||||
]
|
||||
},
|
||||
sections: [
|
||||
{
|
||||
name: 'details',
|
||||
label: '@i18n:objects.otptoken.details',
|
||||
fields: [
|
||||
'ipatokenuniqueid',
|
||||
'type',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
},
|
||||
{
|
||||
$type: 'entity_select',
|
||||
name: 'ipatokenowner',
|
||||
other_entity: 'user',
|
||||
other_field: 'uid'
|
||||
},
|
||||
{
|
||||
$type: 'datetime',
|
||||
name: 'ipatokennotbefore'
|
||||
},
|
||||
{
|
||||
$type: 'datetime',
|
||||
name: 'ipatokennotafter'
|
||||
},
|
||||
'ipatokenvendor',
|
||||
'ipatokenmodel',
|
||||
'ipatokenserial',
|
||||
'ipatokenotpalgorithm',
|
||||
'ipatokenotpdigits',
|
||||
{
|
||||
name: 'ipatokentotpclockoffset',
|
||||
measurement_unit: 'seconds',
|
||||
hidden_if_empty: true
|
||||
},
|
||||
{
|
||||
name: 'ipatokentotptimestep',
|
||||
measurement_unit: 'seconds',
|
||||
hidden_if_empty: true
|
||||
},
|
||||
{
|
||||
name: 'ipatokenhotpcounter',
|
||||
hidden_if_empty: true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'association',
|
||||
name: 'managedby_user',
|
||||
add_method: 'add_managedby',
|
||||
remove_method: 'remove_managedby'
|
||||
}
|
||||
],
|
||||
|
||||
adder_dialog: {
|
||||
$factory: otptoken.adder_dialog,
|
||||
$pre_ops: [
|
||||
otptoken.adder_dialog_preop
|
||||
],
|
||||
$post_ops: [
|
||||
otptoken.adder_dialog_qrcode_post_op
|
||||
],
|
||||
policies: [
|
||||
{ $factory: otptoken.adder_policy }
|
||||
],
|
||||
fields: [
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'type',
|
||||
default_value: 'totp',
|
||||
options: [
|
||||
{ label: '@i18n:objects.otptoken.type_totp', value: 'totp' },
|
||||
{ label: '@i18n:objects.otptoken.type_hotp', value: 'hotp' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'ipatokenuniqueid',
|
||||
required: false
|
||||
},
|
||||
'description',
|
||||
{// only when not self-service
|
||||
$type: 'entity_select',
|
||||
name: 'ipatokenowner',
|
||||
other_entity: 'user',
|
||||
other_field: 'uid'
|
||||
},
|
||||
{
|
||||
$type: 'datetime',
|
||||
name: 'ipatokennotbefore'
|
||||
},
|
||||
{
|
||||
$type: 'datetime',
|
||||
name: 'ipatokennotafter'
|
||||
},
|
||||
'ipatokenvendor',
|
||||
'ipatokenmodel',
|
||||
'ipatokenserial',
|
||||
'ipatokenotpkey',
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'ipatokenotpalgorithm',
|
||||
default_value: 'sha1',
|
||||
options: [
|
||||
'sha1', 'sha256', 'sha384', 'sha512'
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'ipatokenotpdigits',
|
||||
default_value: '6',
|
||||
options: ['6', '8']
|
||||
},
|
||||
{
|
||||
name: 'ipatokentotptimestep',
|
||||
measurement_unit: 'seconds'
|
||||
}
|
||||
],
|
||||
selfservice_fields: [
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'type',
|
||||
default_value: 'totp',
|
||||
options: [
|
||||
{ label: '@i18n:objects.otptoken.type_totp', value: 'totp' },
|
||||
{ label: '@i18n:objects.otptoken.type_hotp', value: 'hotp' }
|
||||
]
|
||||
},
|
||||
'description'
|
||||
]
|
||||
}
|
||||
};};
|
||||
|
||||
otptoken.adder_policy = function(spec) {
|
||||
var that = IPA.facet_policy(spec);
|
||||
that.init = function() {
|
||||
var type_f = that.container.fields.get_field('type');
|
||||
on(type_f, 'value-change', that.on_type_change);
|
||||
};
|
||||
that.on_type_change = function(args) {
|
||||
var step_f = that.container.fields.get_field('ipatokentotptimestep');
|
||||
if (!step_f) return;
|
||||
var step_w = step_f.widget;
|
||||
var is_totp = args.value[0] === 'totp';
|
||||
step_f.set_enabled(is_totp);
|
||||
step_w.set_visible(is_totp);
|
||||
};
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* OTP adder dialog pre-op.
|
||||
*
|
||||
* Switches fields to different set when in self-service.
|
||||
*/
|
||||
otptoken.adder_dialog_preop = function(spec) {
|
||||
|
||||
spec.self_service = IPA.is_selfservice;
|
||||
|
||||
if (IPA.is_selfservice) {
|
||||
spec.fields = spec.selfservice_fields;
|
||||
}
|
||||
|
||||
return spec;
|
||||
};
|
||||
|
||||
/**
|
||||
* OTP adder dialog
|
||||
*
|
||||
* @class
|
||||
* @extends IPA.entity_adder_dialog
|
||||
*/
|
||||
otptoken.adder_dialog = function(spec) {
|
||||
|
||||
var that = IPA.entity_adder_dialog(spec);
|
||||
|
||||
/**
|
||||
* Dialog sends different command options when in self-service mode.
|
||||
*/
|
||||
that.self_service = !!spec.self_service;
|
||||
|
||||
/** @inheritDoc */
|
||||
that.create_add_command = function(record) {
|
||||
|
||||
var command = that.entity_adder_dialog_create_add_command(record);
|
||||
if (that.self_service) {
|
||||
command.set_option('ipatokenowner', IPA.whoami.data.uid[0]);
|
||||
}
|
||||
return command;
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* Displays text as QR code
|
||||
* @class
|
||||
* @extends IPA.widget
|
||||
*/
|
||||
otptoken.qr_widget = function(spec) {
|
||||
|
||||
var that = IPA.widget(spec);
|
||||
|
||||
/**
|
||||
* Text to be displayed as QR Code
|
||||
* @property {string}
|
||||
* @readonly
|
||||
*/
|
||||
that.text = spec.text;
|
||||
|
||||
/**
|
||||
* Show link with the text instead of QR code
|
||||
* @property {boolean}
|
||||
*/
|
||||
that.show_link = !!spec.show_link;
|
||||
|
||||
/** @inheritDoc */
|
||||
that.create = function(container) {
|
||||
|
||||
that.widget_create(container);
|
||||
container.addClass('qrcode-widget');
|
||||
|
||||
that.div_link_control = $('<a/>', {
|
||||
name: that.name,
|
||||
href: ''
|
||||
}).appendTo(that.container);
|
||||
|
||||
that.qr_control = $('<div/>', {
|
||||
name: that.name
|
||||
}).appendTo(that.div_link_control);
|
||||
|
||||
that.uri_control = $('<div/>', {
|
||||
name: 'uri-control',
|
||||
'class': 'otp-uri',
|
||||
style: 'display: none;'
|
||||
}).appendTo(container);
|
||||
|
||||
that.link_container = $('<div/>', {
|
||||
style: 'padding: 5px 0;'
|
||||
}).appendTo(container);
|
||||
|
||||
that.show_uri_link = $('<a/>', {
|
||||
name: 'show-uri',
|
||||
href: '#',
|
||||
text: text.get('@i18n:objects.otptoken.show_uri'),
|
||||
click: function(e) {
|
||||
e.preventDefault();
|
||||
that.update_display_mode(!that.show_link);
|
||||
}
|
||||
}).appendTo(that.link_container);
|
||||
|
||||
that.qrcode = new QRCode(that.qr_control[0], {
|
||||
text: "",
|
||||
width: 450,
|
||||
height: 450,
|
||||
colorDark : "#000000",
|
||||
colorLight : "#ffffff",
|
||||
correctLevel : QRCode.CorrectLevel.M
|
||||
});
|
||||
|
||||
that.update(that.text);
|
||||
that.update_display_mode(that.show_link);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update displayed information with supplied values.
|
||||
* @param {String|Array|null} values
|
||||
*/
|
||||
that.update = function(values) {
|
||||
|
||||
var val;
|
||||
if (typeof values === 'string') {
|
||||
val = values;
|
||||
} else if (values.length) {
|
||||
val = values[0];
|
||||
} else {
|
||||
val = '';
|
||||
}
|
||||
that.text = val;
|
||||
that.qrcode.makeCode(that.text);
|
||||
that.uri_control.text(that.text);
|
||||
that.div_link_control.prop('href', that.text);
|
||||
that.emit('value-change', { source: that, value: val });
|
||||
};
|
||||
|
||||
/**
|
||||
* Switches between QR code and link
|
||||
* @protected
|
||||
* @param {boolean} show_link
|
||||
*/
|
||||
that.update_display_mode = function(show_link) {
|
||||
|
||||
that.show_link = !!show_link;
|
||||
|
||||
if (that.show_link) {
|
||||
that.show_uri_link.text(text.get('@i18n:objects.otptoken.show_qr'));
|
||||
that.qr_control.hide();
|
||||
that.uri_control.show();
|
||||
} else {
|
||||
that.show_uri_link.text(text.get('@i18n:objects.otptoken.show_uri'));
|
||||
that.qr_control.show();
|
||||
that.uri_control.hide();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
that.clear = function() {
|
||||
that.qrcode.clear();
|
||||
that.link_control.text('');
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* Displays text as QR code in a dialog
|
||||
* @class
|
||||
* @extends IPA.message_dialog
|
||||
*/
|
||||
otptoken.qr_dialog = function(spec) {
|
||||
|
||||
var that = IPA.message_dialog(spec);
|
||||
|
||||
/**
|
||||
* Uses IPA.dialog UI
|
||||
*/
|
||||
that.create_content = that.dialog_create_content;
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* OTP adder dialog post-op which enables showing of QR code after token is
|
||||
* successfully added by displaying QR dialog.
|
||||
* @member otptoken
|
||||
*/
|
||||
otptoken.adder_dialog_qrcode_post_op = function(object) {
|
||||
|
||||
object.added.attach(function(data) {
|
||||
|
||||
var uri = data.result.result.uri;
|
||||
var qr_dialog = otptoken.qr_dialog({
|
||||
name: 'qr_dialog',
|
||||
title: '@i18n:objects.otptoken.config_title',
|
||||
widgets: [
|
||||
{
|
||||
$type: 'qrcode',
|
||||
name: 'qr',
|
||||
css_class: 'col-sm-12',
|
||||
text: uri
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
qr_dialog.open();
|
||||
qr_dialog.show_message(text.get('@i18n:objects.otptoken.config_instructions'));
|
||||
if (otptoken.app_link && otptoken.app_link_text) {
|
||||
var app_text = text.get(otptoken.app_link_text);
|
||||
app_text = app_text.replace('${link}', otptoken.app_link);
|
||||
qr_dialog.show_message(app_text);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return object;
|
||||
};
|
||||
|
||||
/**
|
||||
* Entity specification object
|
||||
* @member otptoken
|
||||
*/
|
||||
otptoken.spec = make_spec();
|
||||
|
||||
/**
|
||||
* Register entity
|
||||
* @member otptoken
|
||||
*/
|
||||
otptoken.register = function() {
|
||||
var e = reg.entity;
|
||||
var w = reg.widget;
|
||||
|
||||
e.register({type: 'otptoken', spec: otptoken.spec});
|
||||
w.register('qrcode', otptoken.qr_widget);
|
||||
};
|
||||
|
||||
phases.on('registration', otptoken.register);
|
||||
|
||||
return otptoken;
|
||||
});
|
||||
36
install/ui/src/freeipa/package.json
Normal file
36
install/ui/src/freeipa/package.json
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "freeipa",
|
||||
"description": "Web UI for FreeIPA, an integrated security information management solution.",
|
||||
"version": "1.0",
|
||||
"keywords": ["FreeIPA","Identity management", "Red Hat", "Web UI"],
|
||||
"maintainers": [{
|
||||
"name": "Petr Vobornik"
|
||||
}],
|
||||
"contributors": [{
|
||||
"name": "Petr Vobornik"
|
||||
},{
|
||||
"name": "Endi Sukma Dewata"
|
||||
},{
|
||||
"name": "Adam Young"
|
||||
},{
|
||||
"name": "Pavel Zuna"
|
||||
},{
|
||||
"name": "Ana Krivokapic"
|
||||
}],
|
||||
"licenses": [{
|
||||
"type": "GPLv3",
|
||||
"url": "http://www.gnu.org/licenses/gpl-3.0.html"
|
||||
}],
|
||||
"bugs": "https://fedorahosted.org/freeipa/",
|
||||
"repositories": [{
|
||||
"type": "git",
|
||||
"url": "git://git.fedorahosted.org/git/freeipa.git ",
|
||||
"path": "install/ui/js/freeipa"
|
||||
}],
|
||||
"dependencies": {
|
||||
"dojo": "~1.8.1"
|
||||
},
|
||||
"main": "src",
|
||||
"homepage": "http://freeipa.org/",
|
||||
"dojoBuild": "freeipa.profile.js"
|
||||
}
|
||||
98
install/ui/src/freeipa/phases.js
Normal file
98
install/ui/src/freeipa/phases.js
Normal file
@@ -0,0 +1,98 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'./_base/Phase_controller'
|
||||
], function(Phase_controller) {
|
||||
|
||||
/**
|
||||
* Phases specification object.
|
||||
* @ignore
|
||||
* @property {string[]}
|
||||
*/
|
||||
var spec = {
|
||||
phases: [
|
||||
//'resource-load', // implicit phase
|
||||
'customization',
|
||||
'registration',
|
||||
'login',
|
||||
'init',
|
||||
'metadata',
|
||||
'post-metadata',
|
||||
'profile',
|
||||
'runtime',
|
||||
'shutdown'
|
||||
]
|
||||
};
|
||||
|
||||
/**
|
||||
* Phases module
|
||||
*
|
||||
* Provides access mainly serves as an registration point for
|
||||
* phase tasks. It also provides access to Phase controller.
|
||||
*
|
||||
* @class phases
|
||||
* @singleton
|
||||
*/
|
||||
var phases = {
|
||||
/**
|
||||
* Phases controller
|
||||
*/
|
||||
controller: new Phase_controller(spec),
|
||||
|
||||
/**
|
||||
* Registers a phase task
|
||||
*
|
||||
* @param {string} phase_name
|
||||
* @param {Function} handler Task handler. Should return promise if async.
|
||||
* @param {number} [priority=10]
|
||||
*/
|
||||
on: function(phase_name, handler, priority) {
|
||||
this.controller.add_task(phase_name, handler, priority);
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a phase
|
||||
*
|
||||
* Possible options:
|
||||
* before: 'name-of-phase'
|
||||
* after: 'name-of-phase'
|
||||
* position: 'position for new phase'
|
||||
*
|
||||
* @param {string} phase_name
|
||||
* @param {Object} options
|
||||
*/
|
||||
add: function(phase_name, options) {
|
||||
this.controller.add_phase(phase_name, null, options);
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if phases with given name exists
|
||||
*
|
||||
* @param {string} name
|
||||
* @return {boolean}
|
||||
*/
|
||||
exists: function(name) {
|
||||
return this.controller.exists(name);
|
||||
}
|
||||
};
|
||||
|
||||
return phases;
|
||||
});
|
||||
99
install/ui/src/freeipa/plugin_loader.js
Normal file
99
install/ui/src/freeipa/plugin_loader.js
Normal file
@@ -0,0 +1,99 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* see file 'COPYING'./for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'dojo/_base/array',
|
||||
'dojo/_base/lang',
|
||||
'dojo/Deferred',
|
||||
'dojo/promise/all'
|
||||
],function(array, lang, Deferred, all) {
|
||||
|
||||
/**
|
||||
* Plugin loader
|
||||
* @class
|
||||
* @singleton
|
||||
*/
|
||||
var plugin_loader = {
|
||||
|
||||
/**
|
||||
* Register plugins
|
||||
* @param {Array.<string>} plugins
|
||||
*/
|
||||
register_plugins: function(plugins) {
|
||||
|
||||
var packages = [];
|
||||
|
||||
array.forEach(plugins, function(name) {
|
||||
packages.push({
|
||||
name: name,
|
||||
location: 'plugins/'+name
|
||||
});
|
||||
});
|
||||
|
||||
require({ packages: packages});
|
||||
},
|
||||
|
||||
/**
|
||||
* Load plugin
|
||||
* @param {string} name
|
||||
* @return {Promise}
|
||||
*/
|
||||
load_plugin: function(name) {
|
||||
var plugin_loaded = new Deferred();
|
||||
|
||||
var mid = name+'/'+name;
|
||||
|
||||
require([mid], function(plugin) {
|
||||
plugin_loaded.resolve(plugin);
|
||||
});
|
||||
|
||||
return plugin_loaded.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Load plugins
|
||||
*
|
||||
* - loads plugin list from `freeipa/plugins` module.
|
||||
* @return {Promise}
|
||||
*/
|
||||
load_plugins: function() {
|
||||
|
||||
var plugins_loaded = new Deferred();
|
||||
|
||||
require(['freeipa/plugins'], function(plugins) {
|
||||
var loading = [];
|
||||
|
||||
this.register_plugins(plugins);
|
||||
|
||||
array.forEach(plugins, function(plugin) {
|
||||
loading.push(this.load_plugin(plugin));
|
||||
}.bind(this));
|
||||
|
||||
all(loading).then(function(results) {
|
||||
plugins_loaded.resolve(results);
|
||||
});
|
||||
}.bind(this));
|
||||
|
||||
return plugins_loaded.promise;
|
||||
}
|
||||
};
|
||||
|
||||
return plugin_loader;
|
||||
});
|
||||
1
install/ui/src/freeipa/plugins.js
Normal file
1
install/ui/src/freeipa/plugins.js
Normal file
@@ -0,0 +1 @@
|
||||
define([],function(){return[];});
|
||||
105
install/ui/src/freeipa/plugins/api_browser.js
Normal file
105
install/ui/src/freeipa/plugins/api_browser.js
Normal file
@@ -0,0 +1,105 @@
|
||||
//
|
||||
// Copyright (C) 2015 FreeIPA Contributors see COPYING for license
|
||||
//
|
||||
|
||||
define(['dojo/_base/declare',
|
||||
'dojo/on',
|
||||
'../facets/Facet',
|
||||
'../phases',
|
||||
'../reg',
|
||||
'../widget',
|
||||
'../widgets/APIBrowserWidget',
|
||||
'../builder'
|
||||
],
|
||||
|
||||
function(declare, on, Facet, phases, reg, widget,
|
||||
APIBrowserWidget, builder) {
|
||||
|
||||
|
||||
var plugins = {}; // dummy namespace object
|
||||
|
||||
/**
|
||||
* API browser plugin
|
||||
*
|
||||
* @class
|
||||
* @singleton
|
||||
*/
|
||||
plugins.api_browser = {};
|
||||
|
||||
plugins.api_browser.facet_spec = {
|
||||
name: 'apibrowser',
|
||||
'class': 'apibrowser container-fluid',
|
||||
widgets: [
|
||||
{
|
||||
$type: 'activity',
|
||||
name: 'activity',
|
||||
text: 'Working',
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
$type: 'apibrowser',
|
||||
name: 'apibrowser'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
/**
|
||||
* API browser facet
|
||||
* @class
|
||||
*/
|
||||
plugins.api_browser.APIBrowserFacet = declare([Facet], {
|
||||
|
||||
init: function(spec) {
|
||||
this.inherited(arguments);
|
||||
var browser = this.get_widget('apibrowser');
|
||||
|
||||
on(this, 'show', function(args) {
|
||||
|
||||
var state = this.get_state();
|
||||
var t = state.type;
|
||||
var n = state.name;
|
||||
|
||||
if (t && n) {
|
||||
browser.show_item(t, n);
|
||||
return;
|
||||
} else if (t) {
|
||||
if (t == 'command') {
|
||||
browser.show_default_command();
|
||||
return;
|
||||
} else {
|
||||
browser.show_default_object();
|
||||
return;
|
||||
}
|
||||
}
|
||||
browser.show_default();
|
||||
return;
|
||||
}.bind(this));
|
||||
|
||||
// Reflect item change in facet state and therefore URL hash
|
||||
browser.watch('current', function(name, old, value) {
|
||||
var state = {};
|
||||
if (value.type && value.name) {
|
||||
state = { type: value.type, name: value.name };
|
||||
}
|
||||
this.set_state(state);
|
||||
}.bind(this));
|
||||
}
|
||||
});
|
||||
|
||||
phases.on('registration', function() {
|
||||
|
||||
var fa = reg.facet;
|
||||
var w = reg.widget;
|
||||
|
||||
w.register('apibrowser', APIBrowserWidget);
|
||||
|
||||
fa.register({
|
||||
type: 'apibrowser',
|
||||
factory: plugins.api_browser.APIBrowserFacet,
|
||||
spec: plugins.api_browser.facet_spec
|
||||
});
|
||||
});
|
||||
|
||||
return plugins.api_browser;
|
||||
|
||||
});
|
||||
91
install/ui/src/freeipa/plugins/ca.js
Normal file
91
install/ui/src/freeipa/plugins/ca.js
Normal file
@@ -0,0 +1,91 @@
|
||||
//
|
||||
// Copyright (C) 2016 FreeIPA Contributors see COPYING for license
|
||||
//
|
||||
|
||||
define([
|
||||
'../ipa',
|
||||
'../jquery',
|
||||
'../phases',
|
||||
'../reg',
|
||||
'../certificate'
|
||||
],
|
||||
function(IPA, $, phases, reg, cert) {
|
||||
|
||||
/**
|
||||
* ca module
|
||||
* @class plugins.ca
|
||||
* @singleton
|
||||
*/
|
||||
var ca = IPA.ca = {};
|
||||
|
||||
var make_ca_spec = function() {
|
||||
var spec = {
|
||||
name: 'ca',
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
disable_facet_tabs: false,
|
||||
tabs_in_sidebar: true,
|
||||
tab_label: '@mo:ca.label',
|
||||
facet_groups: [cert.facet_group],
|
||||
facet_group: 'certificates',
|
||||
columns: [
|
||||
'cn',
|
||||
'ipacasubjectdn',
|
||||
'description'
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
disable_facet_tabs: true,
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
},
|
||||
'ipacaid',
|
||||
'ipacaissuerdn',
|
||||
'ipacasubjectdn'
|
||||
]
|
||||
}
|
||||
],
|
||||
adder_dialog: {
|
||||
fields: [
|
||||
{
|
||||
$type: 'text',
|
||||
name: 'cn',
|
||||
required: true
|
||||
},
|
||||
'ipacasubjectdn',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
return spec;
|
||||
};
|
||||
|
||||
/**
|
||||
* CA entity specification object
|
||||
* @member plugins.ca
|
||||
*/
|
||||
ca.ca_spec = make_ca_spec();
|
||||
|
||||
/**
|
||||
* Register entity
|
||||
* @member plugins.ca
|
||||
*/
|
||||
ca.register = function() {
|
||||
var e = reg.entity;
|
||||
|
||||
e.register({type: 'ca', spec: ca.ca_spec});
|
||||
};
|
||||
|
||||
phases.on('registration', ca.register);
|
||||
|
||||
return ca;
|
||||
});
|
||||
425
install/ui/src/freeipa/plugins/caacl.js
Normal file
425
install/ui/src/freeipa/plugins/caacl.js
Normal file
@@ -0,0 +1,425 @@
|
||||
//
|
||||
// Copyright (C) 2015 FreeIPA Contributors see COPYING for license
|
||||
//
|
||||
|
||||
define([
|
||||
'../ipa',
|
||||
'../jquery',
|
||||
'../phases',
|
||||
'../reg',
|
||||
'../certificate',
|
||||
'../rule'
|
||||
],
|
||||
function(IPA, $, phases, reg, cert) {
|
||||
/**
|
||||
* caacl module
|
||||
* @class plugins.caacl
|
||||
* @singleton
|
||||
*/
|
||||
var caacl = IPA.caacl = {
|
||||
remove_method_priority: IPA.config.default_priority - 1
|
||||
};
|
||||
|
||||
var make_caacl_spec = function() {
|
||||
var spec = {
|
||||
name: 'caacl',
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
disable_facet_tabs: false,
|
||||
tabs_in_sidebar: true,
|
||||
tab_label: '@mo:caacl.label',
|
||||
facet_groups: [cert.facet_group],
|
||||
facet_group: 'certificates',
|
||||
row_enabled_attribute: 'ipaenabledflag',
|
||||
columns: [
|
||||
'cn',
|
||||
{
|
||||
name: 'ipaenabledflag',
|
||||
label: '@i18n:status.label',
|
||||
formatter: 'boolean_status'
|
||||
},
|
||||
'description'
|
||||
],
|
||||
actions: [
|
||||
'batch_disable',
|
||||
'batch_enable'
|
||||
],
|
||||
control_buttons: [
|
||||
{
|
||||
name: 'disable',
|
||||
label: '@i18n:buttons.disable',
|
||||
icon: 'fa-minus'
|
||||
},
|
||||
{
|
||||
name: 'enable',
|
||||
label: '@i18n:buttons.enable',
|
||||
icon: 'fa-check'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
$factory: IPA.sudorule_details_facet,
|
||||
disable_facet_tabs: true,
|
||||
command_mode: 'info',
|
||||
actions: [
|
||||
'enable',
|
||||
'disable',
|
||||
'delete'
|
||||
],
|
||||
header_actions: ['enable', 'disable', 'delete'],
|
||||
state: {
|
||||
evaluators: [
|
||||
{
|
||||
$factory: IPA.enable_state_evaluator,
|
||||
field: 'ipaenabledflag'
|
||||
}
|
||||
],
|
||||
summary_conditions: [
|
||||
IPA.enabled_summary_cond,
|
||||
IPA.disabled_summary_cond
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
adder_dialog: {
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'checkboxes',
|
||||
name: 'ipacacategory',
|
||||
options: [
|
||||
{
|
||||
label: '@i18n:objects.caacl.all',
|
||||
value: 'all'
|
||||
}
|
||||
],
|
||||
tooltip: '@i18n:objects.caacl.no_ca_msg'
|
||||
},
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
add_caacl_details_facet_widgets(spec.facets[1]);
|
||||
return spec;
|
||||
};
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
* @param {Object} facet spec
|
||||
*/
|
||||
var add_caacl_details_facet_widgets = function (spec) {
|
||||
|
||||
//
|
||||
// General
|
||||
//
|
||||
|
||||
spec.fields = [
|
||||
{
|
||||
name: 'cn',
|
||||
read_only: true,
|
||||
widget: 'general.cn'
|
||||
},
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description',
|
||||
widget: 'general.description'
|
||||
}
|
||||
];
|
||||
|
||||
spec.widgets = [
|
||||
{
|
||||
$type: 'details_section',
|
||||
name: 'general',
|
||||
label: '@i18n:details.general',
|
||||
widgets: [
|
||||
{
|
||||
name: 'cn'
|
||||
},
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
//
|
||||
// Cert Profiles
|
||||
//
|
||||
|
||||
spec.fields.push(
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'ipacertprofilecategory',
|
||||
widget: 'certprofile.rule.ipacertprofilecategory'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'ipamembercertprofile_certprofile',
|
||||
widget: 'certprofile.rule.ipamembercertprofile_certprofile',
|
||||
priority: IPA.caacl.remove_method_priority
|
||||
}
|
||||
);
|
||||
|
||||
spec.widgets.push(
|
||||
{
|
||||
$factory: IPA.section,
|
||||
name: 'certprofile',
|
||||
label: '@i18n:objects.caacl.profile',
|
||||
widgets: [
|
||||
{
|
||||
$factory: IPA.rule_details_widget,
|
||||
name: 'rule',
|
||||
radio_name: 'ipacertprofilecategory',
|
||||
options: [
|
||||
{ value: 'all',
|
||||
label: '@i18n:objects.caacl.any_profile' },
|
||||
{ value: '',
|
||||
label: '@i18n:objects.caacl.specified_profiles' }
|
||||
],
|
||||
tables: [
|
||||
{ name: 'ipamembercertprofile_certprofile' }
|
||||
],
|
||||
widgets: [
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'caacl-ipamembercertprofile_certprofile',
|
||||
name: 'ipamembercertprofile_certprofile',
|
||||
add_method: 'add_profile',
|
||||
remove_method: 'remove_profile',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
//
|
||||
// Who
|
||||
//
|
||||
|
||||
spec.fields.push(
|
||||
// users
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'usercategory',
|
||||
widget: 'who.user.usercategory'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberuser_user',
|
||||
widget: 'who.user.memberuser_user',
|
||||
priority: IPA.caacl.remove_method_priority
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberuser_group',
|
||||
widget: 'who.user.memberuser_group',
|
||||
priority: IPA.caacl.remove_method_priority
|
||||
},
|
||||
|
||||
// hosts
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'hostcategory',
|
||||
widget: 'who.host.hostcategory'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberhost_host',
|
||||
widget: 'who.host.memberhost_host',
|
||||
priority: IPA.caacl.remove_method_priority
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberhost_hostgroup',
|
||||
widget: 'who.host.memberhost_hostgroup',
|
||||
priority: IPA.caacl.remove_method_priority
|
||||
},
|
||||
|
||||
// services
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'servicecategory',
|
||||
widget: 'who.service.servicecategory'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberservice_service',
|
||||
widget: 'who.service.memberservice_service',
|
||||
priority: IPA.caacl.remove_method_priority
|
||||
},
|
||||
// ca
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'ipacacategory',
|
||||
widget: 'who.ipaca.ipacacategory'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'ipamemberca_ca',
|
||||
widget: 'who.ipaca.ipamemberca_ca',
|
||||
priority: IPA.caacl.remove_method_priority
|
||||
}
|
||||
);
|
||||
|
||||
spec.widgets.push(
|
||||
{
|
||||
$factory: IPA.section,
|
||||
name: 'who',
|
||||
label: '@i18n:objects.caacl.who',
|
||||
widgets: [
|
||||
{
|
||||
$factory: IPA.rule_details_widget,
|
||||
name: 'user',
|
||||
radio_name: 'usercategory',
|
||||
options: [
|
||||
{ value: 'all',
|
||||
label: '@i18n:objects.caacl.anyone' },
|
||||
{ value: '',
|
||||
label: '@i18n:objects.caacl.specified_users' }
|
||||
],
|
||||
tables: [
|
||||
{ name: 'memberuser_user' },
|
||||
{ name: 'memberuser_group' }
|
||||
],
|
||||
widgets: [
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'caacl-memberuser_user',
|
||||
name: 'memberuser_user',
|
||||
add_method: 'add_user',
|
||||
remove_method: 'remove_user',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'caacl-memberuser_group',
|
||||
name: 'memberuser_group',
|
||||
add_method: 'add_user',
|
||||
remove_method: 'remove_user',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$factory: IPA.rule_details_widget,
|
||||
name: 'host',
|
||||
radio_name: 'hostcategory',
|
||||
options: [
|
||||
{
|
||||
'value': 'all',
|
||||
'label': '@i18n:objects.caacl.any_host'
|
||||
},
|
||||
{
|
||||
'value': '',
|
||||
'label': '@i18n:objects.caacl.specified_hosts'
|
||||
}
|
||||
],
|
||||
tables: [
|
||||
{ 'name': 'memberhost_host' },
|
||||
{ 'name': 'memberhost_hostgroup' }
|
||||
],
|
||||
widgets: [
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'caacl-memberuser_user',
|
||||
name: 'memberhost_host',
|
||||
add_method: 'add_host',
|
||||
remove_method: 'remove_host',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'caacl-memberuser_group',
|
||||
name: 'memberhost_hostgroup',
|
||||
add_method: 'add_host',
|
||||
remove_method: 'remove_host',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$factory: IPA.rule_details_widget,
|
||||
name: 'service',
|
||||
radio_name: 'servicecategory',
|
||||
options: [
|
||||
{ 'value': 'all', 'label': '@i18n:objects.caacl.any_service' },
|
||||
{ 'value': '', 'label': '@i18n:objects.caacl.specified_services' }
|
||||
],
|
||||
tables: [
|
||||
{ 'name': 'memberservice_service' }
|
||||
],
|
||||
widgets: [
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'caacl-memberservice_service',
|
||||
name: 'memberservice_service',
|
||||
add_method: 'add_service',
|
||||
remove_method: 'remove_service',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$factory: IPA.rule_details_widget,
|
||||
name: 'ipaca',
|
||||
radio_name: 'ipacacategory',
|
||||
note: '@i18n:objects.caacl.no_ca_msg',
|
||||
options: [
|
||||
{ 'value': 'all', 'label': '@i18n:objects.caacl.any_ca' },
|
||||
{ 'value': '', 'label': '@i18n:objects.caacl.specified_cas' }
|
||||
],
|
||||
tables: [
|
||||
{ 'name': 'ipamemberca_ca' }
|
||||
],
|
||||
widgets: [
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'caacl-ipamemberca_ca',
|
||||
name: 'ipamemberca_ca',
|
||||
add_method: 'add_ca',
|
||||
remove_method: 'remove_ca',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* CAACL entity specification object
|
||||
* @member plugins.caacl
|
||||
*/
|
||||
caacl.caacl_spec = make_caacl_spec();
|
||||
|
||||
|
||||
/**
|
||||
* Register entity
|
||||
* @member plugins.caacl
|
||||
*/
|
||||
caacl.register = function() {
|
||||
var e = reg.entity;
|
||||
e.register({type: 'caacl', spec: caacl.caacl_spec});
|
||||
};
|
||||
|
||||
phases.on('registration', caacl.register);
|
||||
|
||||
return caacl;
|
||||
});
|
||||
391
install/ui/src/freeipa/plugins/certmap.js
Normal file
391
install/ui/src/freeipa/plugins/certmap.js
Normal file
@@ -0,0 +1,391 @@
|
||||
//
|
||||
// Copyright (C) 2017 FreeIPA Contributors see COPYING for license
|
||||
//
|
||||
|
||||
|
||||
define([
|
||||
'dojo/_base/lang',
|
||||
'dojo/_base/declare',
|
||||
'dojo/Evented',
|
||||
'dojo/on',
|
||||
'../certificate',
|
||||
'../navigation',
|
||||
'../field',
|
||||
'../ipa',
|
||||
'../phases',
|
||||
'../reg',
|
||||
'../widget',
|
||||
'../text',
|
||||
'../util',
|
||||
// plain imports
|
||||
'../search',
|
||||
'../entity'],
|
||||
function(lang, declare, Evented, on, certificate, navigation,
|
||||
mod_field, IPA, phases, reg, widget_mod, text, util) {
|
||||
/**
|
||||
* Certificate map module
|
||||
* @class
|
||||
*/
|
||||
var certmap = IPA.certmap = {
|
||||
|
||||
search_facet_group: {
|
||||
facets: {
|
||||
certmaprule_search: 'certmaprule_search',
|
||||
certmapconfig: 'certmapconfig_details',
|
||||
certmapmatch: 'certmapmatch_details'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var make_certmaprule_spec = function() {
|
||||
return {
|
||||
name: 'certmaprule',
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
always_request_members: true,
|
||||
details_facet: 'details',
|
||||
facet_groups: [certmap.search_facet_group],
|
||||
facet_group: 'search',
|
||||
row_enabled_attribute: 'ipaenabledflag',
|
||||
columns: [
|
||||
'cn',
|
||||
{
|
||||
name: 'ipaenabledflag',
|
||||
label: '@i18n:status.label',
|
||||
formatter: 'boolean_status'
|
||||
},
|
||||
'description'
|
||||
],
|
||||
actions: [
|
||||
'batch_disable',
|
||||
'batch_enable'
|
||||
],
|
||||
control_buttons: [
|
||||
{
|
||||
name: 'disable',
|
||||
label: '@i18n:buttons.disable',
|
||||
icon: 'fa-minus'
|
||||
},
|
||||
{
|
||||
name: 'enable',
|
||||
label: '@i18n:buttons.enable',
|
||||
icon: 'fa-check'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
disable_facet_tabs: true,
|
||||
facet_groups: [certmap.search_facet_group],
|
||||
facet_group: 'search',
|
||||
actions: [
|
||||
'enable',
|
||||
'disable',
|
||||
'delete'
|
||||
],
|
||||
header_actions: ['enable', 'disable', 'delete'],
|
||||
state: {
|
||||
evaluators: [
|
||||
{
|
||||
$factory: IPA.enable_state_evaluator,
|
||||
field: 'ipaenabledflag'
|
||||
}
|
||||
]
|
||||
},
|
||||
sections: [
|
||||
{
|
||||
name: 'details',
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
},
|
||||
{
|
||||
name: 'ipacertmapmaprule',
|
||||
tooltip: {
|
||||
title: '@mc-opt:certmaprule_add:ipacertmapmaprule:doc'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'ipacertmapmatchrule',
|
||||
tooltip: {
|
||||
title: '@mc-opt:certmaprule_add:ipacertmapmatchrule:doc'
|
||||
}
|
||||
},
|
||||
{
|
||||
$type: 'multivalued',
|
||||
name: 'associateddomain',
|
||||
tooltip: {
|
||||
title: '@mc-opt:certmaprule_add:associateddomain:doc'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'ipacertmappriority',
|
||||
tooltip: {
|
||||
title: '@mc-opt:certmaprule_add:ipacertmappriority:doc'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
adder_dialog: {
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
name: 'ipacertmapmaprule',
|
||||
tooltip: {
|
||||
title: '@mc-opt:certmaprule_add:ipacertmapmaprule:doc'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'ipacertmapmatchrule',
|
||||
tooltip: {
|
||||
title: '@mc-opt:certmaprule_add:ipacertmapmatchrule:doc'
|
||||
}
|
||||
},
|
||||
{
|
||||
$type: 'multivalued',
|
||||
name: 'associateddomain',
|
||||
tooltip: {
|
||||
title: '@mc-opt:certmaprule_add:associateddomain:doc'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'ipacertmappriority',
|
||||
tooltip: {
|
||||
title: '@mc-opt:certmaprule_add:ipacertmappriority:doc'
|
||||
}
|
||||
},
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
};};
|
||||
|
||||
|
||||
var make_certmapconfig_spec = function() {
|
||||
return {
|
||||
name: 'certmapconfig',
|
||||
defines_key: false,
|
||||
facets: [
|
||||
{
|
||||
$type: 'details',
|
||||
facet_groups: [certmap.search_facet_group],
|
||||
facet_group: 'search',
|
||||
sections: [
|
||||
{
|
||||
name: 'details',
|
||||
fields: [
|
||||
{
|
||||
$type: 'checkbox',
|
||||
name: 'ipacertmappromptusername'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};};
|
||||
|
||||
|
||||
/**
|
||||
* Multivalued widget which is used for working with user's certmap.
|
||||
*
|
||||
* @class
|
||||
* @extends IPA.custom_command_multivalued_widget
|
||||
*/
|
||||
certmap.certmap_multivalued_widget = function (spec) {
|
||||
|
||||
spec = spec || {};
|
||||
spec.adder_dialog_spec = spec.adder_dialog_spec || {
|
||||
name: 'custom-add-dialog',
|
||||
title: '@i18n:objects.certmap.adder_title',
|
||||
policies: [
|
||||
{
|
||||
$factory: IPA.multiple_choice_section_policy,
|
||||
widget: 'type'
|
||||
}
|
||||
],
|
||||
fields: [
|
||||
{
|
||||
$type: 'multivalued',
|
||||
name: 'ipacertmapdata',
|
||||
label: '@i18n:objects.certmap.data_label',
|
||||
widget: 'type.ipacertmapdata'
|
||||
},
|
||||
{
|
||||
$type: 'multivalued',
|
||||
name: 'certificate',
|
||||
label: '@i18n:objects.certmap.certificate',
|
||||
widget: 'type.certificate',
|
||||
child_spec: {
|
||||
$type: 'textarea'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'issuer',
|
||||
label: '@i18n:objects.certmap.issuer',
|
||||
widget: 'type.issuer'
|
||||
},
|
||||
{
|
||||
name: 'subject',
|
||||
label: '@i18n:objects.certmap.subject',
|
||||
widget: 'type.subject'
|
||||
}
|
||||
],
|
||||
widgets: [
|
||||
{
|
||||
$type: 'multiple_choice_section',
|
||||
name: 'type',
|
||||
choices: [
|
||||
{
|
||||
name: 'data',
|
||||
label: '@i18n:objects.certmap.data_label',
|
||||
fields: ['ipacertmapdata', 'certificate'],
|
||||
required: [],
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
name: 'issuer_subj',
|
||||
label: '@i18n:objects.certmap.issuer_subject',
|
||||
fields: ['issuer', 'subject'],
|
||||
required: ['issuer', 'subject']
|
||||
}
|
||||
],
|
||||
widgets: [
|
||||
{
|
||||
$type: 'multivalued',
|
||||
name: 'ipacertmapdata'
|
||||
},
|
||||
{
|
||||
$type: 'multivalued',
|
||||
name: 'certificate',
|
||||
child_spec: {
|
||||
$type: 'textarea'
|
||||
},
|
||||
tooltip: {
|
||||
title: '@mc-opt:user_add_certmapdata:certificate:doc'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'issuer',
|
||||
tooltip: {
|
||||
title: '@mc-opt:user_add_certmapdata:issuer:doc'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'subject',
|
||||
tooltip: {
|
||||
title: '@mc-opt:user_add_certmapdata:subject:doc'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
var that = IPA.custom_command_multivalued_widget(spec);
|
||||
|
||||
that.create_remove_dialog_title = function(row) {
|
||||
return text.get('@i18n:objects.certmap.deleter_title');
|
||||
};
|
||||
|
||||
that.create_remove_dialog_message = function(row) {
|
||||
var message = text.get('@i18n:objects.certmap.deleter_content');
|
||||
message = message.replace('${data}', row.widget.new_value);
|
||||
|
||||
return message;
|
||||
};
|
||||
|
||||
/**
|
||||
* Compose options for add command.
|
||||
* @return {Object} options
|
||||
*/
|
||||
that.create_add_options = function() {
|
||||
var options = {};
|
||||
var widgets = that.adder_dialog.widgets.get_widgets();
|
||||
var widget = widgets[0];
|
||||
var inner_widgets = widget.widgets.get_widgets();
|
||||
|
||||
var normalize_certs = function(certs) {
|
||||
for (var k = 0, l = certs.length; k<l; k++) {
|
||||
certs[k] = certificate.get_base64(certs[k]);
|
||||
}
|
||||
};
|
||||
|
||||
for (var i = 0, l = inner_widgets.length; i<l; i++) {
|
||||
var w = inner_widgets[i];
|
||||
|
||||
if (w.enabled) {
|
||||
var field = that.adder_dialog.fields.get_field(w.name);
|
||||
var value = field.save();
|
||||
|
||||
if (field.name === 'issuer' || field.name === 'subject') {
|
||||
value = value[0];
|
||||
} else if (field.name === 'certificate') {
|
||||
normalize_certs(value);
|
||||
}
|
||||
|
||||
if (!util.is_empty(value)) options[field.name] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Compose options for remove command.
|
||||
*
|
||||
* @param {Object} row
|
||||
* @return {Object} options
|
||||
*/
|
||||
that.create_remove_options = function(row) {
|
||||
var options = {};
|
||||
var data = row.widget.new_value;
|
||||
|
||||
options['ipacertmapdata'] = data;
|
||||
|
||||
return options;
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* Certificat Mapping Rules entity specification object
|
||||
* @member certmap
|
||||
*/
|
||||
certmap.certmaprule_spec = make_certmaprule_spec();
|
||||
|
||||
/**
|
||||
* Certificate Mapping Configuration entity specification object
|
||||
* @member certmap
|
||||
*/
|
||||
certmap.certmapconfig_spec = make_certmapconfig_spec();
|
||||
|
||||
|
||||
/**
|
||||
* Register entity
|
||||
* @member cermap
|
||||
*/
|
||||
certmap.register = function() {
|
||||
var e = reg.entity;
|
||||
var w = reg.widget;
|
||||
|
||||
e.register({type: 'certmaprule', spec: certmap.certmaprule_spec});
|
||||
e.register({type: 'certmapconfig', spec: certmap.certmapconfig_spec});
|
||||
w.register('certmap_multivalued',
|
||||
certmap.certmap_multivalued_widget);
|
||||
};
|
||||
|
||||
phases.on('registration', certmap.register);
|
||||
|
||||
return certmap;
|
||||
});
|
||||
387
install/ui/src/freeipa/plugins/certmapmatch.js
Normal file
387
install/ui/src/freeipa/plugins/certmapmatch.js
Normal file
@@ -0,0 +1,387 @@
|
||||
//
|
||||
// Copyright (C) 2017 FreeIPA Contributors see COPYING for license
|
||||
//
|
||||
|
||||
define([
|
||||
'dojo/_base/lang',
|
||||
'dojo/_base/declare',
|
||||
'dojo/Evented',
|
||||
'dojo/on',
|
||||
'../metadata',
|
||||
'../ipa',
|
||||
'../phases',
|
||||
'../reg',
|
||||
'../rpc',
|
||||
'../widget',
|
||||
'../util',
|
||||
// plain imports
|
||||
'../search',
|
||||
'../entity'],
|
||||
function(lang, declare, Evented, on, metadata_provider, IPA, phases,
|
||||
reg, rpc, widget_mod, util ) {
|
||||
|
||||
var certmapmatch = IPA.certmapmatch = {};
|
||||
|
||||
var make_certmap_spec = function() {
|
||||
return {
|
||||
name: 'certmap_match',
|
||||
facets: [
|
||||
{
|
||||
|
||||
$factory: certmapmatch.details_certmapmatch_facet,
|
||||
disable_breadcrumb: true,
|
||||
no_update: true,
|
||||
name: 'cert',
|
||||
label: "@i18n:objects.certmap_match.facet_label",
|
||||
actions: [
|
||||
'match', 'clear'
|
||||
],
|
||||
control_buttons: [
|
||||
{
|
||||
name: 'match',
|
||||
title: '@i18n:buttons.match_title',
|
||||
label: '@i18n:buttons.match',
|
||||
icon: 'fa-gear'
|
||||
},
|
||||
{
|
||||
name: 'clear',
|
||||
title: '@i18n:buttons.clear_title',
|
||||
label: '@i18n:buttons.clear',
|
||||
icon: 'fa-refresh'
|
||||
}
|
||||
],
|
||||
sections: [
|
||||
{
|
||||
name: 'cert_input',
|
||||
label: '@i18n:objects.certmap_match.cert_for_match',
|
||||
fields: [
|
||||
{
|
||||
$type: 'cert_textarea',
|
||||
name: 'cert_textarea',
|
||||
label: '@i18n:objects.cert.certificate',
|
||||
autoload_value: false,
|
||||
undo: false,
|
||||
rows: 20,
|
||||
cols: 70
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'parsed_cert',
|
||||
label: '@i18n:objects.certmap_match.cert_data',
|
||||
fields: [
|
||||
{
|
||||
name: 'issuer',
|
||||
label: '@i18n:objects.cert.issued_by',
|
||||
adapter: {
|
||||
object_index: 0,
|
||||
result_index: 1
|
||||
},
|
||||
read_only: true
|
||||
},
|
||||
{
|
||||
name: 'subject',
|
||||
label: '@i18n:objects.cert.issued_to',
|
||||
adapter: {
|
||||
object_index: 0,
|
||||
result_index: 1
|
||||
},
|
||||
read_only: true
|
||||
},
|
||||
{
|
||||
name: 'serial_number',
|
||||
label: '@i18n:objects.cert.serial_number',
|
||||
adapter: {
|
||||
object_index: 0,
|
||||
result_index: 1
|
||||
},
|
||||
read_only: true
|
||||
},
|
||||
{
|
||||
name: 'serial_number_hex',
|
||||
label: '@i18n:objects.cert.serial_number_hex',
|
||||
adapter: {
|
||||
object_index: 0,
|
||||
result_index: 1
|
||||
},
|
||||
read_only: true
|
||||
},
|
||||
{
|
||||
name: 'valid_not_before',
|
||||
label: '@i18n:objects.cert.valid_from',
|
||||
adapter: {
|
||||
object_index: 0,
|
||||
result_index: 1
|
||||
},
|
||||
read_only: true
|
||||
},
|
||||
{
|
||||
name: 'valid_not_after',
|
||||
label: '@i18n:objects.cert.valid_to',
|
||||
adapter: {
|
||||
object_index: 0,
|
||||
result_index: 1
|
||||
},
|
||||
read_only: true
|
||||
},
|
||||
{
|
||||
name: 'sha1_fingerprint',
|
||||
label: '@i18n:objects.cert.sha1_fingerprint',
|
||||
adapter: {
|
||||
object_index: 0,
|
||||
result_index: 1
|
||||
},
|
||||
read_only: true
|
||||
},
|
||||
{
|
||||
name: 'sha256_fingerprint',
|
||||
label: '@i18n:objects.cert.sha256_fingerprint',
|
||||
adapter: {
|
||||
object_index: 0,
|
||||
result_index: 1
|
||||
},
|
||||
read_only: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$factory: IPA.section,
|
||||
name: 'divider',
|
||||
layout_css_class: 'col-sm-12 col-sm-12',
|
||||
fields: []
|
||||
},
|
||||
{
|
||||
name: 'user_result_table',
|
||||
label: '@i18n:objects.certmap_match.matched_users',
|
||||
layout: {
|
||||
$factory: widget_mod.fluid_layout,
|
||||
widget_cls: "col-sm-12 col-sm-12",
|
||||
label_cls: "hide"
|
||||
},
|
||||
layout_css_class: 'col-md-12 col-sm-12',
|
||||
fields: [
|
||||
{
|
||||
$type: 'association_table',
|
||||
name: 'result_table',
|
||||
read_only: true,
|
||||
selectable: false,
|
||||
other_entity: 'user',
|
||||
adapter: {
|
||||
$type: 'certmatch_transform'
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
name: 'uid',
|
||||
label: '@i18n:objects.certmap_match.userlogin'
|
||||
},
|
||||
{
|
||||
name: 'domain',
|
||||
label: '@i18n:objects.certmap_match.domain'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};};
|
||||
|
||||
|
||||
/**
|
||||
* Artificial entity created from command which does not have its own entity
|
||||
*
|
||||
* @class certmapmatch.certmapmatch_entity
|
||||
* @extends IPA.entity
|
||||
*/
|
||||
certmapmatch.certmapmatch_entity = function(spec) {
|
||||
var that = IPA.entity(spec);
|
||||
|
||||
that.get_default_metadata = function() {
|
||||
return metadata_provider.get('@mc:'+that.name);
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* Custom facet which is used for showing certmap match information
|
||||
*
|
||||
* @class certmapmatch.details_certmapmatch_facet
|
||||
* @extends IPA.details_facet
|
||||
*/
|
||||
certmapmatch.details_certmapmatch_facet = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.details_facet(spec);
|
||||
|
||||
that.refresh = function() {};
|
||||
|
||||
// always not dirty
|
||||
that.is_dirty = function() {
|
||||
return false;
|
||||
};
|
||||
|
||||
that.get_result_table_widget = function() {
|
||||
return that.widgets.get_widget("user_result_table.result_table");
|
||||
};
|
||||
|
||||
that.update_result_table_summary = function(summary) {
|
||||
var result_w = that.get_result_table_widget();
|
||||
result_w.summary.text(summary);
|
||||
};
|
||||
|
||||
that.clean_result = function() {
|
||||
var result_w = that.get_result_table_widget();
|
||||
result_w.empty();
|
||||
that.update_result_table_summary('');
|
||||
};
|
||||
|
||||
that.clean_cert_info = function() {
|
||||
var widgets = that.widgets.get_widget('parsed_cert').widgets.get_widgets();
|
||||
|
||||
for (var i=0, l=widgets.length; i<l; i++) {
|
||||
var widget = widgets[i];
|
||||
|
||||
widget.update();
|
||||
}
|
||||
};
|
||||
|
||||
that.obtain_cert = function() {
|
||||
var cert_w = that.widgets.get_widget('cert_input.cert_textarea');
|
||||
|
||||
return cert_w.save();
|
||||
};
|
||||
|
||||
that.on_cert_match = function(data) {
|
||||
that.clean_result();
|
||||
that.clean_cert_info();
|
||||
var cert = that.obtain_cert();
|
||||
|
||||
if (util.is_empty(cert)) return;
|
||||
|
||||
var batch_command = rpc.batch_command({
|
||||
name: 'certmap-match-batch',
|
||||
show_error: false
|
||||
});
|
||||
|
||||
var command = rpc.command({
|
||||
method: 'certmap_match',
|
||||
args: cert
|
||||
});
|
||||
|
||||
batch_command.add_command(command);
|
||||
|
||||
command = rpc.command({
|
||||
entity: 'cert',
|
||||
method: 'find',
|
||||
options: {
|
||||
certificate: cert[0],
|
||||
all: true
|
||||
}
|
||||
});
|
||||
|
||||
batch_command.add_command(command);
|
||||
|
||||
batch_command.on_success = function(data, text_status, xhr) {
|
||||
// Error handling needs to be here because cert-find never fails,
|
||||
// therefore batch_command always calls on_success method.
|
||||
var certmatch_r = data.result.results[0];
|
||||
if (certmatch_r.error === null) {
|
||||
//no error
|
||||
that.load(data);
|
||||
that.update_result_table_summary(certmatch_r.summary);
|
||||
IPA.notify_success(certmatch_r.summary);
|
||||
} else {
|
||||
that.update_result_table_summary(certmatch_r.error);
|
||||
IPA.notify(certmatch_r.error, 'error');
|
||||
}
|
||||
};
|
||||
|
||||
batch_command.execute();
|
||||
};
|
||||
|
||||
that.on_clear_facet = function() {
|
||||
that.reset();
|
||||
that.clean_result();
|
||||
that.clean_cert_info();
|
||||
};
|
||||
|
||||
that.init = function() {
|
||||
on(that, 'cert-match', that.on_cert_match);
|
||||
on(that, 'clear-facet', that.on_clear_facet);
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* Action which run certmap match.
|
||||
*
|
||||
* @class certmapmatch.match_action
|
||||
* @extends IPA.object_action
|
||||
*/
|
||||
certmapmatch.match_action = function(spec) {
|
||||
spec = spec || {};
|
||||
spec.name = spec.name || 'match';
|
||||
|
||||
var that = IPA.object_action(spec);
|
||||
|
||||
that.execute_action = function(facet) {
|
||||
facet.emit('cert-match');
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Action which allows to clean whole facet.
|
||||
*
|
||||
* @class certmapmatch.clean_action
|
||||
* @extends IPA.object_action
|
||||
*/
|
||||
certmapmatch.clear_action = function(spec) {
|
||||
spec = spec || {};
|
||||
spec.name = spec.name || 'clear';
|
||||
|
||||
var that = IPA.object_action(spec);
|
||||
|
||||
that.execute_action = function(facet) {
|
||||
facet.emit('clear-facet');
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* Certificate Mapping Configuration entity specification object
|
||||
* @member certmap
|
||||
*/
|
||||
certmapmatch.certmap_spec = make_certmap_spec();
|
||||
|
||||
|
||||
/**
|
||||
* Register entity
|
||||
* @member cermap
|
||||
*/
|
||||
certmapmatch.register = function() {
|
||||
var e = reg.entity;
|
||||
var f = reg.field;
|
||||
var a = reg.action;
|
||||
|
||||
a.register('match', certmapmatch.match_action);
|
||||
a.register('clear', certmapmatch.clear_action);
|
||||
f.register('cert_textarea', certmapmatch.cert_textarea_field);
|
||||
e.register({
|
||||
type: 'certmap_match',
|
||||
spec: certmapmatch.certmap_spec,
|
||||
factory: certmapmatch.certmapmatch_entity
|
||||
});
|
||||
};
|
||||
|
||||
phases.on('registration', certmapmatch.register);
|
||||
|
||||
return certmapmatch;
|
||||
});
|
||||
84
install/ui/src/freeipa/plugins/certprofile.js
Normal file
84
install/ui/src/freeipa/plugins/certprofile.js
Normal file
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// Copyright (C) 2015 FreeIPA Contributors see COPYING for license
|
||||
//
|
||||
|
||||
define([
|
||||
'../ipa',
|
||||
'../jquery',
|
||||
'../phases',
|
||||
'../reg',
|
||||
'../certificate'
|
||||
],
|
||||
function(IPA, $, phases, reg, cert) {
|
||||
/**
|
||||
* certprofile module
|
||||
* @class plugins.certprofile
|
||||
* @singleton
|
||||
*/
|
||||
var certprofile = IPA.certprofile = {
|
||||
};
|
||||
|
||||
var make_certprofile_spec = function() {
|
||||
return {
|
||||
name: 'certprofile',
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
$pre_ops: [
|
||||
{ $del: [[ 'control_buttons', [{ name: 'add'}] ]] }
|
||||
],
|
||||
disable_facet_tabs: false,
|
||||
tabs_in_sidebar: true,
|
||||
tab_label: '@mo:certprofile.label',
|
||||
facet_groups: [cert.facet_group],
|
||||
facet_group: 'certificates',
|
||||
columns: [
|
||||
'cn',
|
||||
'description',
|
||||
'ipacertprofilestoreissued'
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
disable_facet_tabs: true,
|
||||
sections: [
|
||||
{
|
||||
name: 'details',
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
},
|
||||
{
|
||||
$type: 'checkbox',
|
||||
name: 'ipacertprofilestoreissued'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};};
|
||||
|
||||
|
||||
/**
|
||||
* Certificate profile entity specification object
|
||||
* @member plugins.certprofile
|
||||
*/
|
||||
certprofile.certprofile_spec = make_certprofile_spec();
|
||||
|
||||
|
||||
/**
|
||||
* Register entity
|
||||
* @member plugins.certprofile
|
||||
*/
|
||||
certprofile.register = function() {
|
||||
var e = reg.entity;
|
||||
e.register({type: 'certprofile', spec: certprofile.certprofile_spec});
|
||||
};
|
||||
|
||||
phases.on('registration', certprofile.register);
|
||||
|
||||
return certprofile;
|
||||
});
|
||||
67
install/ui/src/freeipa/plugins/load_page.js
Normal file
67
install/ui/src/freeipa/plugins/load_page.js
Normal file
@@ -0,0 +1,67 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'dojo/_base/declare',
|
||||
'dojo/_base/lang',
|
||||
'dojo/on',
|
||||
'../facets/Facet',
|
||||
'../phases',
|
||||
'../reg'
|
||||
|
||||
],
|
||||
function(declare, lang, on, Facet, phases, reg) {
|
||||
|
||||
/**
|
||||
* Load Facet plugin
|
||||
*
|
||||
* @class plugins.load
|
||||
* @singleton
|
||||
*/
|
||||
var load = {};
|
||||
|
||||
load.facet_spec = {
|
||||
name: 'load',
|
||||
preferred_container: 'simple',
|
||||
requires_auth: false,
|
||||
'class': 'login-pf-body',
|
||||
widgets: [
|
||||
{
|
||||
$type: 'activity',
|
||||
name: 'activity',
|
||||
text: 'Loading',
|
||||
visible: true
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
phases.on('registration', function() {
|
||||
|
||||
var fa = reg.facet;
|
||||
|
||||
fa.register({
|
||||
type: 'load',
|
||||
factory: Facet,
|
||||
spec: load.facet_spec
|
||||
});
|
||||
});
|
||||
|
||||
return load;
|
||||
});
|
||||
100
install/ui/src/freeipa/plugins/login.js
Normal file
100
install/ui/src/freeipa/plugins/login.js
Normal file
@@ -0,0 +1,100 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define(['dojo/_base/declare',
|
||||
'dojo/_base/lang',
|
||||
'dojo/on',
|
||||
'../facets/Facet',
|
||||
'../auth',
|
||||
'../phases',
|
||||
'../reg',
|
||||
'../widget',
|
||||
'../widgets/LoginScreen'
|
||||
],
|
||||
function(declare, lang, on, Facet, auth, phases, reg, widget, LoginScreen) {
|
||||
|
||||
/**
|
||||
* Login Facet plugin
|
||||
*
|
||||
* Creates and registers a facet with login page.
|
||||
*
|
||||
* @class plugins.login
|
||||
* @singleton
|
||||
*/
|
||||
var login = {};
|
||||
|
||||
login.facet_spec = {
|
||||
name: 'login',
|
||||
preferred_container: 'simple',
|
||||
requires_auth: false,
|
||||
widgets: [
|
||||
{
|
||||
$type: 'activity',
|
||||
name: 'activity',
|
||||
text: 'Authenticating',
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
$type: 'login_screen',
|
||||
name: 'login_screen'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
login.LoginFacet = declare([Facet], {
|
||||
|
||||
can_leave: function() {
|
||||
return auth.current.authenticated;
|
||||
},
|
||||
|
||||
init: function() {
|
||||
this.inherited(arguments);
|
||||
var login_screen = this.get_widget('login_screen');
|
||||
var self = this;
|
||||
on(login_screen, 'logged_in', function(args) {
|
||||
self.emit('logged_in', args);
|
||||
});
|
||||
|
||||
on(this, 'show', function(args) {
|
||||
login_screen.refresh();
|
||||
});
|
||||
|
||||
on(login_screen, 'require-otp-sync', function(args) {
|
||||
self.emit('require-otp-sync', args);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
phases.on('registration', function() {
|
||||
|
||||
var fa = reg.facet;
|
||||
var w = reg.widget;
|
||||
|
||||
w.register('login_screen', LoginScreen);
|
||||
|
||||
fa.register({
|
||||
type: 'login',
|
||||
factory: login.LoginFacet,
|
||||
spec: login.facet_spec
|
||||
});
|
||||
});
|
||||
|
||||
return login;
|
||||
});
|
||||
61
install/ui/src/freeipa/plugins/login_process.js
Normal file
61
install/ui/src/freeipa/plugins/login_process.js
Normal file
@@ -0,0 +1,61 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2014 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'dojo/_base/lang',
|
||||
'dojo/on',
|
||||
'../ipa',
|
||||
'../app_container',
|
||||
'../reg',
|
||||
'../phases',
|
||||
'exports',
|
||||
'./login',
|
||||
'./sync_otp'], function(lang, on, IPA, app, reg, phases, login_process) {
|
||||
|
||||
/**
|
||||
* Defines switching between Sync OTP facet and Login facet.
|
||||
* @singleton
|
||||
* @class plugins.login_process
|
||||
*/
|
||||
lang.mixin(login_process, {
|
||||
|
||||
bind_login_process: function() {
|
||||
|
||||
var sync_facet = reg.facet.get('sync-otp');
|
||||
var login_facet = reg.facet.get('login');
|
||||
|
||||
on(sync_facet, 'sync-success, sync-cancel', function(args) {
|
||||
app.app.show_facet(login_facet);
|
||||
IPA.notify_success(args.message);
|
||||
});
|
||||
on(login_facet, 'require-otp-sync', function(args) {
|
||||
sync_facet.set_user(args.user);
|
||||
app.app.show_facet(sync_facet);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
phases.on('init', function() {
|
||||
login_process.bind_login_process();
|
||||
}, 15);
|
||||
|
||||
|
||||
return login_process;
|
||||
});
|
||||
103
install/ui/src/freeipa/plugins/sync_otp.js
Normal file
103
install/ui/src/freeipa/plugins/sync_otp.js
Normal file
@@ -0,0 +1,103 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define(['dojo/_base/declare',
|
||||
'dojo/_base/lang',
|
||||
'dojo/on',
|
||||
'../facets/Facet',
|
||||
'../auth',
|
||||
'../navigation',
|
||||
'../phases',
|
||||
'../reg',
|
||||
'../widget',
|
||||
'../widgets/SyncOTPScreen'
|
||||
],
|
||||
function(declare, lang, on, Facet, auth, navigation, phases, reg, widget, SyncOTPScreen) {
|
||||
|
||||
/**
|
||||
* Sync OTP Facet plugin
|
||||
*
|
||||
* Creates and registers a facet with sync otp page.
|
||||
*
|
||||
* @class plugins.sync_otp
|
||||
* @singleton
|
||||
*/
|
||||
var sync_otp = {};
|
||||
|
||||
sync_otp.facet_spec = {
|
||||
name: 'sync-otp',
|
||||
'class': 'login-pf-body',
|
||||
preferred_container: 'simple',
|
||||
requires_auth: false,
|
||||
widgets: [
|
||||
{
|
||||
$type: 'activity',
|
||||
name: 'activity',
|
||||
text: 'Synchronizing',
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
$type: 'sync_otp_screen',
|
||||
name: 'sync_screen'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
sync_otp.SyncOTPFacet = declare([Facet], {
|
||||
|
||||
init: function() {
|
||||
this.inherited(arguments);
|
||||
var sync_screen = this.get_widget('sync_screen');
|
||||
var self = this;
|
||||
on(sync_screen, 'sync-success', function(args) {
|
||||
self.emit('sync-success', args);
|
||||
});
|
||||
|
||||
on(sync_screen, 'sync-cancel', function(args) {
|
||||
self.emit('sync-cancel', args);
|
||||
});
|
||||
|
||||
on(this, 'show', function(args) {
|
||||
sync_screen.refresh();
|
||||
});
|
||||
},
|
||||
|
||||
set_user: function(user) {
|
||||
var sync_screen = this.get_widget('sync_screen');
|
||||
sync_screen.set('user', user);
|
||||
}
|
||||
});
|
||||
|
||||
phases.on('registration', function() {
|
||||
|
||||
var fa = reg.facet;
|
||||
var w = reg.widget;
|
||||
|
||||
w.register('sync_otp_screen', SyncOTPScreen);
|
||||
|
||||
fa.register({
|
||||
type: 'sync-otp',
|
||||
factory: sync_otp.SyncOTPFacet,
|
||||
spec: sync_otp.facet_spec
|
||||
});
|
||||
});
|
||||
|
||||
return sync_otp;
|
||||
});
|
||||
138
install/ui/src/freeipa/policy.js
Normal file
138
install/ui/src/freeipa/policy.js
Normal file
@@ -0,0 +1,138 @@
|
||||
/* Authors:
|
||||
* Adam Young <ayoung@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'./ipa',
|
||||
'./jquery',
|
||||
'./phases',
|
||||
'./reg',
|
||||
'./details',
|
||||
'./search',
|
||||
'./association',
|
||||
'./entity'],
|
||||
function(IPA, $, phases, reg) {
|
||||
|
||||
var exp = {};
|
||||
exp.pwpolicy = IPA.pwpolicy = {};
|
||||
|
||||
var make_pwpolicy_spec = function() {
|
||||
return {
|
||||
name: 'pwpolicy',
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
sort_enabled: false,
|
||||
columns:['cn','cospriority']
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
sections:[
|
||||
{
|
||||
name : 'identity',
|
||||
fields:[
|
||||
{
|
||||
$type: 'link',
|
||||
name: 'cn',
|
||||
other_entity: 'group'
|
||||
},
|
||||
'krbmaxpwdlife',
|
||||
'krbminpwdlife',
|
||||
{
|
||||
name: 'krbpwdhistorylength',
|
||||
measurement_unit: 'number_of_passwords'
|
||||
},
|
||||
'krbpwdmindiffchars',
|
||||
'krbpwdminlength',
|
||||
'krbpwdmaxfailure',
|
||||
{
|
||||
name: 'krbpwdfailurecountinterval',
|
||||
measurement_unit: 'seconds'
|
||||
},
|
||||
{
|
||||
name: 'krbpwdlockoutduration',
|
||||
measurement_unit: 'seconds'
|
||||
},
|
||||
{
|
||||
name: 'cospriority',
|
||||
required: true
|
||||
}
|
||||
]
|
||||
}]
|
||||
}
|
||||
],
|
||||
standard_association_facets: true,
|
||||
adder_dialog: {
|
||||
fields: [
|
||||
{
|
||||
$type: 'entity_select',
|
||||
name: 'cn',
|
||||
other_entity: 'group',
|
||||
other_field: 'cn',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: 'cospriority',
|
||||
required: true
|
||||
}
|
||||
],
|
||||
height: 300
|
||||
}
|
||||
};};
|
||||
|
||||
exp.krbtpolicy = IPA.krbtpolicy = {};
|
||||
|
||||
var make_krbtpolicy_spec = function() {
|
||||
return {
|
||||
name: 'krbtpolicy',
|
||||
facets: [
|
||||
{
|
||||
$type: 'details',
|
||||
title: '@mo:krbtpolicy.label',
|
||||
sections: [
|
||||
{
|
||||
name: 'identity',
|
||||
fields: [
|
||||
{
|
||||
name: 'krbmaxrenewableage',
|
||||
measurement_unit: 'seconds'
|
||||
},
|
||||
{
|
||||
name: 'krbmaxticketlife',
|
||||
measurement_unit: 'seconds'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
needs_update: true
|
||||
}
|
||||
]
|
||||
};};
|
||||
|
||||
exp.pwpolicy_spec = make_pwpolicy_spec();
|
||||
exp.krbtpolicy_spec = make_krbtpolicy_spec();
|
||||
exp.register = function() {
|
||||
var e = reg.entity;
|
||||
e.register({type: 'pwpolicy', spec: exp.pwpolicy_spec});
|
||||
e.register({type: 'krbtpolicy', spec: exp.krbtpolicy_spec});
|
||||
};
|
||||
phases.on('registration', exp.register);
|
||||
|
||||
return exp;
|
||||
});
|
||||
27
install/ui/src/freeipa/qrcode.js
Normal file
27
install/ui/src/freeipa/qrcode.js
Normal file
@@ -0,0 +1,27 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//
|
||||
// AMD Wrapper for QRCode.js library
|
||||
// It expects that the library was already loaded.
|
||||
//
|
||||
define(function() {
|
||||
return window.QRCode;
|
||||
});
|
||||
133
install/ui/src/freeipa/radiusproxy.js
Normal file
133
install/ui/src/freeipa/radiusproxy.js
Normal file
@@ -0,0 +1,133 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'./ipa',
|
||||
'./jquery',
|
||||
'./menu',
|
||||
'./phases',
|
||||
'./reg',
|
||||
'./details',
|
||||
'./search',
|
||||
'./entity',
|
||||
'./dialogs/password'
|
||||
],
|
||||
function(IPA, $, menu, phases, reg) {
|
||||
|
||||
/**
|
||||
* Radius module
|
||||
* @class
|
||||
* @singleton
|
||||
*/
|
||||
var radiusproxy = IPA.radiusproxy = {};
|
||||
|
||||
var make_spec = function() {
|
||||
return {
|
||||
name: 'radiusproxy',
|
||||
enable_test: function() {
|
||||
return true;
|
||||
},
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
columns: [
|
||||
'cn',
|
||||
'ipatokenradiusserver',
|
||||
'ipatokenusermapattribute',
|
||||
'description'
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
sections: [
|
||||
{
|
||||
name: 'details',
|
||||
label: '@i18n:objects.radiusproxy.details',
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
},
|
||||
{
|
||||
$type: 'multivalued',
|
||||
name: 'ipatokenradiusserver' // TODO: add validation
|
||||
},
|
||||
'ipatokenusermapattribute', // TODO: add validation
|
||||
'ipatokenradiustimeout',
|
||||
'ipatokenradiusretries'
|
||||
]
|
||||
}
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
$type: 'password',
|
||||
dialog: {
|
||||
password_name: 'ipatokenradiussecret'
|
||||
}
|
||||
}
|
||||
],
|
||||
header_actions: ['password']
|
||||
}
|
||||
],
|
||||
adder_dialog: {
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'multivalued',
|
||||
name: 'ipatokenradiusserver'
|
||||
},
|
||||
{
|
||||
$type: 'password',
|
||||
name: 'ipatokenradiussecret'
|
||||
},
|
||||
{
|
||||
$type: 'password',
|
||||
name: 'secret_verify',
|
||||
label: '@i18n:password.verify_password',
|
||||
flags: ['no_command'],
|
||||
required: true,
|
||||
validators: [{
|
||||
$type: 'same_password',
|
||||
other_field: 'ipatokenradiussecret'
|
||||
}]
|
||||
},
|
||||
'ipatokenusermapattribute'
|
||||
]
|
||||
}
|
||||
};};
|
||||
|
||||
/**
|
||||
* Radius specification object
|
||||
*/
|
||||
radiusproxy.spec = make_spec();
|
||||
|
||||
/**
|
||||
* Register radiusproxy entity
|
||||
*/
|
||||
radiusproxy.register = function() {
|
||||
var e = reg.entity;
|
||||
e.register({type: 'radiusproxy', spec: radiusproxy.spec});
|
||||
};
|
||||
|
||||
phases.on('registration', radiusproxy.register);
|
||||
|
||||
return radiusproxy;
|
||||
});
|
||||
113
install/ui/src/freeipa/realmdomains.js
Normal file
113
install/ui/src/freeipa/realmdomains.js
Normal file
@@ -0,0 +1,113 @@
|
||||
/* Authors:
|
||||
* Ana Krivokapic <akrivoka@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'./ipa',
|
||||
'./jquery',
|
||||
'./phases',
|
||||
'./reg',
|
||||
'./details',
|
||||
'./entity'],
|
||||
function (IPA, $, phases, reg) {
|
||||
|
||||
var exp = IPA.realmdomains = {};
|
||||
|
||||
var make_spec = function() {
|
||||
return {
|
||||
name: 'realmdomains',
|
||||
defines_key: false,
|
||||
facets: [
|
||||
{
|
||||
$type: 'details',
|
||||
$factory: IPA.realmdomains_details_facet,
|
||||
title: '@mo:realmdomains.label',
|
||||
sections: [
|
||||
{
|
||||
name: 'identity',
|
||||
label: '@i18n:objects.realmdomains.identity',
|
||||
fields: [
|
||||
{
|
||||
name: 'associateddomain',
|
||||
$type: 'multivalued'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
needs_update: true
|
||||
}
|
||||
]
|
||||
};};
|
||||
|
||||
IPA.realmdomains_details_facet = function (spec) {
|
||||
spec = spec || {};
|
||||
var that = IPA.details_facet(spec);
|
||||
|
||||
that.update = function (on_success, on_error) {
|
||||
var command = that.create_update_command();
|
||||
|
||||
command.on_success = function (data, text_status, xhr) {
|
||||
that.update_on_success(data, text_status, xhr);
|
||||
if (on_success) on_success.call(this, data, text_status, xhr);
|
||||
};
|
||||
|
||||
command.on_error = function (xhr, text_status, error_thrown) {
|
||||
that.update_on_error(xhr, text_status, error_thrown);
|
||||
if (on_error) on_error.call(this, xhr, text_status, error_thrown);
|
||||
};
|
||||
|
||||
var dialog = IPA.confirm_dialog({
|
||||
title: '@i18n:objects.realmdomains.check_dns',
|
||||
message: '@i18n:objects.realmdomains.check_dns_confirmation',
|
||||
ok_label: '@i18n:objects.realmdomains.check_dns',
|
||||
on_ok: function () {
|
||||
command.execute();
|
||||
}
|
||||
});
|
||||
|
||||
var cancel_button = dialog.get_button('cancel');
|
||||
dialog.buttons.remove('cancel');
|
||||
|
||||
dialog.create_button({
|
||||
name: 'force',
|
||||
label: '@i18n:objects.realmdomains.force_update',
|
||||
visible: true,
|
||||
click: function () {
|
||||
command.set_option('force', true);
|
||||
command.execute();
|
||||
dialog.close();
|
||||
}
|
||||
});
|
||||
|
||||
dialog.add_button(cancel_button);
|
||||
dialog.open();
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
exp.entity_spec = make_spec();
|
||||
exp.register = function() {
|
||||
var e = reg.entity;
|
||||
e.register({type: 'realmdomains', spec: exp.entity_spec});
|
||||
};
|
||||
phases.on('registration', exp.register);
|
||||
|
||||
return exp;
|
||||
});
|
||||
91
install/ui/src/freeipa/reg.js
Normal file
91
install/ui/src/freeipa/reg.js
Normal file
@@ -0,0 +1,91 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Registry-like object which serves as a registry of registries.
|
||||
*
|
||||
* Registry object should implement `register` and `get; method as Singleton or
|
||||
* Construct registry do. It's expected that there will be different types of
|
||||
* registries for various object types.
|
||||
*
|
||||
* Existing registries can be accessed directly by properties.
|
||||
*
|
||||
* Use set method for setting new registry.
|
||||
* Use get/registry method for getting/registering object in a registry.
|
||||
*
|
||||
* Registries should be named by their object type in singular form:
|
||||
*
|
||||
* * entity
|
||||
* * widget
|
||||
* * action
|
||||
* * formatter
|
||||
* * facet
|
||||
* * dialog
|
||||
*
|
||||
* @class reg
|
||||
* @singleton
|
||||
*/
|
||||
define(['dojo/_base/declare',
|
||||
'dojo/_base/array',
|
||||
'dojo/_base/lang',
|
||||
'./_base/Singleton_registry'
|
||||
], function(declare, array, lang, Singleton_registry) {
|
||||
|
||||
var reg = new Singleton_registry();
|
||||
reg.builder.ctor = Singleton_registry;
|
||||
|
||||
var exp = reg._map;
|
||||
|
||||
/**
|
||||
* Get registry
|
||||
* @param {string} object_type
|
||||
* @param {string} type
|
||||
* @return {_base.Construct_registry/_base.Singleton_registry}
|
||||
*/
|
||||
exp.get = function(object_type, type) {
|
||||
|
||||
var registry = reg.get(object_type);
|
||||
return registry.get(type);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create and register new registry
|
||||
* @param {string} object_type
|
||||
* @param {string} type
|
||||
* @param {Function} func
|
||||
* @param {Object} default_spec
|
||||
*/
|
||||
exp.register = function(object_type, type, func, default_spec) {
|
||||
var registry = reg.get(object_type);
|
||||
registry.register(type, func, default_spec);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set new registry
|
||||
* @param {string} object_type
|
||||
* @param {_base.Construct_registry|_base.Singleton_registry} registry
|
||||
*/
|
||||
exp.set = function(object_type, registry) {
|
||||
reg.set(object_type, registry);
|
||||
};
|
||||
|
||||
|
||||
return exp;
|
||||
});
|
||||
1109
install/ui/src/freeipa/rpc.js
Normal file
1109
install/ui/src/freeipa/rpc.js
Normal file
File diff suppressed because it is too large
Load Diff
292
install/ui/src/freeipa/rule.js
Normal file
292
install/ui/src/freeipa/rule.js
Normal file
@@ -0,0 +1,292 @@
|
||||
/* Authors:
|
||||
* Endi Sukma Dewata <edewata@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'./ipa',
|
||||
'./jquery',
|
||||
'./phases',
|
||||
'./reg',
|
||||
'./rpc',
|
||||
'./text',
|
||||
'./details',
|
||||
'./search',
|
||||
'./association',
|
||||
'./entity'],
|
||||
function(IPA, $, phases, reg, rpc, text) {
|
||||
|
||||
IPA.rule_details_widget = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.composite_widget(spec);
|
||||
|
||||
that.radio_name = spec.radio_name;
|
||||
that.options = spec.options || [];
|
||||
that.tables = spec.tables || [];
|
||||
that.columns = spec.columns;
|
||||
that.note = spec.note;
|
||||
|
||||
that.init = function() {
|
||||
|
||||
that.enable_radio = IPA.rule_radio_widget({
|
||||
name: that.radio_name,
|
||||
options: that.options,
|
||||
entity: that.entity,
|
||||
css_class: 'rule-enable-radio',
|
||||
note: that.note
|
||||
});
|
||||
|
||||
that.widgets.add_widget(that.enable_radio);
|
||||
that.enable_radio.value_changed.attach(that.on_enable_radio_changed);
|
||||
};
|
||||
|
||||
that.on_enable_radio_changed = function() {
|
||||
var value = that.enable_radio.save();
|
||||
if(value.length > 0) {
|
||||
var enabled = ('' === value[0]);
|
||||
for (var i=0; i<that.tables.length; i++) {
|
||||
var table = that.tables[i];
|
||||
|
||||
var table_widget = that.widgets.get_widget(table.name);
|
||||
table_widget.set_enabled(enabled);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
that.init();
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* Rule radio widget
|
||||
*
|
||||
* Intended to be used especially by rule widget.
|
||||
*
|
||||
* @class IPA.rule_radio_widget
|
||||
* @extends IPA.radio_widget
|
||||
*/
|
||||
IPA.rule_radio_widget = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
var that = IPA.radio_widget(spec);
|
||||
|
||||
/**
|
||||
* The text from note will be displayed after radio buttons.
|
||||
*/
|
||||
that.note = spec.note || '';
|
||||
|
||||
/** @inheritDoc */
|
||||
that.create = function(container) {
|
||||
|
||||
var param_info = IPA.get_entity_param(that.entity.name, that.name);
|
||||
var title = param_info ? param_info.doc : that.name;
|
||||
|
||||
container.append(document.createTextNode(title + ': '));
|
||||
that.widget_create(container);
|
||||
that.owb_create(container);
|
||||
if (that.undo) {
|
||||
that.create_undo(container);
|
||||
}
|
||||
|
||||
if (that.note) {
|
||||
$('<div />', {
|
||||
text: text.get(that.note),
|
||||
'class': 'rule-radio-note'
|
||||
}).appendTo(container);
|
||||
}
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
|
||||
IPA.rule_association_table_widget = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
spec.footer = spec.footer === undefined ? false : spec.footer;
|
||||
|
||||
var that = IPA.association_table_widget(spec);
|
||||
|
||||
that.external = spec.external;
|
||||
|
||||
that.setup_column = function(column, div, record) {
|
||||
var suppress_link = false;
|
||||
if (that.external) {
|
||||
suppress_link = record[that.external] === 'true';
|
||||
}
|
||||
column.setup(div, record, suppress_link);
|
||||
};
|
||||
|
||||
that.create_columns = function() {
|
||||
|
||||
if (!that.columns.length) {
|
||||
that.association_table_widget_create_columns();
|
||||
if (that.external) {
|
||||
that.create_column({
|
||||
name: that.external,
|
||||
label: '@i18n:objects.sudorule.external',
|
||||
entity: that.other_entity,
|
||||
formatter: 'boolean',
|
||||
width: '200px'
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
that.create_add_dialog = function() {
|
||||
|
||||
var entity_label = that.entity.metadata.label_singular;
|
||||
var pkey = that.facet.get_pkey();
|
||||
var other_entity_label = that.other_entity.metadata.label;
|
||||
|
||||
var title = that.add_title;
|
||||
title = title.replace('${entity}', entity_label);
|
||||
title = title.replace('${primary_key}', pkey);
|
||||
title = title.replace('${other_entity}', other_entity_label);
|
||||
|
||||
var exclude = that.values;
|
||||
if (that.external) {
|
||||
exclude = [];
|
||||
for (var i=0; i<that.values.length; i++) {
|
||||
exclude.push(that.values[i][that.name]);
|
||||
}
|
||||
}
|
||||
|
||||
return IPA.rule_association_adder_dialog({
|
||||
title: title,
|
||||
pkey: pkey,
|
||||
other_entity: that.other_entity,
|
||||
attribute_member: that.attribute_member,
|
||||
entity: that.entity,
|
||||
external: that.external,
|
||||
exclude: exclude
|
||||
});
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.rule_association_table_field = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.association_table_field(spec);
|
||||
|
||||
that.external = spec.external;
|
||||
|
||||
that.set_values_external = function(values, external) {
|
||||
|
||||
for (var i=0; i<values.length; i++) {
|
||||
|
||||
var record = values[i];
|
||||
|
||||
if (typeof record !== 'object') {
|
||||
record = {};
|
||||
record[that.param] = values[i];
|
||||
}
|
||||
|
||||
record[that.external] = external;
|
||||
|
||||
values[i] = record;
|
||||
}
|
||||
};
|
||||
|
||||
that.load = function(data) {
|
||||
that.values = that.adapter.load(data);
|
||||
|
||||
if (that.external) {
|
||||
that.set_values_external(that.values, '');
|
||||
var external_values = that.adapter.load(data, that.external, []);
|
||||
that.set_values_external(external_values, 'true');
|
||||
$.merge(that.values, external_values);
|
||||
}
|
||||
|
||||
that.widget.update(that.values);
|
||||
that.widget.unselect_all();
|
||||
};
|
||||
|
||||
that.get_update_info = function() {
|
||||
|
||||
var update_info = IPA.update_info_builder.new_update_info();
|
||||
|
||||
//association_table_widget performs basic add and remove operation
|
||||
//immediately. Rule association field test if its enabled and if not it
|
||||
//performs delete operation.
|
||||
|
||||
if (!that.widget.enabled) {
|
||||
var values = that.widget.save();
|
||||
|
||||
if (values.length > 0) { //no need to delete if has no values
|
||||
|
||||
var command = rpc.command({
|
||||
entity: that.entity.name,
|
||||
method: that.widget.remove_method,
|
||||
args: that.facet.get_pkeys()
|
||||
});
|
||||
|
||||
command.set_option(that.widget.other_entity.name, values);
|
||||
update_info.append_command(command, that.priority);
|
||||
}
|
||||
}
|
||||
|
||||
return update_info;
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.rule_association_adder_dialog = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.association_adder_dialog(spec);
|
||||
|
||||
that.external = spec.external;
|
||||
|
||||
that.add = function() {
|
||||
var rows = that.available_table.remove_selected_rows();
|
||||
that.selected_table.add_rows(rows);
|
||||
|
||||
if (that.external) {
|
||||
var pkey_name = that.other_entity.metadata.primary_key;
|
||||
var value = that.external_field.val();
|
||||
if (!value) return;
|
||||
|
||||
var record = {};
|
||||
record[pkey_name] = value;
|
||||
that.selected_table.add_record(record);
|
||||
that.external_field.val('');
|
||||
}
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
phases.on('registration', function() {
|
||||
var w = reg.widget;
|
||||
var f = reg.field;
|
||||
|
||||
w.register('rule_association_table', IPA.rule_association_table_widget);
|
||||
f.register('rule_association_table', IPA.rule_association_table_field);
|
||||
});
|
||||
|
||||
return {};
|
||||
});
|
||||
687
install/ui/src/freeipa/search.js
Normal file
687
install/ui/src/freeipa/search.js
Normal file
@@ -0,0 +1,687 @@
|
||||
/* Authors:
|
||||
* Pavel Zuna <pzuna@redhat.com>
|
||||
* Adam Young <ayoung@redhat.com>
|
||||
* Endi S. Dewata <edewata@redhat.com>
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'./builder',
|
||||
'./ipa',
|
||||
'./jquery',
|
||||
'./phases',
|
||||
'./reg',
|
||||
'./rpc',
|
||||
'./spec_util',
|
||||
'./text',
|
||||
'./facet'],
|
||||
function(builder, IPA, $, phases, reg, rpc, su, text, mod_facet) {
|
||||
|
||||
var exp = {};
|
||||
|
||||
exp.search_facet_control_buttons_pre_op = function(spec, context) {
|
||||
|
||||
var override_actions = function(cust_acts, def_acts) {
|
||||
if (!cust_acts) return def_acts;
|
||||
|
||||
var new_default_actions = [];
|
||||
for (var i=0, l=def_acts.length; i<l; i++) {
|
||||
var d_action = def_acts[i];
|
||||
|
||||
var chosen_action = d_action;
|
||||
|
||||
for (var k=0, j=cust_acts.length; k<j; k++) {
|
||||
var custom_act = cust_acts[k];
|
||||
if (custom_act === d_action || (custom_act.$type && custom_act.$type === d_action)) {
|
||||
chosen_action = custom_act;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
new_default_actions.push(chosen_action);
|
||||
}
|
||||
|
||||
return new_default_actions;
|
||||
};
|
||||
|
||||
var default_actions = ['refresh', 'batch_remove', 'add'];
|
||||
var merged_actions = override_actions(spec.custom_actions, default_actions);
|
||||
|
||||
spec.actions = merged_actions.concat(spec.actions || []);
|
||||
spec.control_buttons = spec.control_buttons || [];
|
||||
|
||||
if (!spec.no_update) {
|
||||
spec.control_buttons.unshift(
|
||||
{
|
||||
name: 'remove',
|
||||
label: '@i18n:buttons.remove',
|
||||
icon: 'fa-trash-o'
|
||||
},
|
||||
{
|
||||
name: 'add',
|
||||
label: '@i18n:buttons.add',
|
||||
icon: 'fa-plus'
|
||||
});
|
||||
}
|
||||
spec.control_buttons.unshift(
|
||||
{
|
||||
name: 'refresh',
|
||||
label: '@i18n:buttons.refresh',
|
||||
icon: 'fa-refresh'
|
||||
});
|
||||
|
||||
spec.state = spec.state || {};
|
||||
spec.state.evaluators = spec.state.evaluators || [];
|
||||
spec.state.evaluators.push(
|
||||
IPA.selected_state_evaluator,
|
||||
IPA.self_service_state_evaluator);
|
||||
return spec;
|
||||
};
|
||||
|
||||
exp.search_facet_pre_op = function(spec, context) {
|
||||
|
||||
su.context_entity(spec, context);
|
||||
var entity = reg.entity.get(spec.entity);
|
||||
|
||||
spec.name = spec.name || 'search';
|
||||
spec.title = spec.title || entity.metadata.label;
|
||||
spec.label = spec.label || entity.metadata.label;
|
||||
spec.tab_label = spec.tab_label || '@i18n:facets.search';
|
||||
|
||||
spec.managed_entity = spec.managed_entity ? IPA.get_entity(spec.managed_entity) : spec.entity;
|
||||
|
||||
spec.disable_breadcrumb =
|
||||
spec.disable_breadcrumb === undefined ? true : spec.disable_breadcrumb;
|
||||
spec.disable_facet_tabs =
|
||||
spec.disable_facet_tabs === undefined ? true : spec.disable_facet_tabs;
|
||||
|
||||
exp.search_facet_control_buttons_pre_op(spec, context);
|
||||
return spec;
|
||||
};
|
||||
|
||||
/**
|
||||
* Search facet
|
||||
* @class IPA.search_facet
|
||||
*/
|
||||
IPA.search_facet = function(spec, no_init) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.table_facet(spec, true);
|
||||
|
||||
/**
|
||||
* Additional command options which are added to refresh command on
|
||||
* refresh.
|
||||
*
|
||||
* @property {Object}
|
||||
*/
|
||||
that.command_options = spec.command_options || {};
|
||||
|
||||
that.deleter_dialog = spec.deleter_dialog;
|
||||
|
||||
that.disable_search_field = !!spec.disable_search_field;
|
||||
|
||||
that.create_header = function(container) {
|
||||
|
||||
that.facet_create_header(container);
|
||||
if (!that.disable_search_field) {
|
||||
that.create_search_filter(that.controls_left);
|
||||
}
|
||||
that.create_control_buttons(that.controls_right);
|
||||
that.create_action_dropdown(that.controls_right);
|
||||
};
|
||||
|
||||
that.create_search_filter = function(container) {
|
||||
|
||||
that.filter_container = $('<div/>', {
|
||||
'class': 'search-filter'
|
||||
}).appendTo(container);
|
||||
|
||||
that.filter = $('<input/>', {
|
||||
type: 'text',
|
||||
'class': 'form-control',
|
||||
name: 'filter',
|
||||
placeholder: text.get('@i18n:search.placeholder')
|
||||
}).appendTo(that.filter_container);
|
||||
|
||||
that.filter.keypress(function(e) {
|
||||
/* if the key pressed is the enter key */
|
||||
if (e.which == 13) {
|
||||
that.find();
|
||||
}
|
||||
});
|
||||
|
||||
that.find_button = IPA.action_button({
|
||||
name: 'find',
|
||||
icon: 'fa-search',
|
||||
click: function() {
|
||||
that.find();
|
||||
return false;
|
||||
}
|
||||
}).appendTo(that.filter_container);
|
||||
};
|
||||
|
||||
that.managed_entity_pkey_prefix = function() {
|
||||
|
||||
if (that.entity !== that.managed_entity) {
|
||||
return that.get_pkeys();
|
||||
}
|
||||
return that.get_pkey_prefix();
|
||||
};
|
||||
|
||||
that.show = function() {
|
||||
that.facet_show();
|
||||
|
||||
var filter = that.state.filter || '';
|
||||
|
||||
if (that.filter) {
|
||||
that.filter.val(filter);
|
||||
}
|
||||
};
|
||||
|
||||
that.show_add_dialog = function() {
|
||||
var dialog = that.managed_entity.get_dialog('add');
|
||||
if (!that.adder_dialog) {
|
||||
that.adder_dialog = dialog;
|
||||
dialog.added.attach(function() {
|
||||
that.refresh();
|
||||
});
|
||||
}
|
||||
dialog.pkey_prefix = that.managed_entity_pkey_prefix();
|
||||
dialog.open();
|
||||
};
|
||||
|
||||
that.create_remove_dialog = function() {
|
||||
var values = that.get_selected_values();
|
||||
|
||||
var title;
|
||||
if (!values.length) {
|
||||
title = text.get('@i18n:dialogs.remove_empty');
|
||||
window.alert(title);
|
||||
return null;
|
||||
}
|
||||
|
||||
var dialog = builder.build('', that.deleter_dialog);
|
||||
if (!dialog) {
|
||||
dialog = that.managed_entity.get_dialog('remove');
|
||||
}
|
||||
if (!dialog) {
|
||||
dialog = IPA.search_deleter_dialog();
|
||||
}
|
||||
|
||||
dialog.entity_name = that.managed_entity.name;
|
||||
dialog.entity = that.managed_entity;
|
||||
dialog.facet = that;
|
||||
dialog.pkey_prefix = that.managed_entity_pkey_prefix();
|
||||
|
||||
title = text.get('@i18n:dialogs.remove_title');
|
||||
var label = that.managed_entity.metadata.label;
|
||||
dialog.title = title.replace('${entity}', label);
|
||||
|
||||
dialog.set_values(values);
|
||||
|
||||
return dialog;
|
||||
};
|
||||
|
||||
that.show_remove_dialog = function() {
|
||||
|
||||
var dialog = that.create_remove_dialog();
|
||||
if (dialog) {
|
||||
dialog.open();
|
||||
} else {
|
||||
window.console.log("Remove dialog was not created properly.");
|
||||
}
|
||||
};
|
||||
|
||||
that.find = function() {
|
||||
var filter = that.filter.val();
|
||||
var old_filter = that.state.filter;
|
||||
var state = {};
|
||||
state[that.managed_entity.name + '-filter'] = filter;
|
||||
|
||||
if (filter !== old_filter) that.set_expired_flag();
|
||||
|
||||
that.state.set({filter: filter});
|
||||
};
|
||||
|
||||
that.get_search_command_name = function() {
|
||||
var name = that.managed_entity.name + '_find';
|
||||
if (that.pagination && !that.search_all_entries) {
|
||||
name += '_pkeys';
|
||||
}
|
||||
return name;
|
||||
};
|
||||
|
||||
that.get_refresh_command_args = function() {
|
||||
|
||||
var filter = that.state.filter || '';
|
||||
var args = that.managed_entity_pkey_prefix();
|
||||
args.push(filter);
|
||||
return args;
|
||||
};
|
||||
|
||||
/**
|
||||
* Provide RPC options for refresh command
|
||||
* - override point
|
||||
*/
|
||||
that.get_refresh_command_options = function() {
|
||||
|
||||
return that.command_options;
|
||||
};
|
||||
|
||||
that.create_refresh_command = function() {
|
||||
|
||||
var args = that.get_refresh_command_args();
|
||||
|
||||
var command = rpc.command({
|
||||
name: that.get_search_command_name(),
|
||||
entity: that.managed_entity.name,
|
||||
method: 'find',
|
||||
args: args
|
||||
});
|
||||
|
||||
command.set_options(that.get_refresh_command_options());
|
||||
|
||||
if (that.pagination) {
|
||||
if (!that.search_all_entries) command.set_option('pkey_only', true);
|
||||
command.set_option('sizelimit', 0);
|
||||
}
|
||||
|
||||
return command;
|
||||
};
|
||||
|
||||
that.refresh = function() {
|
||||
|
||||
var command = that.create_refresh_command();
|
||||
|
||||
command.on_success = function(data, text_status, xhr) {
|
||||
if (!IPA.opened_dialogs.dialogs.length &&
|
||||
!that.disable_search_field) {
|
||||
that.filter.focus();
|
||||
}
|
||||
that.load(data);
|
||||
that.show_content();
|
||||
};
|
||||
|
||||
command.on_error = function(xhr, text_status, error_thrown) {
|
||||
that.report_error(error_thrown);
|
||||
};
|
||||
|
||||
command.execute();
|
||||
};
|
||||
|
||||
that.clear = function() {
|
||||
if (that.needs_clear()) {
|
||||
that.table.clear();
|
||||
}
|
||||
};
|
||||
|
||||
that.needs_clear = function() {
|
||||
var clear = false;
|
||||
|
||||
var filter = that.state.filter;
|
||||
clear = that.old_filter !== '' || that.old_filter !== filter;
|
||||
|
||||
var pkeys = that.get_pkeys();
|
||||
clear = clear || IPA.array_diff(pkeys, that.old_pkeys);
|
||||
|
||||
return clear;
|
||||
};
|
||||
|
||||
that.init_search_facet = function() {
|
||||
|
||||
that.init_facet();
|
||||
that.init_table_columns();
|
||||
that.init_table(that.managed_entity);
|
||||
that.policies.init();
|
||||
};
|
||||
|
||||
if (!no_init) that.init_search_facet();
|
||||
|
||||
// methods that should be invoked by subclasses
|
||||
that.search_facet_refresh = that.refresh;
|
||||
that.search_facet_create_refresh_command = that.create_refresh_command;
|
||||
that.search_facet_create_remove_dialog = that.create_remove_dialog;
|
||||
that.search_facet_create_header = that.create_header;
|
||||
that.search_facet_show = that.show;
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.search_deleter_dialog = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.deleter_dialog(spec);
|
||||
that.pkey_prefix = spec.pkey_prefix || [];
|
||||
|
||||
/**
|
||||
* List of attributes from table from search facet, which
|
||||
* are added to remove command as options. In case that there is not column
|
||||
* with this name, then the option is skipped
|
||||
*
|
||||
* @property {String}
|
||||
*/
|
||||
that.additional_table_attrs = spec.additional_table_attrs || [];
|
||||
|
||||
that.create_command = function() {
|
||||
var batch = rpc.batch_command({
|
||||
error_message: '@i18n:search.partial_delete',
|
||||
name: that.entity.name + '_batch_del'
|
||||
});
|
||||
|
||||
for (var i=0; i<that.values.length; i++) {
|
||||
var command = rpc.command({
|
||||
entity: that.entity.name,
|
||||
method: 'del'
|
||||
});
|
||||
|
||||
if (that.pkey_prefix.length) command.add_args(that.pkey_prefix);
|
||||
|
||||
var value = that.values[i];
|
||||
if (value instanceof Object) {
|
||||
for (var key in value) {
|
||||
if (value.hasOwnProperty(key)) {
|
||||
if (key === 'pkey'){
|
||||
value = value[key];
|
||||
command.add_arg(value);
|
||||
} else {
|
||||
command.set_option(key, value[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
command.add_arg(value);
|
||||
}
|
||||
|
||||
var add_attrs = that.additional_table_attrs;
|
||||
if (add_attrs && add_attrs.length && add_attrs.length > 0) {
|
||||
command = that.extend_command(command, add_attrs, value);
|
||||
}
|
||||
|
||||
batch.add_command(command);
|
||||
}
|
||||
|
||||
return batch;
|
||||
};
|
||||
|
||||
that.execute = function() {
|
||||
|
||||
var batch = that.create_command();
|
||||
|
||||
batch.on_success = function(data, text_status, xhr) {
|
||||
that.facet.refresh();
|
||||
that.facet.on_update.notify([],that.facet);
|
||||
that.facet.table.unselect_all();
|
||||
var succeeded = batch.commands.length - batch.errors.errors.length;
|
||||
var msg = text.get('@i18n:search.deleted').replace('${count}', succeeded);
|
||||
IPA.notify_success(msg);
|
||||
};
|
||||
|
||||
batch.on_error = function() {
|
||||
that.facet.refresh();
|
||||
};
|
||||
|
||||
batch.execute();
|
||||
};
|
||||
|
||||
that.extend_command = function(command, add_attrs, pkey) {
|
||||
var records = that.facet.fetch_records();
|
||||
var pkey_name = that.entity.metadata.primary_key;
|
||||
|
||||
for (var i=0,l=records.length; i<l; i++) {
|
||||
var record = records[i];
|
||||
var curr_pkey = record[pkey_name][0];
|
||||
if (curr_pkey && curr_pkey === pkey) {
|
||||
for (var j=0,k=add_attrs.length; j<k; j++) {
|
||||
var attr = add_attrs[j];
|
||||
var val = record[attr];
|
||||
if (val) command.set_option(attr, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return command;
|
||||
};
|
||||
|
||||
that.search_deleter_dialog_create_command = that.create_command;
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
exp.nested_search_facet_preop = function(spec, context) {
|
||||
|
||||
su.context_entity(spec, context);
|
||||
var entity = reg.entity.get(spec.entity);
|
||||
|
||||
spec.name = spec.name || 'search';
|
||||
spec.title = spec.title || entity.metadata.label_singular;
|
||||
spec.label = spec.label || entity.metadata.label;
|
||||
spec.tab_label = spec.tab_label || '@i18n:facets.search';
|
||||
|
||||
spec.managed_entity = spec.nested_entity;
|
||||
|
||||
spec.disable_breadcrumb = false;
|
||||
spec.disable_facet_tabs = false;
|
||||
|
||||
exp.search_facet_control_buttons_pre_op(spec, context);
|
||||
return spec;
|
||||
};
|
||||
|
||||
/*TODO. this has much copied code from above. Refactor the search_facet
|
||||
To either be nested or not nested. */
|
||||
exp.nested_search_facet = IPA.nested_search_facet = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.search_facet(spec);
|
||||
|
||||
that.show = function() {
|
||||
that.facet_show();
|
||||
var pkey = that.get_pkey();
|
||||
that.header.set_pkey(pkey);
|
||||
var filter = that.state.filter || '';
|
||||
if (that.filter) {
|
||||
that.filter.val(filter);
|
||||
}
|
||||
};
|
||||
|
||||
that.refresh = function() {
|
||||
|
||||
var pkey = that.get_pkey();
|
||||
|
||||
if ((!pkey) && (that.entity.redirect_facet)) {
|
||||
that.redirect();
|
||||
return;
|
||||
}
|
||||
|
||||
that.search_facet_refresh();
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.batch_remove_action = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
spec.name = spec.name || 'remove';
|
||||
spec.label = spec.label || '@i18n:buttons.remove';
|
||||
spec.enable_cond = spec.enable_cond || ['item-selected'];
|
||||
spec.enabled = spec.enabled === undefined ? false : spec.enabled;
|
||||
spec.hide_cond = spec.hide_cond || ['self-service'];
|
||||
|
||||
var that = IPA.action(spec);
|
||||
|
||||
that.execute_action = function(facet) {
|
||||
facet.show_remove_dialog();
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.add_action = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
spec.name = spec.name || 'add';
|
||||
spec.label = spec.label || '@i18n:buttons.add';
|
||||
spec.hide_cond = spec.hide_cond || ['self-service'];
|
||||
|
||||
var that = IPA.action(spec);
|
||||
|
||||
that.execute_action = function(facet) {
|
||||
facet.show_add_dialog();
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
/*
|
||||
* Calls entity's disable command for each selected item in a batch.
|
||||
* Usable in table facets.
|
||||
*/
|
||||
IPA.batch_items_action = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.action(spec);
|
||||
|
||||
that.method = spec.method || 'disable';
|
||||
that.success_msg = text.get(spec.success_msg);
|
||||
that.options = spec.options || {};
|
||||
|
||||
that.execute_action = function(facet, on_success, on_error) {
|
||||
|
||||
var entity = facet.managed_entity;
|
||||
var selected_keys = facet.get_selected_values();
|
||||
var pkeys = facet.get_pkeys();
|
||||
if (!pkeys[0]) pkeys = []; // correction for search facet
|
||||
|
||||
that.batch = rpc.batch_command({
|
||||
name: entity.name + '_batch_'+ that.method,
|
||||
on_success: that.get_on_success(facet, on_success)
|
||||
});
|
||||
|
||||
for (var i=0; i<selected_keys.length; i++) {
|
||||
var item_keys = pkeys.splice(0);
|
||||
item_keys.push(selected_keys[i]);
|
||||
|
||||
var command = that.create_action_command(facet, item_keys);
|
||||
that.batch.add_command(command);
|
||||
}
|
||||
|
||||
that.batch.execute();
|
||||
};
|
||||
|
||||
that.create_action_command = function(facet, keys) {
|
||||
var command = rpc.command({
|
||||
entity: facet.managed_entity.name,
|
||||
method: that.method,
|
||||
args: keys,
|
||||
options: that.options
|
||||
});
|
||||
return command;
|
||||
};
|
||||
|
||||
that.on_success = function(facet, data, text_status, xhr) {
|
||||
facet.on_update.notify();
|
||||
facet.refresh();
|
||||
facet.table.unselect_all();
|
||||
|
||||
if (that.success_msg) {
|
||||
var succeeded = that.batch.commands.length - that.batch.errors.errors.length;
|
||||
var msg = that.success_msg.replace('${count}', succeeded);
|
||||
IPA.notify_success(msg);
|
||||
}
|
||||
};
|
||||
|
||||
that.get_on_success = function(facet, on_success) {
|
||||
return function(data, text_status, xhr) {
|
||||
that.on_success(facet, data, text_status, xhr);
|
||||
if (on_success) on_success.call(this, data, text_status, xhr);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.batch_disable_action = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
spec.name = spec.name || 'disable';
|
||||
spec.method = spec.method || 'disable';
|
||||
spec.needs_confirm = spec.needs_confirm === undefined ? true : spec.needs_confirm;
|
||||
spec.enable_cond = spec.enable_cond || ['item-selected'];
|
||||
spec.enabled = spec.enabled === undefined ? false : spec.enabled;
|
||||
spec.success_msg = spec.success_msg || '@i18n:search.disabled';
|
||||
spec.confirm_msg = spec.confirm_msg || '@i18n:search.disable_confirm';
|
||||
|
||||
return IPA.batch_items_action(spec);
|
||||
};
|
||||
|
||||
IPA.batch_enable_action = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
spec.name = spec.name || 'enable';
|
||||
spec.method = spec.method || 'enable';
|
||||
spec.needs_confirm = spec.needs_confirm === undefined ? true : spec.needs_confirm;
|
||||
spec.enabled = spec.enabled === undefined ? false : spec.enabled;
|
||||
spec.enable_cond = spec.enable_cond || ['item-selected'];
|
||||
spec.success_msg = spec.success_msg || '@i18n:search.enabled';
|
||||
spec.confirm_msg = spec.confirm_msg || '@i18n:search.enable_confirm';
|
||||
|
||||
return IPA.batch_items_action(spec);
|
||||
};
|
||||
|
||||
exp.register = function() {
|
||||
|
||||
var a = reg.action;
|
||||
var f = reg.facet;
|
||||
|
||||
a.register('batch_remove', IPA.batch_remove_action);
|
||||
a.register('add', IPA.add_action);
|
||||
a.register('batch_items', IPA.batch_items_action);
|
||||
a.register('batch_disable', IPA.batch_disable_action);
|
||||
a.register('batch_enable', IPA.batch_enable_action);
|
||||
|
||||
f.register({
|
||||
type: 'search',
|
||||
factory: IPA.search_facet,
|
||||
pre_ops: [
|
||||
exp.search_facet_pre_op
|
||||
],
|
||||
spec: { name: 'search' }
|
||||
});
|
||||
|
||||
f.register({
|
||||
type: 'nested_search',
|
||||
factory: IPA.nested_search_facet,
|
||||
pre_ops: [
|
||||
exp.nested_search_facet_preop
|
||||
],
|
||||
spec: { name: 'nestedsearch' }
|
||||
});
|
||||
};
|
||||
|
||||
phases.on('registration', exp.register);
|
||||
|
||||
return exp;
|
||||
});
|
||||
337
install/ui/src/freeipa/selinux.js
Normal file
337
install/ui/src/freeipa/selinux.js
Normal file
@@ -0,0 +1,337 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'./ipa',
|
||||
'./jquery',
|
||||
'./phases',
|
||||
'./reg',
|
||||
'./association',
|
||||
'./entity',
|
||||
'./details',
|
||||
'./rule',
|
||||
'./search'
|
||||
],
|
||||
function(IPA, $, phases, reg) {
|
||||
|
||||
var exp = IPA.selinux = {
|
||||
remove_method_priority: IPA.config.default_priority - 1
|
||||
};
|
||||
|
||||
var make_spec = function() {
|
||||
var spec = {
|
||||
name: 'selinuxusermap',
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
row_enabled_attribute: 'ipaenabledflag',
|
||||
columns: [
|
||||
'cn',
|
||||
'ipaselinuxuser',
|
||||
{
|
||||
name: 'ipaenabledflag',
|
||||
label: '@i18n:status.label',
|
||||
formatter: 'boolean_status'
|
||||
},
|
||||
'description'
|
||||
],
|
||||
actions: [
|
||||
'batch_disable',
|
||||
'batch_enable'
|
||||
],
|
||||
control_buttons: [
|
||||
{
|
||||
name: 'disable',
|
||||
label: '@i18n:buttons.disable',
|
||||
icon: 'fa-minus'
|
||||
},
|
||||
{
|
||||
name: 'enable',
|
||||
label: '@i18n:buttons.enable',
|
||||
icon: 'fa-check'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
$factory: IPA.selinux_details_facet,
|
||||
command_mode: 'info',
|
||||
actions: [
|
||||
'select',
|
||||
'enable',
|
||||
'disable',
|
||||
'delete'
|
||||
],
|
||||
header_actions: ['enable', 'disable', 'delete'],
|
||||
state: {
|
||||
evaluators: [
|
||||
{
|
||||
$factory: IPA.enable_state_evaluator,
|
||||
field: 'ipaenabledflag'
|
||||
}
|
||||
],
|
||||
summary_conditions: [
|
||||
IPA.enabled_summary_cond,
|
||||
IPA.disabled_summary_cond
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
adder_dialog: {
|
||||
fields: [
|
||||
'cn',
|
||||
'ipaselinuxuser'
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
add_selinux_details_facet_widgets(spec.facets[1]);
|
||||
return spec;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
* @param {Object} facet spec
|
||||
*/
|
||||
var add_selinux_details_facet_widgets = function (spec) {
|
||||
|
||||
//
|
||||
// General
|
||||
//
|
||||
|
||||
spec.fields = [
|
||||
{
|
||||
name: 'cn',
|
||||
read_only: true,
|
||||
widget: 'general.cn'
|
||||
},
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description',
|
||||
widget: 'general.description'
|
||||
},
|
||||
{
|
||||
name: 'ipaselinuxuser',
|
||||
widget: 'general.ipaselinuxuser'
|
||||
},
|
||||
{
|
||||
$type: 'entity_select',
|
||||
name: 'seealso',
|
||||
widget: 'general.seealso'
|
||||
}
|
||||
];
|
||||
|
||||
spec.widgets = [
|
||||
{
|
||||
$type: 'details_section',
|
||||
name: 'general',
|
||||
label: '@i18n:details.general',
|
||||
widgets: [
|
||||
{
|
||||
name: 'cn'
|
||||
},
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
},
|
||||
{
|
||||
name: 'ipaselinuxuser',
|
||||
widget: 'general.ipaselinuxuser'
|
||||
},
|
||||
{
|
||||
$type: 'entity_select',
|
||||
name: 'seealso',
|
||||
other_entity: 'hbacrule',
|
||||
other_field: 'cn'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
//
|
||||
// Users
|
||||
//
|
||||
|
||||
spec.fields.push(
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'usercategory',
|
||||
widget: 'user.rule.usercategory'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberuser_user',
|
||||
widget: 'user.rule.memberuser_user',
|
||||
priority: IPA.selinux.remove_method_priority
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberuser_group',
|
||||
widget: 'user.rule.memberuser_group',
|
||||
priority: IPA.selinux.remove_method_priority
|
||||
}
|
||||
);
|
||||
|
||||
spec.widgets.push(
|
||||
{
|
||||
$factory: IPA.section,
|
||||
name: 'user',
|
||||
label: '@i18n:objects.selinuxusermap.user',
|
||||
widgets: [
|
||||
{
|
||||
$factory: IPA.rule_details_widget,
|
||||
name: 'rule',
|
||||
radio_name: 'usercategory',
|
||||
options: [
|
||||
{ value: 'all',
|
||||
label: '@i18n:objects.selinuxusermap.anyone' },
|
||||
{ value: '',
|
||||
label: '@i18n:objects.selinuxusermap.specified_users' }
|
||||
],
|
||||
tables: [
|
||||
{ name: 'memberuser_user' },
|
||||
{ name: 'memberuser_group' }
|
||||
],
|
||||
widgets: [
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'selinuxusermap-memberuser_user',
|
||||
name: 'memberuser_user',
|
||||
add_method: 'add_user',
|
||||
remove_method: 'remove_user',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'selinuxusermap-memberuser_group',
|
||||
name: 'memberuser_group',
|
||||
add_method: 'add_user',
|
||||
remove_method: 'remove_user',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
//
|
||||
// Hosts
|
||||
//
|
||||
|
||||
spec.fields.push(
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'hostcategory',
|
||||
widget: 'host.rule.hostcategory'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberhost_host',
|
||||
widget: 'host.rule.memberhost_host',
|
||||
priority: IPA.selinux.remove_method_priority
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberhost_hostgroup',
|
||||
widget: 'host.rule.memberhost_hostgroup',
|
||||
priority: IPA.selinux.remove_method_priority
|
||||
}
|
||||
);
|
||||
|
||||
spec.widgets.push(
|
||||
{
|
||||
$factory: IPA.section,
|
||||
name: 'host',
|
||||
label: '@i18n:objects.selinuxusermap.host',
|
||||
widgets: [
|
||||
{
|
||||
$factory: IPA.rule_details_widget,
|
||||
name: 'rule',
|
||||
radio_name: 'hostcategory',
|
||||
options: [
|
||||
{
|
||||
'value': 'all',
|
||||
label: '@i18n:objects.selinuxusermap.any_host'
|
||||
},
|
||||
{
|
||||
'value': '',
|
||||
label: '@i18n:objects.selinuxusermap.specified_hosts'
|
||||
}
|
||||
],
|
||||
tables: [
|
||||
{ 'name': 'memberhost_host' },
|
||||
{ 'name': 'memberhost_hostgroup' }
|
||||
],
|
||||
widgets: [
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'selinuxusermap-memberuser_user',
|
||||
name: 'memberhost_host',
|
||||
add_method: 'add_host',
|
||||
remove_method: 'remove_host',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'selinuxusermap-memberuser_group',
|
||||
name: 'memberhost_hostgroup',
|
||||
add_method: 'add_host',
|
||||
remove_method: 'remove_host',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
IPA.selinux_details_facet = function(spec) {
|
||||
|
||||
var that = IPA.details_facet(spec);
|
||||
|
||||
that.update_on_success = function(data, text_status, xhr) {
|
||||
that.refresh();
|
||||
that.on_update.notify();
|
||||
that.nofify_update_success();
|
||||
};
|
||||
|
||||
that.update_on_error = function(xhr, text_status, error_thrown) {
|
||||
that.refresh();
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
exp.entity_spec = make_spec();
|
||||
exp.register = function() {
|
||||
var e = reg.entity;
|
||||
e.register({type: 'selinuxusermap', spec: exp.entity_spec});
|
||||
};
|
||||
phases.on('registration', exp.register);
|
||||
|
||||
return exp;
|
||||
});
|
||||
156
install/ui/src/freeipa/serverconfig.js
Normal file
156
install/ui/src/freeipa/serverconfig.js
Normal file
@@ -0,0 +1,156 @@
|
||||
/* Authors:
|
||||
* Endi Sukma Dewata <edewata@redhat.com>
|
||||
* Adam Young <ayoung@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'./ipa',
|
||||
'./jquery',
|
||||
'./phases',
|
||||
'./reg',
|
||||
'./details',
|
||||
'./search',
|
||||
'./association',
|
||||
'./entity'],
|
||||
function(IPA, $, phases, reg) {
|
||||
|
||||
var exp = IPA.serverconfig = {};
|
||||
|
||||
var make_spec = function() {
|
||||
return {
|
||||
name: 'config',
|
||||
defines_key: false,
|
||||
facets: [
|
||||
{
|
||||
$type: 'details',
|
||||
title: '@mo:config.label',
|
||||
sections: [
|
||||
{
|
||||
name: 'search',
|
||||
label: '@i18n:objects.config.search',
|
||||
fields: [
|
||||
'ipasearchrecordslimit',
|
||||
'ipasearchtimelimit'
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'user',
|
||||
label: '@i18n:objects.config.user',
|
||||
fields: [
|
||||
'ipausersearchfields',
|
||||
'ipadefaultemaildomain',
|
||||
{
|
||||
name: 'ipadomainresolutionorder',
|
||||
tooltip: '@mc-opt:config_mod:ipadomainresolutionorder:doc'
|
||||
},
|
||||
{
|
||||
$type: 'entity_select',
|
||||
name: 'ipadefaultprimarygroup',
|
||||
other_entity: 'group',
|
||||
other_field: 'cn'
|
||||
},
|
||||
'ipahomesrootdir',
|
||||
'ipadefaultloginshell',
|
||||
'ipamaxusernamelength',
|
||||
'ipapwdexpadvnotify',
|
||||
{
|
||||
name: 'ipaconfigstring',
|
||||
$type: 'checkboxes',
|
||||
options: IPA.create_options([
|
||||
'AllowNThash',
|
||||
'KDC:Disable Last Success', 'KDC:Disable Lockout'
|
||||
])
|
||||
},
|
||||
{
|
||||
$type: 'checkboxes',
|
||||
name: 'ipauserauthtype',
|
||||
flags: ['w_if_no_aci'],
|
||||
options: [
|
||||
{ label: '@i18n:authtype.type_disabled', value: 'disabled' },
|
||||
{ label: '@i18n:authtype.type_password', value: 'password' },
|
||||
{ label: '@i18n:authtype.type_radius', value: 'radius' },
|
||||
{ label: '@i18n:authtype.type_otp', value: 'otp' }
|
||||
],
|
||||
tooltip: {
|
||||
title: '@i18n:authtype.config_tooltip',
|
||||
html: true
|
||||
}
|
||||
},
|
||||
{
|
||||
$type: 'checkbox',
|
||||
name: 'ipamigrationenabled'
|
||||
},
|
||||
{
|
||||
$type: 'multivalued',
|
||||
name: 'ipauserobjectclasses'
|
||||
},
|
||||
{
|
||||
$type: 'entity_select',
|
||||
name: 'ca_renewal_master_server',
|
||||
other_entity: 'server',
|
||||
other_field: 'cn',
|
||||
flags: ['w_if_no_aci']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'group',
|
||||
label: '@i18n:objects.config.group',
|
||||
fields: [
|
||||
'ipagroupsearchfields',
|
||||
{
|
||||
$type: 'multivalued',
|
||||
name: 'ipagroupobjectclasses'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'selinux',
|
||||
label: '@i18n:objects.config.selinux',
|
||||
fields: [
|
||||
'ipaselinuxusermaporder',
|
||||
'ipaselinuxusermapdefault'
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'service',
|
||||
label: '@i18n:objects.config.service',
|
||||
fields: [
|
||||
{
|
||||
name: 'ipakrbauthzdata',
|
||||
$type: 'checkboxes',
|
||||
options: IPA.create_options(['MS-PAC', 'PAD', 'nfs:NONE'])
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
needs_update: true
|
||||
}
|
||||
]
|
||||
};};
|
||||
|
||||
exp.entity_spec = make_spec();
|
||||
exp.register = function() {
|
||||
var e = reg.entity;
|
||||
e.register({type: 'config', spec: exp.entity_spec});
|
||||
};
|
||||
phases.on('registration', exp.register);
|
||||
|
||||
return {};
|
||||
});
|
||||
757
install/ui/src/freeipa/service.js
Normal file
757
install/ui/src/freeipa/service.js
Normal file
@@ -0,0 +1,757 @@
|
||||
/* Authors:
|
||||
* Endi Sukma Dewata <edewata@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'dojo/_base/declare',
|
||||
'./field',
|
||||
'./builder',
|
||||
'./ipa',
|
||||
'./jquery',
|
||||
'./phases',
|
||||
'./reg',
|
||||
'./rpc',
|
||||
'./text',
|
||||
'./details',
|
||||
'./search',
|
||||
'./association',
|
||||
'./entity'],
|
||||
function(declare, field_mod, builder, IPA, $, phases, reg, rpc, text) {
|
||||
|
||||
var exp =IPA.service = {};
|
||||
|
||||
var make_spec = function() {
|
||||
return {
|
||||
name: 'service',
|
||||
policies: [
|
||||
IPA.search_facet_update_policy,
|
||||
IPA.details_facet_update_policy,
|
||||
{
|
||||
$factory: IPA.cert.cert_update_policy,
|
||||
source_facet: 'details',
|
||||
dest_entity: 'cert',
|
||||
dest_facet: 'details'
|
||||
},
|
||||
{
|
||||
$factory: IPA.cert.cert_update_policy,
|
||||
source_facet: 'details',
|
||||
dest_entity: 'cert',
|
||||
dest_facet: 'search'
|
||||
}
|
||||
],
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
$factory: IPA.service.search_facet,
|
||||
columns: [
|
||||
{
|
||||
name: 'krbcanonicalname',
|
||||
adapter: {
|
||||
$type: 'alternate_attr_field_adapter',
|
||||
alt_attr: 'krbprincipalname'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
$factory: IPA.service.details_facet,
|
||||
sections: [
|
||||
{
|
||||
name: 'details',
|
||||
fields: [
|
||||
{
|
||||
$type: 'krb_principal_multivalued',
|
||||
name: 'krbprincipalname',
|
||||
item_name: 'principal',
|
||||
child_spec: {
|
||||
$type: 'non_editable_row',
|
||||
data_name: 'krb-principal'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'service',
|
||||
label: '@i18n:objects.service.service',
|
||||
read_only: true,
|
||||
adapter: IPA.service_name_adapter
|
||||
},
|
||||
{
|
||||
name: 'host',
|
||||
label: '@i18n:objects.service.host',
|
||||
read_only: true,
|
||||
adapter: IPA.service_host_adapter
|
||||
},
|
||||
{
|
||||
name: 'ipakrbauthzdata',
|
||||
$type: 'radio',
|
||||
layout: 'vertical',
|
||||
options: [
|
||||
{
|
||||
label: '@i18n:krbauthzdata.inherited',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '@i18n:krbauthzdata.override',
|
||||
name: 'ipakrbauthzdata_override',
|
||||
$factory: IPA.option_widget_base,
|
||||
input_type: 'checkbox',
|
||||
value: 'NONE',
|
||||
combine_values: false,
|
||||
options: [
|
||||
{
|
||||
label: '@i18n:krbauthzdata.mspac',
|
||||
value: 'MS-PAC'
|
||||
},
|
||||
{
|
||||
label: '@i18n:krbauthzdata.pad',
|
||||
value: 'PAD'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'custom_checkboxes',
|
||||
label: '@i18n:authtype.auth_indicators',
|
||||
name: 'krbprincipalauthind',
|
||||
add_dialog_title: '@i18n:authtype.custom_auth_ind_title',
|
||||
add_field_label: '@i18n:authtype.auth_indicator',
|
||||
options: [
|
||||
{
|
||||
label: 'otp',
|
||||
value: 'otp'
|
||||
},
|
||||
{
|
||||
label: 'radius',
|
||||
value: 'radius'
|
||||
}
|
||||
],
|
||||
tooltip: {
|
||||
title: '@mc-opt:service_add:krbprincipalauthind:doc'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'ipakrbokasdelegate',
|
||||
$type: 'checkbox',
|
||||
acl_param: 'krbticketflags'
|
||||
},
|
||||
{
|
||||
name: 'ipakrboktoauthasdelegate',
|
||||
$type: 'checkbox',
|
||||
acl_param: 'krbticketflags'
|
||||
},
|
||||
{
|
||||
name: 'ipakrbrequirespreauth',
|
||||
$type: 'checkbox',
|
||||
acl_param: 'krbticketflags'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'provisioning',
|
||||
fields: [
|
||||
{
|
||||
$type: 'service_provisioning_status',
|
||||
name: 'has_keytab',
|
||||
label: '@i18n:objects.service.status'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'certificate',
|
||||
fields: [
|
||||
{
|
||||
$type: 'certs',
|
||||
adapter: {
|
||||
$type: 'object_adapter',
|
||||
result_index: 1
|
||||
},
|
||||
label: '@i18n:objects.cert.certificates'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$factory: IPA.section,
|
||||
name: 'divider',
|
||||
layout_css_class: 'col-sm-12',
|
||||
fields: []
|
||||
},
|
||||
{
|
||||
name: 'read',
|
||||
label: '@i18n:keytab.allowed_to_retrieve',
|
||||
$factory: IPA.section,
|
||||
fields: [
|
||||
{
|
||||
$type: 'association_table',
|
||||
id: 'service_ipaallowedtoperform_read_keys_user',
|
||||
name: 'ipaallowedtoperform_read_keys_user',
|
||||
add_method: 'allow_retrieve_keytab',
|
||||
remove_method: 'disallow_retrieve_keytab',
|
||||
add_title: '@i18n:keytab.add_retrive',
|
||||
remove_title: '@i18n:keytab.remove_retrieve',
|
||||
columns: [
|
||||
{
|
||||
name: 'ipaallowedtoperform_read_keys_user',
|
||||
label: '@mo:user.label_singular',
|
||||
link: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'association_table',
|
||||
id: 'service_ipaallowedtoperform_read_keys_group',
|
||||
name: 'ipaallowedtoperform_read_keys_group',
|
||||
add_method: 'allow_retrieve_keytab',
|
||||
remove_method: 'disallow_retrieve_keytab',
|
||||
add_title: '@i18n:keytab.add_retrive',
|
||||
remove_title: '@i18n:keytab.remove_retrieve',
|
||||
columns: [
|
||||
{
|
||||
name: 'ipaallowedtoperform_read_keys_group',
|
||||
label: '@mo:group.label_singular',
|
||||
link: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'association_table',
|
||||
id: 'service_ipaallowedtoperform_read_keys_host',
|
||||
name: 'ipaallowedtoperform_read_keys_host',
|
||||
add_method: 'allow_retrieve_keytab',
|
||||
remove_method: 'disallow_retrieve_keytab',
|
||||
add_title: '@i18n:keytab.add_retrive',
|
||||
remove_title: '@i18n:keytab.remove_retrieve',
|
||||
columns: [
|
||||
{
|
||||
name: 'ipaallowedtoperform_read_keys_host',
|
||||
label: '@mo:host.label_singular',
|
||||
link: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'association_table',
|
||||
id: 'service_ipaallowedtoperform_read_keys_hostgroup',
|
||||
name: 'ipaallowedtoperform_read_keys_hostgroup',
|
||||
add_method: 'allow_retrieve_keytab',
|
||||
remove_method: 'disallow_retrieve_keytab',
|
||||
add_title: '@i18n:keytab.add_retrive',
|
||||
remove_title: '@i18n:keytab.remove_retrieve',
|
||||
columns: [
|
||||
{
|
||||
name: 'ipaallowedtoperform_read_keys_hostgroup',
|
||||
label: '@mo:hostgroup.label_singular',
|
||||
link: true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'write',
|
||||
label: '@i18n:keytab.allowed_to_create',
|
||||
$factory: IPA.section,
|
||||
fields: [
|
||||
{
|
||||
$type: 'association_table',
|
||||
id: 'service_ipaallowedtoperform_write_keys_user',
|
||||
name: 'ipaallowedtoperform_write_keys_user',
|
||||
add_method: 'allow_create_keytab',
|
||||
remove_method: 'disallow_create_keytab',
|
||||
add_title: '@i18n:keytab.add_create',
|
||||
remove_title: '@i18n:keytab.remove_create',
|
||||
columns: [
|
||||
{
|
||||
name: 'ipaallowedtoperform_write_keys_user',
|
||||
label: '@mo:user.label_singular',
|
||||
link: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'association_table',
|
||||
id: 'service_ipaallowedtoperform_write_keys_group',
|
||||
name: 'ipaallowedtoperform_write_keys_group',
|
||||
add_method: 'allow_create_keytab',
|
||||
remove_method: 'disallow_create_keytab',
|
||||
add_title: '@i18n:keytab.add_create',
|
||||
remove_title: '@i18n:keytab.remove_create',
|
||||
columns: [
|
||||
{
|
||||
name: 'ipaallowedtoperform_write_keys_group',
|
||||
label: '@mo:group.label_singular',
|
||||
link: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'association_table',
|
||||
id: 'service_ipaallowedtoperform_write_keys_host',
|
||||
name: 'ipaallowedtoperform_write_keys_host',
|
||||
add_method: 'allow_create_keytab',
|
||||
remove_method: 'disallow_create_keytab',
|
||||
add_title: '@i18n:keytab.add_create',
|
||||
remove_title: '@i18n:keytab.remove_create',
|
||||
columns: [
|
||||
{
|
||||
name: 'ipaallowedtoperform_write_keys_host',
|
||||
label: '@mo:host.label_singular',
|
||||
link: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'association_table',
|
||||
id: 'service_ipaallowedtoperform_write_keys_hostgroup',
|
||||
name: 'ipaallowedtoperform_write_keys_hostgroup',
|
||||
add_method: 'allow_create_keytab',
|
||||
remove_method: 'disallow_create_keytab',
|
||||
add_title: '@i18n:keytab.add_create',
|
||||
remove_title: '@i18n:keytab.remove_create',
|
||||
columns: [
|
||||
{
|
||||
name: 'ipaallowedtoperform_write_keys_hostgroup',
|
||||
label: '@mo:hostgroup.label_singular',
|
||||
link: true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
actions: [
|
||||
'service_unprovision',
|
||||
'cert_request'
|
||||
],
|
||||
header_actions: [
|
||||
'unprovision',
|
||||
'request_cert'
|
||||
],
|
||||
state: {
|
||||
evaluators: [
|
||||
{
|
||||
$factory: IPA.has_keytab_evaluator,
|
||||
param: 'has_keytab',
|
||||
adapter: { $type: 'batch', result_index: 0 }
|
||||
},
|
||||
IPA.service.krbprincipalkey_acl_evaluator,
|
||||
IPA.cert.certificate_evaluator
|
||||
]
|
||||
},
|
||||
policies: [
|
||||
IPA.service.certificate_policy
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'association',
|
||||
name: 'managedby_host',
|
||||
add_method: 'add_host',
|
||||
remove_method: 'remove_host'
|
||||
}
|
||||
],
|
||||
standard_association_facets: true,
|
||||
adder_dialog: {
|
||||
$factory: IPA.service_adder_dialog,
|
||||
height: 350,
|
||||
sections: [
|
||||
{
|
||||
fields: [
|
||||
{
|
||||
$type: 'combobox',
|
||||
name: 'service',
|
||||
label: '@i18n:objects.service.service',
|
||||
options: [
|
||||
'cifs',
|
||||
'DNS',
|
||||
'ftp',
|
||||
'HTTP',
|
||||
'imap',
|
||||
'ldap',
|
||||
'libvirt',
|
||||
'nfs',
|
||||
'smtp',
|
||||
'qpidd'
|
||||
],
|
||||
editable: true,
|
||||
size: 10,
|
||||
required: true,
|
||||
z_index: 2
|
||||
},
|
||||
{
|
||||
$type: 'entity_select',
|
||||
name: 'host',
|
||||
other_entity: 'host',
|
||||
other_field: 'fqdn',
|
||||
label: '@i18n:objects.service.host',
|
||||
required: true,
|
||||
z_index: 1
|
||||
},
|
||||
{
|
||||
$type: 'checkbox',
|
||||
name: 'force',
|
||||
metadata: '@mc-opt:service_add:force'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
};};
|
||||
|
||||
|
||||
/**
|
||||
* Custom search facet for services. It has alternative primary key, in case
|
||||
* that the service doesn't have canonical name.
|
||||
*/
|
||||
IPA.service.search_facet = function(spec) {
|
||||
spec = spec || {};
|
||||
|
||||
spec.alternative_pkey = spec.alternative_pkey || 'krbprincipalname';
|
||||
|
||||
var that = IPA.search_facet(spec);
|
||||
|
||||
that.alternative_pkey = spec.alternative_pkey;
|
||||
|
||||
that.get_records_map = function(data) {
|
||||
|
||||
var records_map = $.ordered_map();
|
||||
var pkeys_map = $.ordered_map();
|
||||
|
||||
var result = data.result.result;
|
||||
var pkey_name = that.managed_entity.metadata.primary_key ||
|
||||
that.primary_key_name;
|
||||
var adapter = builder.build('adapter', 'adapter', {context: that});
|
||||
|
||||
for (var i=0; i<result.length; i++) {
|
||||
var record = result[i];
|
||||
var pkey = adapter.load(record, pkey_name)[0];
|
||||
if (pkey === undefined && that.alternative_pkey) {
|
||||
pkey = adapter.load(record, that.alternative_pkey)[0];
|
||||
}
|
||||
if (that.filter_records(records_map, pkey, record)) {
|
||||
var compound_pkey = pkey + i;
|
||||
records_map.put(compound_pkey, record);
|
||||
pkeys_map.put(compound_pkey, pkey);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
records_map: records_map,
|
||||
pkeys_map: pkeys_map
|
||||
};
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
|
||||
IPA.service.details_facet = function(spec, no_init) {
|
||||
|
||||
var that = IPA.details_facet(spec, true);
|
||||
that.certificate_loaded = IPA.observer();
|
||||
that.certificate_updated = IPA.observer();
|
||||
|
||||
that.create_refresh_command = function() {
|
||||
var pkey = that.get_pkey();
|
||||
|
||||
var batch = rpc.batch_command({
|
||||
name: 'services_details_refresh'
|
||||
});
|
||||
|
||||
var service_command = that.details_facet_create_refresh_command();
|
||||
batch.add_command(service_command);
|
||||
|
||||
var certificates = rpc.command({
|
||||
entity: 'cert',
|
||||
method: 'find',
|
||||
retry: false,
|
||||
options: {
|
||||
service: [ pkey ],
|
||||
sizelimit: 0,
|
||||
all: true
|
||||
}
|
||||
});
|
||||
|
||||
batch.add_command(certificates);
|
||||
|
||||
return batch;
|
||||
};
|
||||
|
||||
if (!no_init) that.init_details_facet();
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.service_adder_dialog = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.entity_adder_dialog(spec);
|
||||
|
||||
var init = function() {
|
||||
|
||||
//small hack - krbcanonicalname should not be displayed. This way
|
||||
//creation of associated widget is skipped.
|
||||
//In future it would be better split section definion into widget and
|
||||
//fields definition and create custom field with two associated
|
||||
//widgets - 'service' and 'host' with this dialog's save logic.
|
||||
that.builder.build_field({
|
||||
$type: 'field',
|
||||
name: 'krbcanonicalname',
|
||||
required: false
|
||||
});
|
||||
};
|
||||
|
||||
that.save = function(record) {
|
||||
|
||||
var field = that.fields.get_field('service');
|
||||
var service = field.save()[0];
|
||||
|
||||
field = that.fields.get_field('host');
|
||||
var host = field.save()[0];
|
||||
|
||||
record['krbcanonicalname'] = [ service+'/'+host ];
|
||||
|
||||
field = that.fields.get_field('force');
|
||||
record['force'] = field.save();
|
||||
};
|
||||
|
||||
init();
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.service_name_adapter = declare([field_mod.Adapter], {
|
||||
load: function(data) {
|
||||
var record = this.get_record(data);
|
||||
var krbprincipalname = record.krbprincipalname[0];
|
||||
var value = krbprincipalname.replace(/\/.*$/, '');
|
||||
return [value];
|
||||
}
|
||||
});
|
||||
|
||||
IPA.service_host_adapter = declare([field_mod.Adapter], {
|
||||
load: function(data) {
|
||||
var record = this.get_record(data);
|
||||
var krbprincipalname = record.krbprincipalname[0];
|
||||
var value = krbprincipalname.replace(/^.*\//, '').replace(/@.*$/, '');
|
||||
return [value];
|
||||
}
|
||||
});
|
||||
|
||||
IPA.service_provisioning_status_widget = function (spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.input_widget(spec);
|
||||
|
||||
that.create = function(container) {
|
||||
|
||||
that.widget_create(container);
|
||||
|
||||
that.status_valid = $('<div/>', {
|
||||
name: 'kerberos-key-valid',
|
||||
'class': 'provisioning-status',
|
||||
style: 'display: none;'
|
||||
}).appendTo(container);
|
||||
|
||||
var content = $('<label/>', {
|
||||
}).appendTo(that.status_valid);
|
||||
|
||||
$('<i/>', {
|
||||
'class': 'fa fa-check'
|
||||
}).appendTo(content);
|
||||
content.append(' ');
|
||||
content.append(text.get('@i18n:objects.service.valid'));
|
||||
|
||||
that.status_missing = $('<div/>', {
|
||||
name: 'kerberos-key-missing',
|
||||
'class': 'provisioning-status',
|
||||
style: 'display: none;'
|
||||
}).appendTo(container);
|
||||
|
||||
content = $('<label/>', {
|
||||
}).appendTo(that.status_missing);
|
||||
|
||||
$('<i/>', {
|
||||
'class': 'fa fa-warning'
|
||||
}).appendTo(content);
|
||||
content.append(' ');
|
||||
content.append(text.get('@i18n:objects.service.missing'));
|
||||
};
|
||||
|
||||
that.update = function(values) {
|
||||
that.status = values && values.length ? values[0] : false;
|
||||
set_status(that.status ? 'valid' : 'missing');
|
||||
that.on_value_changed(values);
|
||||
};
|
||||
|
||||
that.clear = function() {
|
||||
that.status_valid.css('display', 'none');
|
||||
that.status_missing.css('display', 'none');
|
||||
};
|
||||
|
||||
function set_status(status) {
|
||||
that.status_valid.css('display', status == 'valid' ? 'inline' : 'none');
|
||||
that.status_missing.css('display', status == 'missing' ? 'inline' : 'none');
|
||||
}
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.service.unprovision_dialog = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
spec.title = spec.title || '@i18n:objects.service.unprovision_title';
|
||||
|
||||
var that = IPA.dialog(spec);
|
||||
that.facet = spec.facet;
|
||||
|
||||
var entity_singular = that.entity.metadata.label_singular;
|
||||
that.title = that.title.replace('${entity}', entity_singular);
|
||||
|
||||
that.create_content = function() {
|
||||
that.container.append(text.get('@i18n:objects.service.unprovision_confirmation'));
|
||||
};
|
||||
|
||||
that.create_buttons = function() {
|
||||
|
||||
that.create_button({
|
||||
name: 'unprovision',
|
||||
label: '@i18n:objects.service.unprovision',
|
||||
click: function() {
|
||||
that.unprovision();
|
||||
}
|
||||
});
|
||||
|
||||
that.create_button({
|
||||
name: 'cancel',
|
||||
label: '@i18n:buttons.cancel',
|
||||
click: function() {
|
||||
that.close();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
that.unprovision = function() {
|
||||
|
||||
var principal_f = that.facet.fields.get_field('krbprincipalname');
|
||||
var pkey = principal_f.get_value()[0];
|
||||
|
||||
rpc.command({
|
||||
entity: that.entity.name,
|
||||
method: 'disable',
|
||||
args: [pkey],
|
||||
on_success: function(data, text_status, xhr) {
|
||||
that.facet.refresh();
|
||||
that.close();
|
||||
IPA.notify_success('@i18n:objects.service.unprovisioned');
|
||||
},
|
||||
on_error: function(xhr, text_status, error_thrown) {
|
||||
that.close();
|
||||
}
|
||||
}).execute();
|
||||
};
|
||||
|
||||
that.create_buttons();
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.service.unprovision_action = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
spec.name = spec.name || 'unprovision';
|
||||
spec.label = spec.label || '@i18n:objects.service.delete_key_unprovision';
|
||||
spec.enable_cond = spec.enable_cond || ['has_keytab', 'krbprincipalkey_w'];
|
||||
|
||||
var that = IPA.action(spec);
|
||||
|
||||
that.execute_action = function(facet) {
|
||||
|
||||
var dialog = IPA.service.unprovision_dialog({
|
||||
entity: facet.entity,
|
||||
facet: facet
|
||||
});
|
||||
|
||||
dialog.open();
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.service.krbprincipalkey_acl_evaluator = function(spec) {
|
||||
|
||||
spec.name = spec.name || 'unprovision_acl_evaluator';
|
||||
spec.attribute = spec.attribute || 'krbprincipalkey';
|
||||
|
||||
var that = IPA.acl_state_evaluator(spec);
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.service.certificate_policy = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
function get_pkey(result) {
|
||||
var values = result.krbprincipalname;
|
||||
return values ? values[0] : null;
|
||||
}
|
||||
|
||||
spec.get_pkey = spec.get_pkey || get_pkey;
|
||||
|
||||
spec.get_name = spec.get_name || function(result) {
|
||||
var value = get_pkey(result);
|
||||
return value ? value.replace(/@.*$/, '') : null;
|
||||
};
|
||||
|
||||
spec.get_principal = spec.get_principal || get_pkey;
|
||||
|
||||
spec.get_cn = spec.get_cn || function(result) {
|
||||
var value = get_pkey(result);
|
||||
if (value) {
|
||||
value = value.replace(/@.*$/, '').replace(/^.*\//, '');
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
spec.get_cn_name = spec.get_cn_name || function(result) {
|
||||
return "hostname";
|
||||
};
|
||||
|
||||
var that = IPA.cert.load_policy(spec);
|
||||
return that;
|
||||
};
|
||||
|
||||
exp.entity_spec = make_spec();
|
||||
phases.on('registration', function() {
|
||||
var e = reg.entity;
|
||||
var w = reg.widget;
|
||||
var f = reg.field;
|
||||
var a = reg.action;
|
||||
|
||||
e.register({type: 'service', spec: exp.entity_spec});
|
||||
|
||||
f.register('service_provisioning_status', IPA.field);
|
||||
w.register('service_provisioning_status', IPA.service_provisioning_status_widget);
|
||||
a.register('service_unprovision', IPA.service.unprovision_action);
|
||||
});
|
||||
|
||||
|
||||
return exp;
|
||||
});
|
||||
85
install/ui/src/freeipa/spec_util.js
Normal file
85
install/ui/src/freeipa/spec_util.js
Normal file
@@ -0,0 +1,85 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define(['dojo/_base/declare',
|
||||
'dojo/_base/array',
|
||||
'dojo/_base/lang'
|
||||
], function(declare, array, lang, construct) {
|
||||
|
||||
var undefined;
|
||||
|
||||
/**
|
||||
* Utility for working with specification objects
|
||||
* @class spec_util
|
||||
* @singleton
|
||||
*/
|
||||
var exp = {
|
||||
|
||||
/**
|
||||
* Set default value of spec's attribute when not already
|
||||
*
|
||||
* @param {Object} spec
|
||||
* @param {string} attribute name
|
||||
* @param {*} default value
|
||||
* @param {Object} object
|
||||
*/
|
||||
def: function(spec, attr_name, def) {
|
||||
|
||||
if (spec[attr_name] === undefined) {
|
||||
spec[attr_name] = def;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Set spec[spec_attr_name] to obj[attr_name].
|
||||
*
|
||||
* Use def value if spec doesn't contain the value.
|
||||
*
|
||||
* Do nothing if no value is defined.
|
||||
*/
|
||||
set: function(obj, spec, attr_name, def, spec_attr_name) {
|
||||
|
||||
spec_attr_name = spec_attr_name || attr_name;
|
||||
|
||||
if (spec[spec_attr_name] !== undefined) {
|
||||
obj[attr_name] = spec[spec_attr_name];
|
||||
} else if (def !== undefined) {
|
||||
obj[attr_name] = def;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Set entity name as entity to spec if context contains entity
|
||||
*/
|
||||
context_entity: function(spec, context) {
|
||||
|
||||
if (context.entity && !spec.entity) {
|
||||
if (typeof context.entity === 'string') {
|
||||
spec.entity = context.entity;
|
||||
} else {
|
||||
spec.entity = context.entity.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return exp;
|
||||
});
|
||||
498
install/ui/src/freeipa/stageuser.js
Normal file
498
install/ui/src/freeipa/stageuser.js
Normal file
@@ -0,0 +1,498 @@
|
||||
//
|
||||
// Copyright (C) 2015 FreeIPA Contributors see COPYING for license
|
||||
//
|
||||
|
||||
define([
|
||||
'dojo/on',
|
||||
'./ipa',
|
||||
'./jquery',
|
||||
'./menu',
|
||||
'./phases',
|
||||
'./reg',
|
||||
'./rpc',
|
||||
'./text',
|
||||
'./details',
|
||||
'./facet',
|
||||
'./user',
|
||||
'./search',
|
||||
'./entity'],
|
||||
function(
|
||||
on, IPA, $, menu, phases, reg, rpc, text, mod_details, mod_facet, mod_user) {
|
||||
/**
|
||||
* Stage user module
|
||||
* @class
|
||||
* @singleton
|
||||
*/
|
||||
var stageuser = IPA.stageuser = {
|
||||
|
||||
search_facet_group: {
|
||||
name: 'search',
|
||||
label: '@i18n:objects.stageuser.user_categories',
|
||||
facets: {
|
||||
search_normal: 'user_search',
|
||||
search: 'stageuser_search',
|
||||
search_preserved: 'user_search_preserved'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var make_stageuser_spec = function() {
|
||||
return {
|
||||
name: 'stageuser',
|
||||
facet_groups: ['settings'],
|
||||
policies: [
|
||||
IPA.search_facet_update_policy,
|
||||
IPA.details_facet_update_policy,
|
||||
{
|
||||
$factory: IPA.facet_update_policy,
|
||||
source_facet: 'search',
|
||||
dest_entity: 'user',
|
||||
dest_facet: 'search'
|
||||
},
|
||||
{
|
||||
$factory: IPA.facet_update_policy,
|
||||
source_facet: 'details',
|
||||
dest_entity: 'user',
|
||||
dest_facet: 'search'
|
||||
}
|
||||
],
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
disable_facet_tabs: false,
|
||||
tabs_in_sidebar: true,
|
||||
tab_label: '@i18n:objects.stageuser.label',
|
||||
facet_groups: [stageuser.search_facet_group],
|
||||
facet_group: 'search',
|
||||
columns: [
|
||||
'uid',
|
||||
'givenname',
|
||||
'sn',
|
||||
'uidnumber',
|
||||
'mail',
|
||||
'telephonenumber',
|
||||
'title'
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
$type: 'batch_activate'
|
||||
}
|
||||
],
|
||||
control_buttons: [
|
||||
{
|
||||
name: 'activate',
|
||||
label: '@i18n:buttons.activate',
|
||||
icon: 'fa-check'
|
||||
}
|
||||
],
|
||||
policies: [
|
||||
mod_user.stageuser_sidebar_policy
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
disable_facet_tabs: true,
|
||||
sections: [
|
||||
{
|
||||
name: 'identity',
|
||||
label: '@i18n:details.identity',
|
||||
fields: [
|
||||
'title',
|
||||
'givenname',
|
||||
'sn',
|
||||
'cn',
|
||||
'displayname',
|
||||
'initials',
|
||||
'gecos',
|
||||
{
|
||||
name: 'userclass',
|
||||
flags: ['w_if_no_aci']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'account',
|
||||
label: '@i18n:objects.user.account',
|
||||
fields: [
|
||||
'uid',
|
||||
{
|
||||
$factory: mod_user.password_widget,
|
||||
name: 'has_password',
|
||||
metadata: '@mo-param:user:userpassword'
|
||||
},
|
||||
{
|
||||
$type: 'datetime',
|
||||
name: 'krbpasswordexpiration',
|
||||
label: '@i18n:objects.user.krbpasswordexpiration',
|
||||
read_only: true
|
||||
},
|
||||
{
|
||||
name: 'uidnumber',
|
||||
minvalue: -1
|
||||
},
|
||||
{
|
||||
name: 'gidnumber',
|
||||
minvalue: -1
|
||||
},
|
||||
'krbprincipalname',
|
||||
{
|
||||
$type: 'datetime',
|
||||
name: 'krbprincipalexpiration'
|
||||
},
|
||||
'loginshell',
|
||||
'homedirectory',
|
||||
{
|
||||
$type: 'sshkeys',
|
||||
name: 'ipasshpubkey',
|
||||
label: '@i18n:objects.sshkeystore.keys'
|
||||
},
|
||||
{
|
||||
$type: 'certmap_multivalued',
|
||||
name: 'ipacertmapdata',
|
||||
item_name: 'certmapdata',
|
||||
child_spec: {
|
||||
$type: 'non_editable_row',
|
||||
data_name: 'certmap'
|
||||
},
|
||||
tooltip: {
|
||||
title: '@mc:stageuser_add_certmapdata.doc'
|
||||
}
|
||||
},
|
||||
{
|
||||
$type: 'checkboxes',
|
||||
name: 'ipauserauthtype',
|
||||
flags: ['w_if_no_aci'],
|
||||
options: [
|
||||
{ label: '@i18n:authtype.type_password', value: 'password' },
|
||||
{ label: '@i18n:authtype.type_radius', value: 'radius' },
|
||||
{ label: '@i18n:authtype.type_otp', value: 'otp' }
|
||||
],
|
||||
tooltip: '@i18n:authtype.user_tooltip'
|
||||
},
|
||||
{
|
||||
$type: 'entity_select',
|
||||
name: 'ipatokenradiusconfiglink',
|
||||
flags: ['w_if_no_aci'],
|
||||
other_entity: 'radiusproxy',
|
||||
other_field: 'cn'
|
||||
},
|
||||
{
|
||||
name: 'ipatokenradiususername',
|
||||
flags: ['w_if_no_aci']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'contact',
|
||||
label: '@i18n:objects.user.contact',
|
||||
fields: [
|
||||
{ $type: 'multivalued', name: 'mail' },
|
||||
{ $type: 'multivalued', name: 'telephonenumber' },
|
||||
{ $type: 'multivalued', name: 'pager' },
|
||||
{ $type: 'multivalued', name: 'mobile' },
|
||||
{ $type: 'multivalued', name: 'facsimiletelephonenumber' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'mailing',
|
||||
label: '@i18n:objects.user.mailing',
|
||||
fields: ['street', 'l', 'st', 'postalcode']
|
||||
},
|
||||
{
|
||||
name: 'employee',
|
||||
label: '@i18n:objects.user.employee',
|
||||
fields: [
|
||||
'ou',
|
||||
{
|
||||
$type: 'entity_select',
|
||||
name: 'manager',
|
||||
other_entity: 'user',
|
||||
other_field: 'uid'
|
||||
},
|
||||
{ $type: 'multivalued', name: 'departmentnumber' },
|
||||
'employeenumber',
|
||||
'employeetype',
|
||||
'preferredlanguage'
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'misc',
|
||||
label: '@i18n:objects.user.misc',
|
||||
fields: [
|
||||
{ $type: 'multivalued', name: 'carlicense' }
|
||||
]
|
||||
}
|
||||
],
|
||||
actions: [
|
||||
'activate',
|
||||
'delete'
|
||||
],
|
||||
header_actions: ['activate', 'delete'],
|
||||
state: {
|
||||
evaluators: [
|
||||
{
|
||||
$factory: mod_facet.noop_state_evaluator,
|
||||
state: ['staging']
|
||||
}
|
||||
],
|
||||
summary_conditions: [
|
||||
{
|
||||
pos: ['staging'],
|
||||
state: ['staging'],
|
||||
description: 'Staging user'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
adder_dialog: {
|
||||
sections: [
|
||||
{
|
||||
fields: [
|
||||
{
|
||||
name: 'uid',
|
||||
required: false
|
||||
},
|
||||
'givenname',
|
||||
'sn',
|
||||
'userclass'
|
||||
]
|
||||
},
|
||||
{
|
||||
fields: [
|
||||
{
|
||||
name: 'userpassword',
|
||||
label: '@i18n:password.new_password',
|
||||
$type: 'password'
|
||||
},
|
||||
{
|
||||
name: 'userpassword2',
|
||||
label: '@i18n:password.verify_password',
|
||||
$type: 'password',
|
||||
flags: ['no_command'],
|
||||
validators: [{
|
||||
$type: 'same_password',
|
||||
other_field: 'userpassword'
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
};};
|
||||
|
||||
stageuser.search_preserved_facet_spec = {
|
||||
$type: 'search',
|
||||
$pre_ops: [
|
||||
{ $del: [[ 'control_buttons', [{ name: 'add'}, { name: 'delete'}] ]] }
|
||||
],
|
||||
disable_facet_tabs: false,
|
||||
tabs_in_sidebar: true,
|
||||
entity: 'user',
|
||||
managed_entity: 'user',
|
||||
name: 'search_preserved',
|
||||
label: '@i18n:objects.stageuser.preserved_label',
|
||||
tab_label: '@i18n:objects.stageuser.preserved_label',
|
||||
facet_groups: [stageuser.search_facet_group],
|
||||
facet_group: 'search',
|
||||
command_options: {
|
||||
'preserved': true
|
||||
},
|
||||
columns: [
|
||||
'uid',
|
||||
'givenname',
|
||||
'sn',
|
||||
'uidnumber',
|
||||
'mail',
|
||||
'telephonenumber',
|
||||
'title'
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
$type: 'batch_undel'
|
||||
},
|
||||
{
|
||||
$type: 'batch_stage'
|
||||
}
|
||||
],
|
||||
control_buttons: [
|
||||
{
|
||||
name: 'undel',
|
||||
label: '@i18n:buttons.restore',
|
||||
icon: 'fa-heart'
|
||||
},
|
||||
{
|
||||
name: 'batch_stage',
|
||||
label: '@i18n:buttons.stage',
|
||||
icon: 'fa-user'
|
||||
}
|
||||
],
|
||||
policies: [
|
||||
mod_user.stageuser_sidebar_policy
|
||||
]
|
||||
};
|
||||
|
||||
mod_user.entity_spec.policies = mod_user.entity_spec.policies || {};
|
||||
mod_user.entity_spec.policies.push(
|
||||
{
|
||||
$factory: IPA.facet_update_policy,
|
||||
source_facet: 'search',
|
||||
dest_entity: 'stageuser',
|
||||
dest_facet: 'search'
|
||||
},
|
||||
{
|
||||
$factory: IPA.facet_update_policy,
|
||||
source_facet: 'search_preserved',
|
||||
dest_entity: 'stageuser',
|
||||
dest_facet: 'search'
|
||||
},
|
||||
{
|
||||
$factory: IPA.facet_update_policy,
|
||||
source_facet: 'search_preserved',
|
||||
dest_entity: 'user',
|
||||
dest_facet: 'search'
|
||||
},
|
||||
{
|
||||
$factory: IPA.facet_update_policy,
|
||||
source_facet: 'search',
|
||||
dest_entity: 'user',
|
||||
dest_facet: 'search_preserved'
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
stageuser.batch_activate_action = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
spec.name = spec.name || 'activate';
|
||||
spec.method = spec.method || 'activate';
|
||||
spec.needs_confirm = spec.needs_confirm === undefined ? true : spec.needs_confirm;
|
||||
spec.enabled = spec.enabled === undefined ? false : spec.enabled;
|
||||
spec.enable_cond = spec.enable_cond || ['item-selected'];
|
||||
spec.success_msg = spec.success_msg || '@i18n:objects.stageuser.activate_success';
|
||||
spec.confirm_msg = spec.confirm_msg || '@i18n:objects.stageuser.activate_confirm';
|
||||
|
||||
return IPA.batch_items_action(spec);
|
||||
};
|
||||
|
||||
stageuser.activate_action = function(spec) {
|
||||
spec = spec || {};
|
||||
spec.name = spec.name || 'activate';
|
||||
spec.method = spec.method || 'activate';
|
||||
spec.needs_confirm = spec.needs_confirm !== undefined ? spec.needs_confirm : true;
|
||||
spec.confirm_msg = spec.confirm_msg || '@i18n:objects.stageuser.activate_one_confirm';
|
||||
spec.label = spec.label || '@i18n:buttons.activate';
|
||||
|
||||
var that = IPA.object_action(spec);
|
||||
|
||||
that.on_success = function(facet, data, text_status, xhr) {
|
||||
|
||||
IPA.notify_success(data.result.summary);
|
||||
facet.on_update.notify();
|
||||
facet.redirect();
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
stageuser.batch_undel_action = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
spec.name = spec.name || 'undel';
|
||||
spec.method = spec.method || 'undel';
|
||||
spec.needs_confirm = spec.needs_confirm === undefined ? true : spec.needs_confirm;
|
||||
spec.enabled = spec.enabled === undefined ? false : spec.enabled;
|
||||
spec.enable_cond = spec.enable_cond || ['item-selected'];
|
||||
spec.success_msg = spec.success_msg || '@i18n:objects.stageuser.undel_success';
|
||||
spec.confirm_msg = spec.confirm_msg || '@i18n:objects.stageuser.undel_confirm';
|
||||
|
||||
return IPA.batch_items_action(spec);
|
||||
};
|
||||
|
||||
stageuser.undel_action = function(spec) {
|
||||
spec = spec || {};
|
||||
|
||||
spec.name = spec.name || 'undel';
|
||||
spec.method = spec.method || 'undel';
|
||||
spec.needs_confirm = spec.needs_confirm === undefined ? true : spec.needs_confirm;
|
||||
spec.confirm_msg = spec.confirm_msg || '@i18n:objects.stageuser.undel_one_confirm';
|
||||
spec.label = spec.label || '@i18n:buttons.restore';
|
||||
|
||||
var that = IPA.object_action(spec);
|
||||
|
||||
that.on_success = function(facet, data, text_status, xhr) {
|
||||
IPA.notify_success(data.result.summary);
|
||||
facet.on_update.notify();
|
||||
facet.redirect();
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
stageuser.batch_stage_action = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
spec.name = spec.name || 'batch_stage';
|
||||
spec.method = spec.method || 'stage';
|
||||
spec.needs_confirm = spec.needs_confirm === undefined ? true : spec.needs_confirm;
|
||||
spec.enable_cond = spec.enable_cond || ['item-selected'];
|
||||
spec.success_msg = spec.success_msg || '@i18n:objects.stageuser.stage_success';
|
||||
spec.confirm_msg = spec.confirm_msg || '@i18n:objects.stageuser.stage_confirm';
|
||||
|
||||
return IPA.batch_items_action(spec);
|
||||
};
|
||||
|
||||
stageuser.stage_action = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
spec.name = spec.name || 'stage';
|
||||
spec.method = spec.method || 'stage';
|
||||
spec.show_cond = spec.show_cond || ['preserved_user'];
|
||||
spec.needs_confirm = spec.needs_confirm !== undefined ? spec.needs_confirm : true;
|
||||
spec.confirm_msg = spec.confirm_msg || '@i18n:objects.stageuser.stage_one_confirm';
|
||||
spec.label = spec.label || '@i18n:buttons.stage';
|
||||
|
||||
var that = IPA.object_action(spec);
|
||||
|
||||
that.on_success = function(facet, data, text_status, xhr) {
|
||||
|
||||
IPA.notify_success(data.result.summary);
|
||||
facet.on_update.notify();
|
||||
facet.redirect();
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stage user entity specification object
|
||||
* @member stageuser
|
||||
*/
|
||||
stageuser.stageuser_spec = make_stageuser_spec();
|
||||
|
||||
/**
|
||||
* Register entity
|
||||
* @member stageuser
|
||||
*/
|
||||
stageuser.register = function() {
|
||||
var a = reg.action;
|
||||
var e = reg.entity;
|
||||
var f = reg.facet;
|
||||
a.register('batch_activate', stageuser.batch_activate_action);
|
||||
a.register('activate', stageuser.activate_action);
|
||||
a.register('batch_undel', stageuser.batch_undel_action);
|
||||
a.register('undel', stageuser.undel_action);
|
||||
a.register('batch_stage', stageuser.batch_stage_action);
|
||||
a.register('stage', stageuser.stage_action);
|
||||
e.register({type: 'stageuser', spec: stageuser.stageuser_spec});
|
||||
f.register_from_spec('user_search_preserved', stageuser.search_preserved_facet_spec);
|
||||
};
|
||||
|
||||
phases.on('registration', stageuser.register);
|
||||
|
||||
return stageuser;
|
||||
});
|
||||
955
install/ui/src/freeipa/sudo.js
Normal file
955
install/ui/src/freeipa/sudo.js
Normal file
@@ -0,0 +1,955 @@
|
||||
/* Authors:
|
||||
* Endi Sukma Dewata <edewata@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'./ipa',
|
||||
'./jquery',
|
||||
'./phases',
|
||||
'./reg',
|
||||
'./rpc',
|
||||
'./text',
|
||||
'./association',
|
||||
'./entity',
|
||||
'./details',
|
||||
'./rule',
|
||||
'./search'
|
||||
],
|
||||
function(IPA, $, phases, reg, rpc, text) {
|
||||
|
||||
var exp = IPA.sudo = {
|
||||
//priority of commands in details facet
|
||||
remove_method_priority: IPA.config.default_priority - 1
|
||||
};
|
||||
|
||||
var make_rule_spec = function() {
|
||||
var spec = {
|
||||
name: 'sudorule',
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
row_enabled_attribute: 'ipaenabledflag',
|
||||
columns: [
|
||||
'cn',
|
||||
{
|
||||
name: 'ipaenabledflag',
|
||||
label: '@i18n:status.label',
|
||||
formatter: 'boolean_status'
|
||||
},
|
||||
'description'
|
||||
],
|
||||
actions: [
|
||||
'batch_disable',
|
||||
'batch_enable'
|
||||
],
|
||||
control_buttons: [
|
||||
{
|
||||
name: 'disable',
|
||||
label: '@i18n:buttons.disable',
|
||||
icon: 'fa-minus'
|
||||
},
|
||||
{
|
||||
name: 'enable',
|
||||
label: '@i18n:buttons.enable',
|
||||
icon: 'fa-check'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
$factory: IPA.sudorule_details_facet,
|
||||
command_mode: 'info',
|
||||
actions: [
|
||||
'select',
|
||||
'enable',
|
||||
'disable',
|
||||
'delete'
|
||||
],
|
||||
header_actions: ['enable', 'disable', 'delete'],
|
||||
state: {
|
||||
evaluators: [
|
||||
{
|
||||
$factory: IPA.enable_state_evaluator,
|
||||
field: 'ipaenabledflag'
|
||||
}
|
||||
],
|
||||
summary_conditions: [
|
||||
IPA.enabled_summary_cond,
|
||||
IPA.disabled_summary_cond
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
adder_dialog: {
|
||||
fields: [ 'cn' ]
|
||||
}
|
||||
};
|
||||
|
||||
add_sudorule_details_facet_widgets(spec.facets[1]);
|
||||
return spec;
|
||||
};
|
||||
|
||||
|
||||
var make_cmd_spec = function() {
|
||||
return {
|
||||
name: 'sudocmd',
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
columns: [
|
||||
'sudocmd',
|
||||
'description'
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
sections: [
|
||||
{
|
||||
name: 'general',
|
||||
label: '@i18n:details.general',
|
||||
fields: [
|
||||
'sudocmd',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'association',
|
||||
name: 'memberof_sudocmdgroup',
|
||||
associator: IPA.serial_associator,
|
||||
columns:[
|
||||
'cn',
|
||||
'description'
|
||||
],
|
||||
adder_columns: [
|
||||
{
|
||||
name: 'cn',
|
||||
primary_key: true,
|
||||
width: '100px'
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
width: '100px'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
standard_association_facets: true,
|
||||
adder_dialog: {
|
||||
fields: [
|
||||
'sudocmd',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
};};
|
||||
|
||||
|
||||
var make_cmd_group_spec = function() {
|
||||
return {
|
||||
name: 'sudocmdgroup',
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
columns: [
|
||||
'cn',
|
||||
'description'
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
sections: [
|
||||
{
|
||||
name: 'general',
|
||||
label: '@i18n:details.general',
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'association',
|
||||
name: 'member_sudocmd',
|
||||
columns: [
|
||||
'sudocmd',
|
||||
'description'
|
||||
],
|
||||
adder_columns: [
|
||||
{
|
||||
name: 'sudocmd',
|
||||
primary_key: true,
|
||||
width: '100px'
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
width: '100px'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
standard_association_facets: true,
|
||||
adder_dialog: {
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
};};
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
* @param {Object} facet spec
|
||||
*/
|
||||
var add_sudorule_details_facet_widgets = function (spec) {
|
||||
|
||||
//
|
||||
// General
|
||||
//
|
||||
|
||||
spec.fields = [
|
||||
{
|
||||
name: 'cn',
|
||||
read_only: true,
|
||||
widget: 'general.cn'
|
||||
},
|
||||
{
|
||||
name: 'sudoorder',
|
||||
widget: 'general.sudoorder'
|
||||
},
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description',
|
||||
widget: 'general.description'
|
||||
}
|
||||
];
|
||||
|
||||
spec.widgets = [
|
||||
{
|
||||
$type: 'details_section',
|
||||
name: 'general',
|
||||
label: '@i18n:details.general',
|
||||
widgets: [
|
||||
{
|
||||
name: 'cn'
|
||||
},
|
||||
'sudoorder',
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
//
|
||||
// Options
|
||||
//
|
||||
|
||||
spec.fields.push(
|
||||
{
|
||||
name: 'ipasudoopt',
|
||||
widget: 'options.ipasudoopt'
|
||||
}
|
||||
);
|
||||
|
||||
spec.widgets.push(
|
||||
{
|
||||
$factory: IPA.sudo.options_section,
|
||||
name: 'options',
|
||||
label: '@i18n:objects.sudorule.options'
|
||||
}
|
||||
);
|
||||
|
||||
//
|
||||
// Users
|
||||
//
|
||||
|
||||
spec.fields.push(
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'usercategory',
|
||||
widget: 'user.rule.usercategory'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberuser_user',
|
||||
widget: 'user.rule.memberuser_user',
|
||||
external: 'externaluser',
|
||||
priority: IPA.sudo.remove_method_priority
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberuser_group',
|
||||
widget: 'user.rule.memberuser_group',
|
||||
priority: IPA.sudo.remove_method_priority
|
||||
}
|
||||
);
|
||||
|
||||
spec.widgets.push(
|
||||
{
|
||||
$factory: IPA.section,
|
||||
name: 'user',
|
||||
label: '@i18n:objects.sudorule.user',
|
||||
widgets: [
|
||||
{
|
||||
$factory: IPA.rule_details_widget,
|
||||
name: 'rule',
|
||||
radio_name: 'usercategory',
|
||||
options: [
|
||||
{
|
||||
value: 'all',
|
||||
label: '@i18n:objects.sudorule.anyone'
|
||||
},
|
||||
{
|
||||
value: '',
|
||||
label: '@i18n:objects.sudorule.specified_users'
|
||||
}
|
||||
],
|
||||
tables: [
|
||||
{ name: 'memberuser_user' },
|
||||
{ name: 'memberuser_group' }
|
||||
],
|
||||
widgets: [
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'sudorule-memberuser_user',
|
||||
name: 'memberuser_user',
|
||||
add_method: 'add_user',
|
||||
remove_method: 'remove_user',
|
||||
external: 'externaluser',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'sudorule-memberuser_group',
|
||||
name: 'memberuser_group',
|
||||
add_method: 'add_user',
|
||||
remove_method: 'remove_user',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
//
|
||||
// Hosts
|
||||
//
|
||||
|
||||
spec.fields.push(
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'hostcategory',
|
||||
widget: 'host.rule.hostcategory'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberhost_host',
|
||||
widget: 'host.rule.memberhost_host',
|
||||
external: 'externalhost',
|
||||
priority: IPA.sudo.remove_method_priority
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberhost_hostgroup',
|
||||
widget: 'host.rule.memberhost_hostgroup',
|
||||
priority: IPA.sudo.remove_method_priority
|
||||
}
|
||||
);
|
||||
|
||||
spec.widgets.push(
|
||||
{
|
||||
$factory: IPA.section,
|
||||
name: 'host',
|
||||
label: '@i18n:objects.sudorule.host',
|
||||
widgets: [
|
||||
{
|
||||
$factory: IPA.rule_details_widget,
|
||||
name: 'rule',
|
||||
radio_name: 'hostcategory',
|
||||
options: [
|
||||
{
|
||||
'value': 'all',
|
||||
label: '@i18n:objects.sudorule.any_host'
|
||||
},
|
||||
{
|
||||
'value': '',
|
||||
label: '@i18n:objects.sudorule.specified_hosts'
|
||||
}
|
||||
],
|
||||
tables: [
|
||||
{ 'name': 'memberhost_host' },
|
||||
{ 'name': 'memberhost_hostgroup' }
|
||||
],
|
||||
widgets: [
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'sudorule-memberuser_user',
|
||||
name: 'memberhost_host',
|
||||
add_method: 'add_host',
|
||||
remove_method: 'remove_host',
|
||||
external: 'externalhost',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'sudorule-memberuser_group',
|
||||
name: 'memberhost_hostgroup',
|
||||
add_method: 'add_host',
|
||||
remove_method: 'remove_host',
|
||||
add_title: '@i18n:association.add.member',
|
||||
remove_title: '@i18n:association.remove.member'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
//
|
||||
// Run Commands
|
||||
//
|
||||
|
||||
spec.fields.push(
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'cmdcategory',
|
||||
widget: 'command.rule.cmdcategory'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberallowcmd_sudocmd',
|
||||
widget: 'command.rule.memberallowcmd_sudocmd',
|
||||
priority: IPA.sudo.remove_method_priority
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberallowcmd_sudocmdgroup',
|
||||
widget: 'command.rule.memberallowcmd_sudocmdgroup',
|
||||
priority: IPA.sudo.remove_method_priority
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberdenycmd_sudocmd',
|
||||
widget: 'command.rule.memberdenycmd_sudocmd',
|
||||
priority: IPA.sudo.remove_method_priority
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'memberdenycmd_sudocmdgroup',
|
||||
widget: 'command.rule.memberdenycmd_sudocmdgroup',
|
||||
priority: IPA.sudo.remove_method_priority
|
||||
}
|
||||
);
|
||||
|
||||
spec.widgets.push(
|
||||
{
|
||||
$factory: IPA.section,
|
||||
name: 'command',
|
||||
label: '@i18n:objects.sudorule.command',
|
||||
widgets: [
|
||||
{
|
||||
$factory: IPA.rule_details_widget,
|
||||
name: 'rule',
|
||||
radio_name: 'cmdcategory',
|
||||
options: [
|
||||
{
|
||||
value: 'all',
|
||||
label: '@i18n:objects.sudorule.any_command'
|
||||
},
|
||||
{
|
||||
value: '',
|
||||
label: '@i18n:objects.sudorule.specified_commands'
|
||||
}
|
||||
],
|
||||
tables: [
|
||||
{ name: 'memberallowcmd_sudocmd' },
|
||||
{ name: 'memberallowcmd_sudocmdgroup' },
|
||||
{ name: 'memberdenycmd_sudocmd' },
|
||||
{ name: 'memberdenycmd_sudocmdgroup' }
|
||||
],
|
||||
widgets: [
|
||||
{
|
||||
$factory: IPA.header_widget,
|
||||
name: 'allow_header',
|
||||
text: '@i18n:objects.sudorule.allow',
|
||||
description: '@i18n:objects.sudorule.allow'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'sudorule-memberallowcmd_sudocmd',
|
||||
name: 'memberallowcmd_sudocmd',
|
||||
add_method: 'add_allow_command',
|
||||
remove_method: 'remove_allow_command',
|
||||
add_title: '@i18n:association.add.memberallowcmd',
|
||||
remove_title: '@i18n:association.remove.memberallowcmd'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'sudorule-memberallowcmd_sudocmdgroup',
|
||||
name: 'memberallowcmd_sudocmdgroup',
|
||||
add_method: 'add_allow_command',
|
||||
remove_method: 'remove_allow_command',
|
||||
add_title: '@i18n:association.add.memberallowcmd',
|
||||
remove_title: '@i18n:association.remove.memberallowcmd'
|
||||
},
|
||||
{
|
||||
$factory: IPA.header_widget,
|
||||
name: 'deny_header',
|
||||
text: '@i18n:objects.sudorule.deny',
|
||||
description: '@i18n:objects.sudorule.deny'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'sudorule-memberdenycmd_sudocmd',
|
||||
name: 'memberdenycmd_sudocmd',
|
||||
add_method: 'add_deny_command',
|
||||
remove_method: 'remove_deny_command',
|
||||
add_title: '@i18n:association.add.memberdenycmd',
|
||||
remove_title: '@i18n:association.remove.memberdenycmd'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'sudorule-memberdenycmd_sudocmdgroup',
|
||||
name: 'memberdenycmd_sudocmdgroup',
|
||||
add_method: 'add_deny_command',
|
||||
remove_method: 'remove_deny_command',
|
||||
add_title: '@i18n:association.add.memberdenycmd',
|
||||
remove_title: '@i18n:association.remove.memberdenycmd'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
//
|
||||
// As whom
|
||||
//
|
||||
|
||||
spec.fields.push(
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'ipasudorunasusercategory',
|
||||
widget: 'runas.runas_users.ipasudorunasusercategory'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'ipasudorunas_user',
|
||||
widget: 'runas.runas_users.ipasudorunas_user',
|
||||
external: 'ipasudorunasextuser',
|
||||
priority: IPA.sudo.remove_method_priority
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'ipasudorunas_group',
|
||||
widget: 'runas.runas_users.ipasudorunas_group',
|
||||
priority: IPA.sudo.remove_method_priority
|
||||
},
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'ipasudorunasgroupcategory',
|
||||
widget: 'runas.runas_groups.ipasudorunasgroupcategory'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
name: 'ipasudorunasgroup_group',
|
||||
widget: 'runas.runas_groups.ipasudorunasgroup_group',
|
||||
external: 'ipasudorunasextgroup',
|
||||
priority: IPA.sudo.remove_method_priority
|
||||
}
|
||||
);
|
||||
|
||||
spec.widgets.push(
|
||||
{
|
||||
$factory: IPA.section,
|
||||
name: 'runas',
|
||||
label: '@i18n:objects.sudorule.runas',
|
||||
widgets: [
|
||||
{
|
||||
$factory: IPA.rule_details_widget,
|
||||
name: 'runas_users',
|
||||
radio_name: 'ipasudorunasusercategory',
|
||||
options: [
|
||||
{ value: 'all', label: '@i18n:objects.sudorule.anyone' },
|
||||
{ value: '', label: '@i18n:objects.sudorule.specified_users' }
|
||||
],
|
||||
tables: [
|
||||
{ name: 'ipasudorunas_user' },
|
||||
{ name: 'ipasudorunas_group' }
|
||||
],
|
||||
widgets: [
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'sudorule-runasruser_user',
|
||||
name: 'ipasudorunas_user',
|
||||
external: 'ipasudorunasextuser',
|
||||
add_method: 'add_runasuser',
|
||||
remove_method: 'remove_runasuser',
|
||||
add_title: '@i18n:association.add.ipasudorunas',
|
||||
remove_title: '@i18n:association.remove.ipasudorunas'
|
||||
},
|
||||
{
|
||||
$type: 'rule_association_table',
|
||||
id: 'sudorule-runasuser_group',
|
||||
name: 'ipasudorunas_group',
|
||||
add_method: 'add_runasuser',
|
||||
remove_method: 'remove_runasuser',
|
||||
add_title: '@i18n:association.add.ipasudorunas',
|
||||
remove_title: '@i18n:association.remove.ipasudorunas'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$factory: IPA.rule_details_widget,
|
||||
name: 'runas_groups',
|
||||
radio_name: 'ipasudorunasgroupcategory',
|
||||
options: [
|
||||
{ value: 'all', label: '@i18n:objects.sudorule.any_group' },
|
||||
{ value: '', label: '@i18n:objects.sudorule.specified_groups' }
|
||||
],
|
||||
tables: [
|
||||
{ name: 'ipasudorunasgroup_group' }
|
||||
],
|
||||
widgets: [{
|
||||
$type: 'rule_association_table',
|
||||
id: 'sudorule-runasgroup_group',
|
||||
name: 'ipasudorunasgroup_group',
|
||||
external: 'ipasudorunasextgroup',
|
||||
add_method: 'add_runasgroup',
|
||||
remove_method: 'remove_runasgroup',
|
||||
add_title: '@i18n:association.add.ipasudorunasgroup',
|
||||
remove_title: '@i18n:association.remove.ipasudorunasgroup'
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
IPA.sudorule_details_facet = function(spec) {
|
||||
|
||||
var that = IPA.details_facet(spec);
|
||||
|
||||
var init = function() {
|
||||
var options = that.widgets.get_widget('options');
|
||||
options.facet = that;
|
||||
};
|
||||
|
||||
that.update_on_success = function(data, text_status, xhr) {
|
||||
that.refresh();
|
||||
that.on_update.notify();
|
||||
that.nofify_update_success();
|
||||
};
|
||||
|
||||
that.update_on_error = function(xhr, text_status, error_thrown) {
|
||||
that.refresh();
|
||||
};
|
||||
|
||||
init();
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.sudo.options_section = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.section(spec);
|
||||
|
||||
function setup_table(){
|
||||
that.table = IPA.table_widget({
|
||||
name: 'ipasudoopt',
|
||||
show_buttons: true
|
||||
});
|
||||
|
||||
that.widgets.add_widget(that.table);
|
||||
|
||||
that.table.create_column({
|
||||
name: 'ipasudoopt',
|
||||
label: '@mc-opt:sudorule_add_option:ipasudoopt:label',
|
||||
entity: that.entity,
|
||||
primary_key: true
|
||||
});
|
||||
|
||||
that.table.create = function(container) {
|
||||
|
||||
that.table.table_create(container);
|
||||
|
||||
that.remove_button = IPA.button_widget({
|
||||
name: 'remove',
|
||||
label: '@i18n:buttons.remove',
|
||||
icon: 'fa-trash-o',
|
||||
enabled: false,
|
||||
button_class: 'btn btn-link',
|
||||
click: that.remove_handler
|
||||
});
|
||||
that.remove_button.create(that.table.buttons);
|
||||
|
||||
that.add_button = IPA.button_widget({
|
||||
name: 'add',
|
||||
label: '@i18n:buttons.add',
|
||||
icon: 'fa-plus',
|
||||
button_class: 'btn btn-link',
|
||||
click: that.add_handler
|
||||
});
|
||||
that.add_button.create(that.table.buttons);
|
||||
};
|
||||
|
||||
that.table.select_changed = function() {
|
||||
|
||||
var values = that.table.get_selected_values();
|
||||
|
||||
if (that.remove_button) {
|
||||
that.remove_button.set_enabled(values.length > 0);
|
||||
}
|
||||
};
|
||||
|
||||
that.table.update = function(values) {
|
||||
|
||||
that.table.empty();
|
||||
|
||||
for (var i=0; i<values.length; i++) {
|
||||
var value = values[i];
|
||||
if(!value || value === '') continue;
|
||||
|
||||
var record = {
|
||||
ipasudoopt: values[i]
|
||||
};
|
||||
that.table.add_record(record);
|
||||
}
|
||||
|
||||
that.table.unselect_all();
|
||||
};
|
||||
}
|
||||
|
||||
that.add_handler = function() {
|
||||
if (that.facet.is_dirty()) {
|
||||
var dialog = IPA.dirty_dialog({
|
||||
facet: that.facet
|
||||
});
|
||||
|
||||
dialog.callback = function() {
|
||||
that.show_add_dialog();
|
||||
};
|
||||
dialog.open();
|
||||
|
||||
} else {
|
||||
that.show_add_dialog();
|
||||
}
|
||||
};
|
||||
|
||||
that.remove_handler = function() {
|
||||
if (that.facet.is_dirty()) {
|
||||
var dialog = IPA.dirty_dialog({
|
||||
facet: that.facet
|
||||
});
|
||||
|
||||
dialog.callback = function() {
|
||||
that.show_remove_dialog();
|
||||
};
|
||||
dialog.open();
|
||||
|
||||
} else {
|
||||
that.show_remove_dialog();
|
||||
}
|
||||
};
|
||||
|
||||
that.show_add_dialog = function() {
|
||||
|
||||
var label = IPA.get_command_option('sudorule_add_option', 'ipasudoopt').label;
|
||||
|
||||
var title = text.get('@i18n:dialogs.add_title');
|
||||
title = title.replace('${entity}', label);
|
||||
|
||||
var dialog = IPA.dialog({
|
||||
name: 'option-adder-dialog',
|
||||
title: title,
|
||||
sections: [
|
||||
{
|
||||
fields: [
|
||||
{
|
||||
name: 'ipasudoopt',
|
||||
label: label
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
dialog.create_button({
|
||||
name: 'add',
|
||||
label: '@i18n:buttons.add',
|
||||
click: function() {
|
||||
var ipasudoopt = dialog.fields.get_field('ipasudoopt');
|
||||
var value = ipasudoopt.save()[0];
|
||||
|
||||
var pkey = that.facet.get_pkey();
|
||||
|
||||
var command = rpc.command({
|
||||
entity: 'sudorule',
|
||||
method: 'add_option',
|
||||
args: [pkey],
|
||||
options: {
|
||||
ipasudoopt: value
|
||||
},
|
||||
on_success: function(data) {
|
||||
that.table.load(data.result.result);
|
||||
dialog.close();
|
||||
IPA.notify_success('@i18n:objects.sudorule.option_added');
|
||||
},
|
||||
on_error: function(data) {
|
||||
that.reload();
|
||||
dialog.close();
|
||||
}
|
||||
});
|
||||
|
||||
command.execute();
|
||||
}
|
||||
});
|
||||
|
||||
dialog.create_button({
|
||||
name: 'cancel',
|
||||
label: '@i18n:buttons.cancel',
|
||||
click: function() {
|
||||
dialog.close();
|
||||
}
|
||||
});
|
||||
|
||||
dialog.open();
|
||||
};
|
||||
|
||||
that.show_remove_dialog = function() {
|
||||
|
||||
var label = IPA.get_command_option('sudorule_add_option', 'ipasudoopt').label;
|
||||
var values = that.table.get_selected_values();
|
||||
|
||||
if (!values.length) {
|
||||
var message = text.get('@i18n:dialogs.remove_empty');
|
||||
window.alert(message);
|
||||
return;
|
||||
}
|
||||
|
||||
var pkey = that.facet.get_pkey();
|
||||
|
||||
var title = text.get('@i18n:dialogs.remove_title');
|
||||
title = title.replace('${entity}', label);
|
||||
|
||||
var dialog = IPA.deleter_dialog({
|
||||
title: title,
|
||||
values: values
|
||||
});
|
||||
|
||||
dialog.execute = function() {
|
||||
|
||||
var batch = rpc.batch_command({
|
||||
on_success: function(data) {
|
||||
//last successful result of batch results contains valid data
|
||||
var result;
|
||||
var succeeded = 0;
|
||||
|
||||
for (var i = data.result.results.length - 1; i > -1; i--) {
|
||||
var error = data.result.results[i].error;
|
||||
if (!result) result = data.result.results[i].result;
|
||||
if (!error) succeeded++;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
that.table.load(result);
|
||||
} else {
|
||||
that.reload();
|
||||
}
|
||||
|
||||
var msg = text.get('@i18n:objects.sudorule.option_removed').replace('${count}', succeeded);
|
||||
IPA.notify_success(msg);
|
||||
},
|
||||
on_error: function(data) {
|
||||
that.reload();
|
||||
}
|
||||
});
|
||||
|
||||
for (var i=0; i<values.length; i++) {
|
||||
var command = rpc.command({
|
||||
entity: 'sudorule',
|
||||
method: 'remove_option',
|
||||
args: [pkey]
|
||||
});
|
||||
|
||||
command.set_option('ipasudoopt', values[i]);
|
||||
|
||||
batch.add_command(command);
|
||||
}
|
||||
|
||||
batch.execute();
|
||||
};
|
||||
|
||||
dialog.open();
|
||||
};
|
||||
|
||||
that.reload = function() {
|
||||
var command = rpc.command({
|
||||
entity: that.facet.entity.name,
|
||||
method: 'show',
|
||||
args: that.facet.get_pkeys(),
|
||||
on_success: function(data) {
|
||||
that.table.load(data.result.result);
|
||||
}
|
||||
});
|
||||
|
||||
command.execute();
|
||||
};
|
||||
|
||||
/*initialization*/
|
||||
setup_table();
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
exp.rule_spec = make_rule_spec();
|
||||
exp.cmd_spec = make_cmd_spec();
|
||||
exp.cmdgroup_spec = make_cmd_group_spec();
|
||||
exp.register = function() {
|
||||
var e = reg.entity;
|
||||
|
||||
e.register({type: 'sudorule', spec: exp.rule_spec});
|
||||
e.register({type: 'sudocmd', spec: exp.cmd_spec});
|
||||
e.register({type: 'sudocmdgroup', spec: exp.cmdgroup_spec});
|
||||
};
|
||||
phases.on('registration', exp.register);
|
||||
|
||||
return exp;
|
||||
});
|
||||
48
install/ui/src/freeipa/text.js
Normal file
48
install/ui/src/freeipa/text.js
Normal file
@@ -0,0 +1,48 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define(['./_base/Provider', './_base/i18n', './metadata'],
|
||||
function(Provider, i18n, metadata) {
|
||||
|
||||
/**
|
||||
* Text provider
|
||||
*
|
||||
* Serves for returning labels, titles, messages from:
|
||||
*
|
||||
* - {@link _base.i18n} provider
|
||||
* - and {@link metadata} provider
|
||||
*
|
||||
* Other providers can extends its functionality.
|
||||
*
|
||||
* @class text
|
||||
* @singleton
|
||||
* @extends _base.Provider
|
||||
*/
|
||||
var text = new Provider({
|
||||
providers: [
|
||||
i18n,
|
||||
metadata
|
||||
],
|
||||
null_value: '',
|
||||
required_type: 'string'
|
||||
});
|
||||
|
||||
return text;
|
||||
});
|
||||
1563
install/ui/src/freeipa/topology.js
Normal file
1563
install/ui/src/freeipa/topology.js
Normal file
File diff suppressed because it is too large
Load Diff
851
install/ui/src/freeipa/topology_graph.js
Normal file
851
install/ui/src/freeipa/topology_graph.js
Normal file
@@ -0,0 +1,851 @@
|
||||
//
|
||||
// Copyright (C) 2015 FreeIPA Contributors see COPYING for license
|
||||
//
|
||||
|
||||
'use strict';
|
||||
|
||||
define([
|
||||
'dojo/_base/lang',
|
||||
'dojo/_base/declare',
|
||||
'dojo/on',
|
||||
'dojo/Evented',
|
||||
'./jquery',
|
||||
'libs/d3'
|
||||
],
|
||||
function(lang, declare, on, Evented, $, d3) {
|
||||
/**
|
||||
* Topology Graph module
|
||||
* @class
|
||||
* @singleton
|
||||
*/
|
||||
var topology_graph = {
|
||||
};
|
||||
|
||||
/**
|
||||
* Topology graph visualization
|
||||
*
|
||||
* @class
|
||||
*/
|
||||
topology_graph.TopoGraph = declare([Evented], {
|
||||
width: 960,
|
||||
height: 500,
|
||||
_adder_anim_duration: 200,
|
||||
_adder_inner_radius: 15,
|
||||
_adder_outer_radius: 30,
|
||||
_colors: d3.scale.category10(),
|
||||
_svg : null,
|
||||
_path: null,
|
||||
_circle: null,
|
||||
|
||||
_create_agreement: null,
|
||||
_selected_link: null,
|
||||
_mousedown_link: null,
|
||||
_source_node: null,
|
||||
_source_node_html: null,
|
||||
_target_node: null,
|
||||
_drag_line: null,
|
||||
|
||||
/**
|
||||
* Nodes - IPA servers
|
||||
* id - int
|
||||
*
|
||||
* @property {Array}
|
||||
*/
|
||||
nodes: [],
|
||||
|
||||
/**
|
||||
* Links between nodes
|
||||
* @property {Array}
|
||||
*/
|
||||
links: [],
|
||||
|
||||
/**
|
||||
* List of suffixes
|
||||
* @property {Array}
|
||||
*/
|
||||
suffixes: [],
|
||||
|
||||
/**
|
||||
* Initializes the graph
|
||||
* @param {HTMLElement} container container where to put the graph svg element
|
||||
*/
|
||||
initialize: function(container) {
|
||||
this._create_svg(container);
|
||||
this.update(this.nodes, this.links, this.suffixes);
|
||||
return;
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the graph
|
||||
* @param {Array} nodes array of node objects
|
||||
* @param {Array} links array of link objects
|
||||
* @param {Array} suffixes array of suffixes
|
||||
*/
|
||||
update: function(nodes, links, suffixes) {
|
||||
var curr_trasform = this._get_stored_transformation();
|
||||
|
||||
var zoomed = function() {
|
||||
var translate = d3.event.translate;
|
||||
var scale = d3.event.scale;
|
||||
var transform = "translate(" + translate + ")scale(" + scale + ")";
|
||||
|
||||
this._svg.selectAll('g.shapes')
|
||||
.attr("transform", transform);
|
||||
this._store_current_transformation();
|
||||
}.bind(this);
|
||||
|
||||
// adds zoom behavior to the svg
|
||||
var zoom = d3.behavior.zoom()
|
||||
.translate(curr_trasform.translate)
|
||||
.scale(curr_trasform.scale)
|
||||
.scaleExtent([0.2, 1])
|
||||
.on("zoom", zoomed);
|
||||
|
||||
// delete all from svg
|
||||
this._svg.selectAll("*").remove();
|
||||
this._svg.attr('width', this.width)
|
||||
.attr('height', this.height)
|
||||
.call(zoom);
|
||||
|
||||
this.links = links;
|
||||
this.nodes = nodes;
|
||||
this.suffixes = suffixes;
|
||||
|
||||
// load saved coordinates
|
||||
// node.fixed uses integer
|
||||
// this is useful when you need to store the original value and set
|
||||
// the node temporarily fixed
|
||||
for (var i=0,l=nodes.length; i<l; i++) {
|
||||
var node = nodes[i];
|
||||
node.fixed = 0;
|
||||
if (this._get_local_storage_attr(node.id, 'fixed')) {
|
||||
node.fixed = 1;
|
||||
node.x = Number(this._get_local_storage_attr(node.id, 'x'));
|
||||
node.y = Number(this._get_local_storage_attr(node.id, 'y'));
|
||||
}
|
||||
node.ca_adder = d3.svg.arc()
|
||||
.innerRadius(this._adder_inner_radius)
|
||||
.outerRadius(this._adder_inner_radius)
|
||||
.startAngle(2 * (Math.PI/180))
|
||||
.endAngle(178 * (Math.PI/180));
|
||||
|
||||
node.domain_adder = d3.svg.arc()
|
||||
.innerRadius(this._adder_inner_radius)
|
||||
.outerRadius(this._adder_inner_radius)
|
||||
.startAngle(182 * (Math.PI/180))
|
||||
.endAngle(358 * (Math.PI/180));
|
||||
|
||||
node.drag_mode = false;
|
||||
}
|
||||
|
||||
this._init_layout();
|
||||
this._define_shapes();
|
||||
|
||||
// handles to link and node element groups
|
||||
// the order of adding shapes is important because of order of showing
|
||||
// them
|
||||
this._path = this._svg.append('svg:g')
|
||||
.classed('shapes', true)
|
||||
.selectAll('path');
|
||||
|
||||
this._drag_line = this._svg.append('svg:g')
|
||||
.classed('shapes', true)
|
||||
.append('path')
|
||||
.style('marker-end', 'url(#end-arrow)')
|
||||
.attr('class', 'link dragline hidden')
|
||||
.attr('d', 'M0,0L0,0')
|
||||
.on('click', function() {
|
||||
d3.event.preventDefault();
|
||||
d3.event.stopPropagation();
|
||||
|
||||
this._create_agreement = false;
|
||||
this.reset_mouse_vars();
|
||||
|
||||
this._drag_line
|
||||
.classed('hidden', true)
|
||||
.style('marker-end', '');
|
||||
|
||||
this.restart();
|
||||
|
||||
}.bind(this));
|
||||
|
||||
this._circle = this._svg.append('svg:g')
|
||||
.classed('shapes', true)
|
||||
.selectAll('g');
|
||||
|
||||
this._selected_link = null;
|
||||
this._mousedown_link = null;
|
||||
this._selected_node = null;
|
||||
this._source_node = null;
|
||||
this._target_node = null;
|
||||
this.restart();
|
||||
},
|
||||
|
||||
_create_svg: function(container) {
|
||||
var self = this;
|
||||
|
||||
this._svg = d3.select(container[0]).
|
||||
append('svg').
|
||||
attr('width', this.width).
|
||||
attr('height', this.height).
|
||||
on('mousemove', mousemove);
|
||||
|
||||
function mousemove(d) {
|
||||
if (!self._source_node && !self._create_agreement) return;
|
||||
|
||||
var translate = self._get_stored_transformation();
|
||||
var x = self._source_node.x;
|
||||
var y = self._source_node.y;
|
||||
|
||||
var mouse_x = x + d3.mouse(self._source_node_html)[0];
|
||||
var mouse_y = y + d3.mouse(self._source_node_html)[1];
|
||||
|
||||
// update drag line
|
||||
self._drag_line.attr('d', 'M' + x + ',' + y + 'L' + mouse_x + ',' + mouse_y);
|
||||
|
||||
self.restart();
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
_init_layout: function() {
|
||||
var l = this._layout = d3.layout.force();
|
||||
l.links(this.links);
|
||||
l.nodes(this.nodes);
|
||||
l.size([this.width, this.height]);
|
||||
l.linkDistance(150);
|
||||
l.charge(-1000);
|
||||
l.on('tick', this._tick.bind(this));
|
||||
|
||||
var that = this;
|
||||
|
||||
l.on('end', function () {
|
||||
var nodes = l.nodes();
|
||||
|
||||
for (var i = 0; i < nodes.length; i++) {
|
||||
var curr_node = nodes[i];
|
||||
|
||||
if (!curr_node.fixed) {
|
||||
curr_node.fixed = 1;
|
||||
that._save_node_info(curr_node);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_get_local_storage_attr: function(id, attr) {
|
||||
return window.localStorage.getItem('topo_' + id + attr);
|
||||
},
|
||||
|
||||
_set_local_storage_attr: function(id, attr, value) {
|
||||
window.localStorage.setItem('topo_' + id + attr, value);
|
||||
},
|
||||
|
||||
_remove_local_storage_attr: function(id, attr) {
|
||||
window.localStorage.removeItem('topo_' + id + attr);
|
||||
},
|
||||
|
||||
_save_node_info: function(d) {
|
||||
if (d.fixed) {
|
||||
this._set_local_storage_attr(d.id, 'fixed', d.fixed + '');
|
||||
this._set_local_storage_attr(d.id, 'x', d.x);
|
||||
this._set_local_storage_attr(d.id, 'y', d.y);
|
||||
} else {
|
||||
this._remove_local_storage_attr(d.id, 'fixed');
|
||||
this._remove_local_storage_attr(d.id, 'x');
|
||||
this._remove_local_storage_attr(d.id, 'y');
|
||||
}
|
||||
},
|
||||
|
||||
_store_current_transformation: function(d) {
|
||||
var prefix = "graph_";
|
||||
var translate = d3.event.translate;
|
||||
var scale = d3.event.scale;
|
||||
|
||||
this._set_local_storage_attr(prefix, "translate", translate);
|
||||
this._set_local_storage_attr(prefix, "scale", scale);
|
||||
},
|
||||
|
||||
_get_stored_transformation: function(d) {
|
||||
var prefix = "graph_";
|
||||
var current_translate = this._get_local_storage_attr(prefix, "translate");
|
||||
var current_scale = this._get_local_storage_attr(prefix, "scale");
|
||||
|
||||
if (current_translate) {
|
||||
var temp_translate = current_translate.split(",");
|
||||
temp_translate[0] = parseInt(temp_translate[0], 10);
|
||||
temp_translate[1] = parseInt(temp_translate[1], 10);
|
||||
current_translate = temp_translate;
|
||||
} else {
|
||||
current_translate = [0, 0];
|
||||
}
|
||||
|
||||
if (!current_scale) {
|
||||
current_scale = 1;
|
||||
}
|
||||
|
||||
return {
|
||||
translate: current_translate,
|
||||
scale: current_scale
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Simulation tick which
|
||||
*
|
||||
* - adjusts link path and position
|
||||
* - node position
|
||||
* - saves node position
|
||||
*/
|
||||
_tick: function() {
|
||||
var self = this;
|
||||
// draw directed edges with proper padding from node centers
|
||||
this._path.attr('d', function(d) {
|
||||
var node_targets = d.source.targets[d.target.id];
|
||||
var target_count = node_targets.length;
|
||||
target_count = target_count ? target_count : 0;
|
||||
|
||||
// ensure right direction of curve
|
||||
var link_i = node_targets.indexOf(d);
|
||||
link_i = link_i === -1 ? 0 : link_i;
|
||||
var dir = link_i % 2;
|
||||
if (d.source.id < d.target.id) {
|
||||
dir = dir ? 0 : 1;
|
||||
}
|
||||
|
||||
var dx = d.target.x - d.source.x,
|
||||
dy = d.target.y - d.source.y;
|
||||
if (dx === 0) dx = 1;
|
||||
if (dy === 0) dy = 1;
|
||||
var dist = Math.sqrt(dx * dx + dy * dy),
|
||||
ux = dx / dist, // directional vector
|
||||
uy = dy / dist,
|
||||
nx = -uy, // normal vector
|
||||
ny = ux, // normal vector
|
||||
off = dir ? -1 : 1, // determines shift direction of curve
|
||||
ns = 5, // shift on normal vector
|
||||
s = target_count > 1 ? 1 : 0, // shift from center?
|
||||
spad = 18, // source padding
|
||||
tpad = 18, // target padding
|
||||
sourceX = d.source.x + (spad * ux) + off * nx * ns * s,
|
||||
sourceY = d.source.y + (spad * uy) + off * ny * ns * s,
|
||||
targetX = d.target.x - (tpad * ux) + off * nx * ns * s,
|
||||
targetY = d.target.y - (tpad * uy) + off * ny * ns * s,
|
||||
dr = s ? dist * Math.log10(dist) : 0;
|
||||
|
||||
return 'M' + sourceX + ',' + sourceY +
|
||||
'A' + dr + " " + dr + " 0 0 " + dir +" " +
|
||||
targetX + " " + targetY;
|
||||
});
|
||||
|
||||
this._circle.attr('transform', function(d) {
|
||||
self._save_node_info(d);
|
||||
return 'translate(' + d.x + ',' + d.y + ')';
|
||||
});
|
||||
},
|
||||
|
||||
_get_marker_name: function(suffix, start) {
|
||||
|
||||
var name = suffix ? suffix.cn[0] : 'drag';
|
||||
var arrow = start ? 'start-arrow' : 'end-arrow';
|
||||
return name + '-' + arrow;
|
||||
},
|
||||
|
||||
/**
|
||||
* Markers on the end of links
|
||||
*/
|
||||
_add_marker: function(name, color, refX) {
|
||||
this._svg.append('svg:defs')
|
||||
.append('svg:marker')
|
||||
.attr('id', name)
|
||||
.attr('viewBox', '0 -5 10 10')
|
||||
.attr('refX', 6)
|
||||
.attr('markerWidth', 3)
|
||||
.attr('markerHeight', 3)
|
||||
.attr('orient', 'auto')
|
||||
.append('svg:path')
|
||||
.attr('d', refX)
|
||||
.attr('fill', color);
|
||||
},
|
||||
|
||||
/**
|
||||
* Suffix hint so user will know which links belong to which suffix
|
||||
*/
|
||||
_append_suffix_hint: function(suffix, x, y) {
|
||||
var color = d3.rgb(this._colors(suffix.cn[0]));
|
||||
this._svg.append('svg:text')
|
||||
.attr('x', x)
|
||||
.attr('y', y)
|
||||
.attr('class', 'suffix')
|
||||
.attr('fill', color)
|
||||
.text(suffix.cn[0]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Defines link arrows and colors of suffixes(links) and nodes
|
||||
*/
|
||||
_define_shapes: function() {
|
||||
|
||||
var name, color;
|
||||
|
||||
var defs = this._svg.selectAll('defs');
|
||||
defs.remove();
|
||||
|
||||
var x = 10;
|
||||
var y = 20;
|
||||
|
||||
for (var i=0,l=this.suffixes.length; i<l; i++) {
|
||||
|
||||
var suffix = this.suffixes[i];
|
||||
color = d3.rgb(this._colors(suffix.cn[0]));
|
||||
|
||||
name = this._get_marker_name(suffix, false);
|
||||
this._add_marker(name, color, 'M0,-5L10,0L0,5');
|
||||
|
||||
name = this._get_marker_name(suffix, true);
|
||||
this._add_marker(name, color, 'M10,-5L0,0L10,5');
|
||||
|
||||
this._append_suffix_hint(suffix, x, y);
|
||||
y += 30;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns lenght of string with set class in pixels
|
||||
*/
|
||||
_count_string_size: function(str, cls) {
|
||||
if (!str) return 0;
|
||||
|
||||
cls = cls || '';
|
||||
|
||||
var node = this._svg.append('text')
|
||||
.classed(cls, true)
|
||||
.text(str);
|
||||
|
||||
var length = node.node().getComputedTextLength();
|
||||
|
||||
node.remove();
|
||||
|
||||
return length;
|
||||
},
|
||||
|
||||
/**
|
||||
* Restart the simulation to reflect changes in data/state
|
||||
*/
|
||||
restart: function() {
|
||||
var self = this;
|
||||
|
||||
// set the graph in motion
|
||||
self._layout.start();
|
||||
|
||||
// path (link) group
|
||||
this._path = this._path.data(self._layout.links());
|
||||
|
||||
// update existing links
|
||||
this._path
|
||||
.classed('selected', function(d) {
|
||||
return d === self._selected_link;
|
||||
})
|
||||
.style('marker-start', function(d) {
|
||||
var name = self._get_marker_name(d.suffix, true);
|
||||
return d.left ? 'url(#'+name+')' : '';
|
||||
})
|
||||
.style('marker-end', function(d) {
|
||||
var name = self._get_marker_name(d.suffix, false);
|
||||
return d.right ? 'url(#'+name+')' : '';
|
||||
});
|
||||
|
||||
|
||||
// add new links
|
||||
this._path.enter().append('svg:path')
|
||||
.attr('class', 'link')
|
||||
.style('stroke', function(d) {
|
||||
var suffix = d.suffix ? d.suffix.cn[0] : '';
|
||||
return d3.rgb(self._colors(suffix)).toString();
|
||||
})
|
||||
.classed('selected', function(d) {
|
||||
return d === self._selected_link;
|
||||
})
|
||||
.style('marker-start', function(d) {
|
||||
var name = self._get_marker_name(d.suffix, true);
|
||||
return d.left ? 'url(#'+name+')' : '';
|
||||
})
|
||||
.style('marker-end', function(d) {
|
||||
var name = self._get_marker_name(d.suffix, false);
|
||||
return d.right ? 'url(#'+name+')' : '';
|
||||
})
|
||||
.on('mousedown', function(d) {
|
||||
if (d3.event.ctrlKey) return;
|
||||
|
||||
// select link
|
||||
self._mousedown_link = d;
|
||||
if (self._mousedown_link === self._selected_link) {
|
||||
self._selected_link = null;
|
||||
} else {
|
||||
self._selected_link = self._mousedown_link;
|
||||
}
|
||||
self.emit('link-selected', { link: self._selected_link });
|
||||
self.restart();
|
||||
});
|
||||
|
||||
// remove old links
|
||||
this._path.exit().remove();
|
||||
|
||||
// circle (node) group
|
||||
this._circle = this._circle.data(
|
||||
self._layout.nodes(),
|
||||
function(d) {
|
||||
return d.id;
|
||||
}
|
||||
);
|
||||
|
||||
var drag = d3.behavior.drag()
|
||||
.on("dragstart", dragstarted)
|
||||
.on("drag", dragged)
|
||||
.on("dragend", dragended);
|
||||
|
||||
function dragstarted(d) {
|
||||
d.drag_mode = true;
|
||||
hide_semicircles.bind(this, d)();
|
||||
d3.event.sourceEvent.stopPropagation();
|
||||
// Store the original value of fixed and set the node fixed.
|
||||
d.fixed = d.fixed << 1;
|
||||
d.fixed |= 1;
|
||||
}
|
||||
|
||||
function dragged(d) {
|
||||
d.px = d3.event.x;
|
||||
d.py = d3.event.y;
|
||||
var translate = "translate(" + d.x + "," + d.y + ")";
|
||||
d3.select(this).attr('transform', translate);
|
||||
self._layout.resume();
|
||||
}
|
||||
|
||||
function dragended(d) {
|
||||
d.drag_mode = false;
|
||||
// Restore old value of fixed.
|
||||
d.fixed = d.fixed >> 1;
|
||||
self._layout.resume();
|
||||
}
|
||||
|
||||
function add_labels(type, color, adder_group) {
|
||||
var label_radius = 3;
|
||||
var decimal_plus = parseInt('f067', 16); // Converts hexadecimal
|
||||
// code of plus icon to decimal.
|
||||
|
||||
var plus = adder_group
|
||||
.append('text')
|
||||
.classed('plus', true)
|
||||
.classed(type + '_plus', true)
|
||||
.text(String.fromCharCode(decimal_plus));
|
||||
|
||||
var label = adder_group.append('path')
|
||||
.attr('id', type + '_label');
|
||||
|
||||
if (type === 'ca') {
|
||||
plus.attr('dx', '18')
|
||||
.attr('dy', '4');
|
||||
var adder_label = adder_group.append('text')
|
||||
.append('textPath')
|
||||
.classed('adder_label', true)
|
||||
.style('fill', color)
|
||||
.attr('xlink:href', '#' + type + '_label')
|
||||
.text(type);
|
||||
|
||||
var str_size = self._count_string_size(type, 'adder_label');
|
||||
var str_translate = str_size + self._adder_outer_radius + 3;
|
||||
label.attr('d', 'M 33 3 L ' + str_translate + ' 3');
|
||||
|
||||
adder_group.insert('rect', 'text')
|
||||
.attr('x', '33')
|
||||
.attr('y', '-11')
|
||||
.attr('rx', label_radius)
|
||||
.attr('ry', label_radius)
|
||||
.attr('width', str_size)
|
||||
.attr('height', '18')
|
||||
.style("fill", "white");
|
||||
}
|
||||
else {
|
||||
plus.attr('dx', '-26')
|
||||
.attr('dy', '4');
|
||||
adder_label = adder_group.append('text')
|
||||
.append('textPath')
|
||||
.classed('adder_label', true)
|
||||
.style('fill', color)
|
||||
.attr('xlink:href', '#' + type + '_label')
|
||||
.text(type);
|
||||
|
||||
str_size = self._count_string_size(type, 'adder_label');
|
||||
str_translate = str_size + self._adder_outer_radius + 3;
|
||||
label.attr('d', 'M -' + str_translate + ' 3 L -33 3');
|
||||
|
||||
adder_group.insert('rect', 'text')
|
||||
.attr('x', '-'+str_translate)
|
||||
.attr('y', '-11')
|
||||
.attr('rx', label_radius)
|
||||
.attr('ry', label_radius)
|
||||
.attr('width', str_size)
|
||||
.attr('height', '18')
|
||||
.style('fill', 'white');
|
||||
}
|
||||
}
|
||||
|
||||
function create_semicircle(d, type) {
|
||||
var color = d3.rgb(self._colors(type)).toString();
|
||||
var adder_group = d3.select(this).select('g');
|
||||
var scale = '1.05';
|
||||
|
||||
adder_group.append("path")
|
||||
.classed(type+'_adder', true)
|
||||
.classed('adder', true)
|
||||
.attr("d", d[type + '_adder'])
|
||||
.attr("fill", color)
|
||||
.on('mouseover', function(d) {
|
||||
window.clearTimeout(d._timeout_hide);
|
||||
|
||||
d3.select(this).attr('transform', 'scale('+scale+')');
|
||||
adder_group.select('text.' + type + '_plus')
|
||||
.attr('transform', 'scale('+scale+')');
|
||||
})
|
||||
.on('mouseout', function(d) {
|
||||
d3.select(this).attr('transform', '');
|
||||
adder_group.select('text.' + type + '_plus')
|
||||
.attr('transform', '');
|
||||
})
|
||||
.on('click', function(d) {
|
||||
d3.event.preventDefault();
|
||||
d3.event.stopPropagation();
|
||||
self.emit('link-selected', { link: null });
|
||||
|
||||
hide_semicircles.bind(this, d)();
|
||||
|
||||
// select node
|
||||
if (!self._source_node) {
|
||||
self._source_node = d;
|
||||
self._source_node_html = d3.select(this)
|
||||
.select('circle').node();
|
||||
self._create_agreement = true;
|
||||
}
|
||||
|
||||
self._selected_link = null;
|
||||
|
||||
var translate = self._get_stored_transformation();
|
||||
var x = self._source_node.x;
|
||||
var y = self._source_node.y;
|
||||
|
||||
// add position of node + translation of whole graph + relative
|
||||
// position of the mouse
|
||||
var mouse_x = d.x + d3.mouse(this)[0];
|
||||
var mouse_y = d.y + d3.mouse(this)[1];
|
||||
|
||||
// reposition drag line
|
||||
self._drag_line
|
||||
.style('marker-end', 'url(#' + type + '-end-arrow)')
|
||||
.style('stroke', color)
|
||||
.classed('hidden', false)
|
||||
.attr('suffix', type)
|
||||
.attr('d', 'M' + x + ',' + y +
|
||||
'L' + mouse_x + ',' + mouse_y);
|
||||
|
||||
self.restart();
|
||||
}.bind(this))
|
||||
.on('mousedown.drag', function() {
|
||||
d3.event.preventDefault();
|
||||
d3.event.stopPropagation();
|
||||
})
|
||||
.transition()
|
||||
.duration(self._adder_anim_duration)
|
||||
.attr("d", d[type + '_adder']
|
||||
.outerRadius(self._adder_outer_radius))
|
||||
.each('end', function() {
|
||||
add_labels(type, color, adder_group);
|
||||
});
|
||||
}
|
||||
|
||||
function show_semicircles(d) {
|
||||
|
||||
if(!d3.select(this).select('g path').empty()) return;
|
||||
|
||||
if (!d.drag_mode && !self._create_agreement) {
|
||||
|
||||
// append invisible circle which covers spaces between node
|
||||
// and adders it prevents hiding adders when mouse is on the space
|
||||
d3.select(this).append('g')
|
||||
.append('circle')
|
||||
.attr('r', self._adder_outer_radius)
|
||||
.style('opacity', 0);
|
||||
create_semicircle.bind(this, d, 'ca')();
|
||||
|
||||
create_semicircle.bind(this, d, 'domain')();
|
||||
|
||||
//move the identification text
|
||||
d3.select(this).select('text')
|
||||
.transition()
|
||||
.duration(self._adder_anim_duration)
|
||||
.attr('dy', '45');
|
||||
}
|
||||
}
|
||||
|
||||
function hide_semicircles(d) {
|
||||
var curr_nod = d3.select(this);
|
||||
curr_nod.selectAll('.plus,.adder_label,rect')
|
||||
.transition()
|
||||
.ease('exp')
|
||||
.duration(100)
|
||||
.style('font-size', '0px')
|
||||
.remove();
|
||||
curr_nod.select('path.domain_adder')
|
||||
.transition()
|
||||
.attr("d", d.domain_adder
|
||||
.outerRadius(self._adder_inner_radius))
|
||||
.duration(self._adder_anim_duration);
|
||||
curr_nod.select('path.ca_adder')
|
||||
.transition()
|
||||
.attr("d", d.ca_adder
|
||||
.outerRadius(self._adder_inner_radius))
|
||||
.duration(self._adder_anim_duration);
|
||||
curr_nod.select('g')
|
||||
.transition()
|
||||
.duration(self._adder_anim_duration)
|
||||
.remove();
|
||||
curr_nod.select('text')
|
||||
.transition()
|
||||
.attr('dy', '30')
|
||||
.duration(self._adder_anim_duration);
|
||||
}
|
||||
|
||||
function is_suffix_shown(suffix) {
|
||||
var links = self._source_node.targets[self._target_node.id];
|
||||
|
||||
if (!links) return false;
|
||||
|
||||
for (var i=0, l=links.length; i<l; i++) {
|
||||
var link = links[i];
|
||||
if (link.suffix.cn[0] === suffix) {
|
||||
self._selected_link = link;
|
||||
self.emit('link-selected', { link: link });
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// add new nodes
|
||||
var g = this._circle.enter()
|
||||
.append('svg:g')
|
||||
.on("dblclick", function(d) {
|
||||
// Stops propagation dblclick event to the zoom behavior.
|
||||
d3.event.preventDefault();
|
||||
d3.event.stopPropagation();
|
||||
//xor operation switch value of fixed from 1 to 0 and vice versa
|
||||
d.fixed = d.fixed ^ 1;
|
||||
self._layout.resume();
|
||||
})
|
||||
.on('mouseover', function(d) {
|
||||
window.clearTimeout(d._timeout_hide);
|
||||
show_semicircles.bind(this, d)();
|
||||
d3.select('circle.cover').classed('cover', true);
|
||||
})
|
||||
.on('mouseout', function(d) {
|
||||
d._timeout_hide = window.setTimeout(hide_semicircles
|
||||
.bind(this, d), 50);
|
||||
})
|
||||
.on('click', function(d) {
|
||||
if (!self._create_agreement) return;
|
||||
|
||||
d3.event.preventDefault();
|
||||
d3.event.stopPropagation();
|
||||
|
||||
if (self._source_node !== d) {
|
||||
self._target_node = d;
|
||||
var source = self._source_node;
|
||||
var target = self._target_node;
|
||||
var suffix = self._drag_line.attr('suffix');
|
||||
var direction = 'left';
|
||||
var link = {
|
||||
source: source,
|
||||
target: target,
|
||||
suffix: suffix,
|
||||
left: false,
|
||||
right: false
|
||||
};
|
||||
|
||||
if (!is_suffix_shown(suffix)) {
|
||||
link[direction] = true;
|
||||
self.emit('add-agreement', link);
|
||||
}
|
||||
}
|
||||
|
||||
self._drag_line
|
||||
.classed('hidden', true)
|
||||
.attr('suffix', '')
|
||||
.style('marker-end', '');
|
||||
|
||||
self.restart();
|
||||
self.reset_mouse_vars();
|
||||
})
|
||||
.call(drag);
|
||||
|
||||
g.append('svg:circle')
|
||||
.attr('class', 'node')
|
||||
.attr('r', 12)
|
||||
.style('fill', function(d) {
|
||||
return self._colors(1);
|
||||
})
|
||||
.style('stroke', function(d) {
|
||||
return d3.rgb(self._colors(1)).darker().toString();
|
||||
});
|
||||
|
||||
// show node IDs
|
||||
g.append('svg:text')
|
||||
.attr('dx', 0)
|
||||
.attr('dy', 30)
|
||||
.attr('class', 'id')
|
||||
.attr('fill', '#002235')
|
||||
.text(function(d) {
|
||||
return d.id.split('.')[0];
|
||||
});
|
||||
|
||||
// remove old nodes
|
||||
self._circle.exit().remove();
|
||||
|
||||
// get previously set position and scale of the graph and move current
|
||||
// graph to the proper position
|
||||
var curr_transform = this._get_stored_transformation();
|
||||
var transform = "translate(" + curr_transform.translate +
|
||||
")scale(" + curr_transform.scale + ")";
|
||||
|
||||
this._svg.selectAll('g.shapes')
|
||||
.attr("transform", transform);
|
||||
},
|
||||
|
||||
reset_mouse_vars: function() {
|
||||
this._source_node = null;
|
||||
this._source_node_html = null;
|
||||
this._target_node = null;
|
||||
this._mousedown_link = null;
|
||||
this._create_agreement = null;
|
||||
|
||||
},
|
||||
|
||||
resize: function(height, width) {
|
||||
if (!(isNaN(height) || isNaN(width))) {
|
||||
this.height = height < 0 ? 0 : height;
|
||||
this.width = width < 0 ? 0 : width;
|
||||
|
||||
if (this._svg) {
|
||||
this._svg
|
||||
.attr('width', this.width)
|
||||
.attr('height', this.height);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
constructor: function(spec) {
|
||||
lang.mixin(this, spec);
|
||||
}
|
||||
});
|
||||
|
||||
return topology_graph;
|
||||
});
|
||||
480
install/ui/src/freeipa/trust.js
Normal file
480
install/ui/src/freeipa/trust.js
Normal file
@@ -0,0 +1,480 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'./ipa',
|
||||
'./jquery',
|
||||
'./menu',
|
||||
'./phases',
|
||||
'./reg',
|
||||
'./details',
|
||||
'./search',
|
||||
'./association',
|
||||
'./entity'],
|
||||
function(IPA, $, menu, phases, reg) {
|
||||
|
||||
var exp = IPA.trust = {};
|
||||
|
||||
var make_trust_spec = function() {
|
||||
return {
|
||||
name: 'trust',
|
||||
enable_test: function() {
|
||||
return IPA.trust_enabled;
|
||||
},
|
||||
policies: [
|
||||
IPA.search_facet_update_policy,
|
||||
IPA.details_facet_update_policy,
|
||||
{
|
||||
$factory: IPA.adder_facet_update_policy,
|
||||
source_facet: 'search',
|
||||
dest_entity: 'idrange',
|
||||
dest_facet: 'search'
|
||||
}
|
||||
],
|
||||
facet_groups: [ 'settings', 'trustdomain' ],
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
columns: [
|
||||
'cn'
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'nested_search',
|
||||
$pre_ops: [
|
||||
// trustdomain-add is hidden, remove add button
|
||||
{ $del: [[ 'control_buttons', [{ name: 'add'}] ]] }
|
||||
],
|
||||
nested_entity: 'trustdomain',
|
||||
facet_group: 'trustdomain',
|
||||
name: 'domains',
|
||||
label: '@mo:trustdomain.label',
|
||||
tab_label: '@mo:trustdomain.label',
|
||||
search_all_entries: true,
|
||||
actions: [
|
||||
{
|
||||
$type: 'batch_disable'
|
||||
},
|
||||
{
|
||||
$type: 'batch_enable'
|
||||
},
|
||||
{
|
||||
$type: 'object',
|
||||
name: 'fetch',
|
||||
label: '@i18n:objects.trust.fetch_domains',
|
||||
method: 'fetch_domains'
|
||||
}
|
||||
],
|
||||
control_buttons: [
|
||||
{
|
||||
name: 'disable',
|
||||
label: '@i18n:buttons.disable',
|
||||
icon: 'fa-minus'
|
||||
},
|
||||
{
|
||||
name: 'enable',
|
||||
label: '@i18n:buttons.enable',
|
||||
icon: 'fa-check'
|
||||
},
|
||||
{
|
||||
name: 'fetch',
|
||||
label: '@i18n:objects.trust.fetch_domains',
|
||||
icon: 'fa-download'
|
||||
}
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
name: 'cn',
|
||||
link: false
|
||||
},
|
||||
{
|
||||
name: 'domain_enabled',
|
||||
label: '@i18n:status.label',
|
||||
formatter: 'boolean_status'
|
||||
},
|
||||
'ipantflatname',
|
||||
'ipanttrusteddomainsid'
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details',
|
||||
sections: [
|
||||
{
|
||||
name: 'details',
|
||||
label: '@i18n:objects.trust.details',
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
name: 'ipantflatname',
|
||||
label: '@i18n:objects.trust.ipantflatname',
|
||||
read_only: true
|
||||
},
|
||||
{
|
||||
name: 'ipanttrusteddomainsid',
|
||||
label: '@i18n:objects.trust.ipanttrusteddomainsid',
|
||||
read_only: true
|
||||
},
|
||||
{
|
||||
name: 'trustdirection',
|
||||
label: '@i18n:objects.trust.trustdirection'
|
||||
},
|
||||
{
|
||||
name: 'trusttype',
|
||||
label: '@i18n:objects.trust.trusttype'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'suffixes',
|
||||
label: '@i18n:objects.trust.ipantadditionalsuffixes',
|
||||
fields: [
|
||||
{
|
||||
$type: 'multivalued',
|
||||
name: 'ipantadditionalsuffixes'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'blacklists',
|
||||
label: '@i18n:objects.trust.blacklists',
|
||||
fields: [
|
||||
{
|
||||
$type: 'multivalued',
|
||||
name: 'ipantsidblacklistincoming'
|
||||
},
|
||||
{
|
||||
$type: 'multivalued',
|
||||
name: 'ipantsidblacklistoutgoing'
|
||||
}
|
||||
// trust status not supported by show command at the moment
|
||||
// {
|
||||
// name: 'truststatus',
|
||||
// label: '@i18n:objects.trust.truststatus'
|
||||
// }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
adder_dialog: {
|
||||
$factory: IPA.trust.adder_dialog,
|
||||
fields: [
|
||||
{
|
||||
name: 'cn',
|
||||
label: '@i18n:objects.trust.domain',
|
||||
widget: 'realm.realm_server'
|
||||
},
|
||||
{
|
||||
$type: 'checkbox',
|
||||
name: 'bidirectional',
|
||||
metadata: '@mc-opt:trust_add:bidirectional',
|
||||
widget: 'realm.bidirectional'
|
||||
},
|
||||
{
|
||||
$type: 'checkbox',
|
||||
name: 'external',
|
||||
metadata: '@mc-opt:trust_add:external',
|
||||
widget: 'realm.external'
|
||||
},
|
||||
{
|
||||
name: 'realm_admin',
|
||||
label: '@i18n:objects.trust.account',
|
||||
widget: 'method.realm_admin'
|
||||
},
|
||||
{
|
||||
$type: 'password',
|
||||
name: 'realm_passwd',
|
||||
label: '@i18n:password.password',
|
||||
widget: 'method.realm_passwd'
|
||||
},
|
||||
{
|
||||
$type: 'password',
|
||||
name: 'trust_secret',
|
||||
label: '@i18n:password.password',
|
||||
widget: 'method.trust_secret'
|
||||
},
|
||||
{
|
||||
$type: 'password',
|
||||
name: 'trust_secret_verify',
|
||||
label: '@i18n:password.verify_password',
|
||||
widget: 'method.trust_secret_verify',
|
||||
flags: ['no_command'],
|
||||
validators: [{
|
||||
$type: 'same_password',
|
||||
other_field: 'trust_secret'
|
||||
}]
|
||||
},
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'range_type',
|
||||
metadata: '@mc-opt:trust_add:range_type',
|
||||
widget: 'range.range_type'
|
||||
},
|
||||
{
|
||||
name: 'base_id',
|
||||
label: '@i18n:objects.idrange.ipabaseid',
|
||||
metadata: '@mc-opt:trust_add:base_id',
|
||||
widget: 'range.base_id'
|
||||
},
|
||||
{
|
||||
name: 'range_size',
|
||||
label: '@i18n:objects.idrange.ipaidrangesize',
|
||||
metadata: '@mc-opt:trust_add:range_size',
|
||||
widget: 'range.range_size'
|
||||
}
|
||||
|
||||
],
|
||||
widgets: [
|
||||
{
|
||||
$type: 'details_section',
|
||||
name: 'realm',
|
||||
widgets: [
|
||||
'realm_server',
|
||||
{
|
||||
$type: 'checkbox',
|
||||
name: 'bidirectional',
|
||||
tooltip: '@mc-opt:trust_add:bidirectional:doc'
|
||||
},
|
||||
{
|
||||
$type: 'checkbox',
|
||||
name: 'external',
|
||||
tooltip: '@mc-opt:trust_add:external:doc'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'multiple_choice_section',
|
||||
name: 'method',
|
||||
label: '@i18n:objects.trust.establish_using',
|
||||
choices: [
|
||||
{
|
||||
name: 'admin-account',
|
||||
label: '@i18n:objects.trust.admin_account',
|
||||
fields: ['realm_admin', 'realm_passwd'],
|
||||
required: ['realm_admin', 'realm_passwd'],
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
name: 'preshared_password',
|
||||
label: '@i18n:objects.trust.preshared_password',
|
||||
fields: ['trust_secret', 'trust_secret_verify'],
|
||||
required: ['trust_secret', 'trust_secret_verify']
|
||||
}
|
||||
],
|
||||
widgets: [
|
||||
{
|
||||
name: 'realm_admin'
|
||||
},
|
||||
{
|
||||
$type: 'password',
|
||||
name: 'realm_passwd'
|
||||
},
|
||||
{
|
||||
$type: 'password',
|
||||
name: 'trust_secret'
|
||||
},
|
||||
{
|
||||
$type: 'password',
|
||||
name: 'trust_secret_verify'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'details_section',
|
||||
name: 'range',
|
||||
widgets: [
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'range_type',
|
||||
layout: 'vertical',
|
||||
default_value: '',
|
||||
options: [
|
||||
{
|
||||
value: '',
|
||||
label: '@i18n:objects.idrange.type_detect'
|
||||
},
|
||||
{
|
||||
value: 'ipa-ad-trust',
|
||||
label: '@i18n:objects.idrange.type_ad'
|
||||
},
|
||||
{
|
||||
value: 'ipa-ad-trust-posix',
|
||||
label: '@i18n:objects.idrange.type_ad_posix'
|
||||
}
|
||||
]
|
||||
},
|
||||
'base_id',
|
||||
'range_size'
|
||||
]
|
||||
}
|
||||
],
|
||||
policies: [
|
||||
{
|
||||
$factory: IPA.multiple_choice_section_policy,
|
||||
widget: 'method'
|
||||
}
|
||||
]
|
||||
}
|
||||
};};
|
||||
|
||||
IPA.trust.adder_dialog = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.entity_adder_dialog(spec);
|
||||
|
||||
that.get_success_message = function(data) {
|
||||
return that.entity_adder_dialog_get_success_message(data) + '. ' + data.result.result.truststatus[0];
|
||||
};
|
||||
|
||||
that.notify_success = function(data) {
|
||||
IPA.notify_success(that.get_success_message(data), 5000);
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
|
||||
var make_trustdomain_spec = function() {
|
||||
return {
|
||||
name: 'trustdomain',
|
||||
containing_entity: 'trust'
|
||||
};};
|
||||
|
||||
var make_trustconfig_spec = function() {
|
||||
return {
|
||||
name: 'trustconfig',
|
||||
defines_key: false,
|
||||
enable_test: function() {
|
||||
return IPA.trust_enabled;
|
||||
},
|
||||
facets: [
|
||||
{
|
||||
$type: 'details',
|
||||
$factory: IPA.trust.config_details_facet,
|
||||
trust_type: 'ad',
|
||||
sections: [
|
||||
{
|
||||
name: 'details',
|
||||
label: '@i18n:objects.trustconfig.options',
|
||||
fields: [
|
||||
'cn',
|
||||
'ipantsecurityidentifier',
|
||||
'ipantflatname',
|
||||
'ipantdomainguid',
|
||||
{
|
||||
$type: 'trust_fallbackgroup_select',
|
||||
name: 'ipantfallbackprimarygroup',
|
||||
other_entity: 'group',
|
||||
other_field: 'cn',
|
||||
empty_option: false,
|
||||
filter_options: {
|
||||
posix: true
|
||||
}
|
||||
},
|
||||
{
|
||||
$type: 'multivalued',
|
||||
name: 'ad_trust_agent_server',
|
||||
read_only: true
|
||||
},
|
||||
{
|
||||
$type: 'multivalued',
|
||||
name: 'ad_trust_controller_server',
|
||||
read_only: true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};};
|
||||
|
||||
IPA.trust.config_details_facet = function(spec) {
|
||||
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.details_facet(spec);
|
||||
|
||||
that.trust_type = spec.trust_type;
|
||||
|
||||
that.get_refresh_command_name = function() {
|
||||
return that.entity.name+that.trust_type+'_show';
|
||||
};
|
||||
|
||||
that.create_refresh_command = function() {
|
||||
|
||||
var command = that.details_facet_create_refresh_command();
|
||||
command.set_option('trust_type', that.trust_type);
|
||||
|
||||
return command;
|
||||
};
|
||||
|
||||
that.create_update_command = function() {
|
||||
|
||||
var command = that.details_facet_create_update_command();
|
||||
command.set_option('trust_type', that.trust_type);
|
||||
|
||||
return command;
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.trust.fallbackgroup_select_widget = function(spec) {
|
||||
var that = IPA.entity_select_widget(spec);
|
||||
|
||||
that.set_options = function(options) {
|
||||
// always add 'Default SMB Group', it can't be obtained by group-find.
|
||||
options.unshift('Default SMB Group');
|
||||
that.entity_select_set_options(options);
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
exp.remove_menu_item = function() {
|
||||
if (!IPA.trust_enabled) {
|
||||
menu.remove_item('ipaserver/trusts');
|
||||
}
|
||||
};
|
||||
|
||||
exp.trust_spec = make_trust_spec();
|
||||
exp.trustdomain_spec = make_trustdomain_spec();
|
||||
exp.trustconfig_spec = make_trustconfig_spec();
|
||||
|
||||
|
||||
IPA.trust.register = function() {
|
||||
var e = reg.entity;
|
||||
var w = reg.widget;
|
||||
var f = reg.field;
|
||||
|
||||
e.register({type: 'trust', spec: exp.trust_spec});
|
||||
e.register({type: 'trustdomain', spec: exp.trustdomain_spec});
|
||||
e.register({type: 'trustconfig', spec: exp.trustconfig_spec});
|
||||
|
||||
w.register('trust_fallbackgroup_select', IPA.trust.fallbackgroup_select_widget);
|
||||
f.register('trust_fallbackgroup_select', IPA.field);
|
||||
};
|
||||
|
||||
phases.on('registration', IPA.trust.register);
|
||||
phases.on('profile', exp.remove_menu_item, 20);
|
||||
|
||||
return exp;
|
||||
});
|
||||
1081
install/ui/src/freeipa/user.js
Normal file
1081
install/ui/src/freeipa/user.js
Normal file
File diff suppressed because it is too large
Load Diff
384
install/ui/src/freeipa/util.js
Normal file
384
install/ui/src/freeipa/util.js
Normal file
@@ -0,0 +1,384 @@
|
||||
/* Authors:
|
||||
* Petr Vobornik <pvoborni@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2014 Red Hat
|
||||
* see file 'COPYING' for use and warranty information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define([
|
||||
'dojo/_base/lang',
|
||||
'./text'
|
||||
],
|
||||
function(lang, text) {
|
||||
|
||||
function equals_obj_def(a, b, options) {
|
||||
var same = true;
|
||||
var checked = {};
|
||||
|
||||
var check_same = function(a, b, skip) {
|
||||
|
||||
var same = true;
|
||||
skip = skip || {};
|
||||
|
||||
for (var key in a) {
|
||||
if (a.hasOwnProperty(key) && !(key in skip)) {
|
||||
|
||||
var va = a[key];
|
||||
var vb = b[key];
|
||||
|
||||
if (!equals(va, vb, options)) {
|
||||
same = false;
|
||||
skip[a] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return same;
|
||||
};
|
||||
|
||||
same = check_same(a,b, checked);
|
||||
same = same && check_same(b,a, checked);
|
||||
return same;
|
||||
}
|
||||
|
||||
function equals_obj(a, b, options) {
|
||||
|
||||
if (options.comparator) {
|
||||
return options.comparator(a, b, options);
|
||||
} else {
|
||||
return equals_obj_def(a, b, options);
|
||||
}
|
||||
}
|
||||
|
||||
function equals_array(a1, b1, options) {
|
||||
|
||||
var a = a1,
|
||||
b = b1;
|
||||
|
||||
if (!a || !b) return false;
|
||||
|
||||
if (a1.length !== b1.length) return false;
|
||||
|
||||
if (options.unordered) {
|
||||
a = a1.slice(0);
|
||||
b = b1.slice(0);
|
||||
a.sort();
|
||||
b.sort();
|
||||
}
|
||||
|
||||
for (var i=0; i<a.length; i++) {
|
||||
if (!equals(a[i], b[i], options)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function equals(a, b, options) {
|
||||
var a_t = typeof a;
|
||||
var b_t = typeof b;
|
||||
options = options || {};
|
||||
|
||||
if (a_t !== b_t) return false;
|
||||
if (a === b) return true;
|
||||
|
||||
if (['string', 'number', 'function', 'boolean',
|
||||
'undefined'].indexOf(a_t) > -1) {
|
||||
return false;
|
||||
} else if (a === null || b === null) {
|
||||
return false;
|
||||
} else if (lang.isArray(a)) {
|
||||
return equals_array(a, b, options);
|
||||
} else if (a instanceof Date) {
|
||||
return a.getTime() === b.getTime();
|
||||
} else { // objects
|
||||
return equals_obj(a, b, options);
|
||||
}
|
||||
}
|
||||
|
||||
function is_empty(value) {
|
||||
var empty = false;
|
||||
|
||||
if (value === null || value === undefined) empty = true;
|
||||
|
||||
if (lang.isArray(value)) {
|
||||
empty = empty || value.length === 0 ||
|
||||
(value.length === 1) && (value[0] === '');
|
||||
} else if (typeof value === 'object') {
|
||||
var has_p = false;
|
||||
for (var p in value) {
|
||||
if (value.hasOwnProperty(p)) {
|
||||
has_p = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
empty = !has_p;
|
||||
} else if (value === '') empty = true;
|
||||
|
||||
return empty;
|
||||
}
|
||||
|
||||
function dirty(value, pristine, options) {
|
||||
|
||||
// check for empty value: null, [''], '', []
|
||||
var orig_empty = is_empty(pristine);
|
||||
var new_empty= is_empty(value);
|
||||
if (orig_empty && new_empty) return false;
|
||||
if (orig_empty != new_empty) return true;
|
||||
|
||||
// strict equality - checks object's ref equality, numbers, strings
|
||||
if (value === pristine) return false;
|
||||
|
||||
return !equals(value, pristine, options);
|
||||
}
|
||||
|
||||
function format_single(formatter, value, error_text, method) {
|
||||
var val = value,
|
||||
ok = true,
|
||||
msg = null;
|
||||
try {
|
||||
if (method === 'format') {
|
||||
val = formatter.format(val);
|
||||
} else {
|
||||
val = formatter.parse(val);
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.reason !== method) throw e;
|
||||
ok = false;
|
||||
value = e.value;
|
||||
msg = e.message || error_text;
|
||||
}
|
||||
return {
|
||||
ok: ok,
|
||||
value: val,
|
||||
message: msg
|
||||
};
|
||||
}
|
||||
|
||||
function format_core(formatter, value, error_text, method) {
|
||||
|
||||
if (!formatter) return { ok: true, value: value };
|
||||
if (lang.isArray(value)) {
|
||||
var res = {
|
||||
ok: true,
|
||||
value: [],
|
||||
messages: []
|
||||
};
|
||||
for (var i=0, l=value.length; i<l; i++) {
|
||||
var single_res = format_single(formatter, value[i], error_text, method);
|
||||
res.ok = res.ok && single_res.ok;
|
||||
res.value[i] =single_res.value;
|
||||
res.messages[i] = single_res.message;
|
||||
if (!res.ok) {
|
||||
if (l > 1) res.message = error_text;
|
||||
else res.message = res.messages[0];
|
||||
}
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
return format_single(formatter, value, error_text, method);
|
||||
}
|
||||
}
|
||||
|
||||
function format(formatter, value, error_text) {
|
||||
|
||||
var err = error_text || text.get('@i18n:widget.validation.format');
|
||||
return format_core(formatter, value, err, 'format');
|
||||
}
|
||||
|
||||
function parse(formatter, value, error_text) {
|
||||
|
||||
var err = error_text || text.get('@i18n:widget.validation.parse');
|
||||
return format_core(formatter, value, err, 'parse');
|
||||
}
|
||||
|
||||
function normalize_value(value) {
|
||||
|
||||
if (!(value instanceof Array)) {
|
||||
value = value !== undefined ? [value] : [];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function emit_delayed(target, type, event, delay) {
|
||||
|
||||
delay = delay || 0;
|
||||
window.setTimeout(function() {
|
||||
target.emit(type, event);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function beautify_message(message) {
|
||||
var els = [];
|
||||
var lines = message.split(/\n/g);
|
||||
var line_span;
|
||||
for (var i=0,l=lines.length; i<l; i++) {
|
||||
if (lines[i].charAt(0) == '\t') {
|
||||
line_span = $('<p />', {
|
||||
'class': 'error-message-hinted',
|
||||
text: lines[i].substr(1)
|
||||
});
|
||||
els.push(line_span);
|
||||
} else {
|
||||
line_span = $('<p />', {
|
||||
text: lines[i]
|
||||
});
|
||||
els.push(line_span);
|
||||
}
|
||||
}
|
||||
return els;
|
||||
}
|
||||
|
||||
function get_val_from_dn(dn, pos) {
|
||||
if (!dn) return '';
|
||||
pos = pos === undefined ? 0 : pos;
|
||||
var val = dn.split(',')[pos].split('=')[1];
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Module with utility functions
|
||||
* @class
|
||||
* @singleton
|
||||
*/
|
||||
var util = {
|
||||
|
||||
/**
|
||||
* Checks if two variables have equal value
|
||||
*
|
||||
* - `string`, `number`, `function`, `boolean`, `null`,
|
||||
* `undefined` are compared with strict equality
|
||||
* - 'object' and arrays are compared by values
|
||||
*
|
||||
* Available options:
|
||||
*
|
||||
* - `unordered` - boolean, sort arrays before value comparison. Does
|
||||
* not modify original values.
|
||||
* - `comparator`- function(a,b), returns bool - custom object comparator
|
||||
*
|
||||
* @param {Mixed} a
|
||||
* @param {Mixed} b
|
||||
* @param {String[]} [options]
|
||||
* @return {boolean} `a` and `b` are value-equal
|
||||
*/
|
||||
equals: equals,
|
||||
|
||||
/**
|
||||
* Check if value is empty.
|
||||
*
|
||||
* True when:
|
||||
*
|
||||
* - value is undefined or `null` or `''`
|
||||
* - value is empty Array
|
||||
* - value is Array with an empty string (`''`)
|
||||
* - value is empty Object- `{}`
|
||||
* @param value - value to check
|
||||
* @return {boolean}
|
||||
*/
|
||||
is_empty: is_empty,
|
||||
|
||||
/**
|
||||
* Special kind of negative `equals` where variants of `empty_value` are
|
||||
* considered same.
|
||||
*
|
||||
* @param {Mixed} value New value
|
||||
* @param {Mixed} pristine Pristine value
|
||||
* @param {String[]} [options] control options, same as in `equals`
|
||||
* @return {boolean} `value` and `pristine` differs
|
||||
*/
|
||||
dirty: dirty,
|
||||
|
||||
/**
|
||||
* Format value or values using a formatter
|
||||
*
|
||||
* Output format for single values:
|
||||
*
|
||||
* {
|
||||
* ok: true|false,
|
||||
* value: null | formatted value,
|
||||
* message: null | string
|
||||
* }
|
||||
*
|
||||
* Output form for array:
|
||||
*
|
||||
* {
|
||||
* ok: true|false,
|
||||
* value: array of formatted values,
|
||||
* messages: array of error messages
|
||||
* message: null | string
|
||||
* }
|
||||
*
|
||||
* @param {IPA.formatter} formatter
|
||||
* @param {Mixed} value
|
||||
* @param {string} error Default error message
|
||||
* @return {Object}
|
||||
*/
|
||||
format: format,
|
||||
|
||||
/**
|
||||
* Basically the same as format method, just uses formatter's `parse`
|
||||
* method instead of `format` method.
|
||||
*
|
||||
* @param {IPA.formatter} formatter
|
||||
* @param {Mixed} value
|
||||
* @param {string} error Default error message
|
||||
* @return {Object}
|
||||
*/
|
||||
parse: parse,
|
||||
|
||||
/**
|
||||
* Encapsulates value into array if it's not already an array.
|
||||
*
|
||||
* @param {Mixed} value
|
||||
* @returns {Array} normalized value
|
||||
*/
|
||||
normalize_value: normalize_value,
|
||||
|
||||
/**
|
||||
* Emit delayed event
|
||||
*
|
||||
* Uses timer in order to wait for current processing to finish.
|
||||
*
|
||||
* @param {Evented} object Source object which emits the event
|
||||
* @param {String} type Name of the event to emit
|
||||
* @param {Object} event Event object
|
||||
* @param {Number} [delay=0]
|
||||
*/
|
||||
emit_delayed: emit_delayed,
|
||||
|
||||
/**
|
||||
* Beautify message
|
||||
*
|
||||
* Converts text value into array of HTML <p> elements. One additional
|
||||
* paragraph for each line break.
|
||||
*
|
||||
* Multi-lined text may contain TAB character as first char of the line
|
||||
* to hint at marking the whole line differently.
|
||||
* @param {string} text
|
||||
* @return {Array} array of jQuery elements
|
||||
*/
|
||||
beautify_message: beautify_message,
|
||||
|
||||
/**
|
||||
* Return value of part of DN on specified position
|
||||
* @param {string} dn Distinguished name
|
||||
* @param {Number} [position=0] Zero-based DN part position
|
||||
* @return {string}
|
||||
*/
|
||||
get_val_from_dn: get_val_from_dn
|
||||
};
|
||||
|
||||
return util;
|
||||
});
|
||||
842
install/ui/src/freeipa/vault.js
Normal file
842
install/ui/src/freeipa/vault.js
Normal file
@@ -0,0 +1,842 @@
|
||||
//
|
||||
// Copyright (C) 2017 FreeIPA Contributors see COPYING for license
|
||||
//
|
||||
|
||||
define([
|
||||
'dojo/on',
|
||||
'./ipa',
|
||||
'./jquery',
|
||||
'./phases',
|
||||
'./menu',
|
||||
'./rpc',
|
||||
'./reg',
|
||||
'./text',
|
||||
'./widget'],
|
||||
function(on, IPA, $, phases, menu, rpc, reg, text, widget) {
|
||||
|
||||
/**
|
||||
* Vault module
|
||||
* @class vault
|
||||
* @alternateClassName IPA.vault
|
||||
* @singleton
|
||||
*/
|
||||
var vault = IPA.vault = {
|
||||
|
||||
search_facet_group: {
|
||||
name: 'vaults',
|
||||
facets: {
|
||||
vault_search: 'vault_search',
|
||||
user_search: 'vault_user_search',
|
||||
service_search: 'vault_service_search',
|
||||
shared_search: 'vault_shared_search',
|
||||
vaultconfig_details: 'vaultconfig_details'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create general specification of "* Vaults" details facets.
|
||||
*/
|
||||
var make_vaults_details_page_spec = function() {
|
||||
return {
|
||||
$type: 'details',
|
||||
$factory: vault.custom_details_facet,
|
||||
update_command_name: 'mod_internal',
|
||||
disable_facet_tabs: true,
|
||||
sections: [
|
||||
{
|
||||
name: 'global_info',
|
||||
layout_ccs_class: 'col-sm-12',
|
||||
fields: [
|
||||
'cn',
|
||||
'description',
|
||||
{
|
||||
name: 'ipavaulttype',
|
||||
read_only: true
|
||||
},
|
||||
{
|
||||
$type: 'text',
|
||||
name: 'ipavaultsalt',
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
$type: 'pub_key',
|
||||
name: 'ipavaultpublickey',
|
||||
visible: false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$factory: IPA.section,
|
||||
name: 'divider',
|
||||
layout_css_class: 'col-sm-12',
|
||||
fields: []
|
||||
},
|
||||
{
|
||||
$factory: IPA.section,
|
||||
name: 'members',
|
||||
label: '@i18n:objects.vault.members',
|
||||
fields: [
|
||||
{
|
||||
$type: 'association_table',
|
||||
id: 'member_user_cn',
|
||||
name: 'member_user',
|
||||
acl_param: 'member',
|
||||
columns: [
|
||||
{
|
||||
name: 'member_user',
|
||||
label: '@i18n:objects.vault.user'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'association_table',
|
||||
id: 'member_group_cn',
|
||||
name: 'member_group',
|
||||
other_entity: 'group',
|
||||
acl_param: 'member',
|
||||
columns: [
|
||||
{
|
||||
name: 'member_group',
|
||||
label: '@i18n:objects.vault.group'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'association_table',
|
||||
id: 'member_service_cn',
|
||||
name: 'member_service',
|
||||
other_entity: 'service',
|
||||
other_option_name: 'services',
|
||||
acl_param: 'member',
|
||||
columns: [
|
||||
{
|
||||
name: 'member_service',
|
||||
label: '@i18n:objects.vault.service'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$factory: IPA.section,
|
||||
name: 'owners',
|
||||
label: '@i18n:objects.vault.owners',
|
||||
fields: [
|
||||
{
|
||||
$type: 'association_table',
|
||||
id: 'owner_user_cn',
|
||||
name: 'owner_user',
|
||||
add_method: 'add_owner',
|
||||
remove_method: 'remove_owner',
|
||||
other_entity: 'user',
|
||||
acl_param: 'owner',
|
||||
columns: [
|
||||
{
|
||||
name: 'owner_user',
|
||||
label: '@i18n:objects.vault.user'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'association_table',
|
||||
id: 'owner_group_cn',
|
||||
name: 'owner_group',
|
||||
add_method: 'add_owner',
|
||||
remove_method: 'remove_owner',
|
||||
other_entity: 'group',
|
||||
acl_param: 'owner',
|
||||
columns: [
|
||||
{
|
||||
name: 'owner_group',
|
||||
label: '@i18n:objects.vault.group'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'association_table',
|
||||
id: 'owner_service_cn',
|
||||
name: 'owner_service',
|
||||
add_method: 'add_owner',
|
||||
remove_method: 'remove_owner',
|
||||
other_entity: 'service',
|
||||
other_option_name: 'services',
|
||||
acl_param: 'owner',
|
||||
columns: [
|
||||
{
|
||||
name: 'owner_service',
|
||||
label: '@i18n:objects.vault.service'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create entity spec for whole vaults and also spec for search facet, adder
|
||||
* and deleter dialog.
|
||||
*/
|
||||
var make_my_vault_spec = function() {
|
||||
var entity = {
|
||||
name: 'vault',
|
||||
facets: [
|
||||
{
|
||||
$type: 'search',
|
||||
tab_label: '@i18n:objects.vault.my_vaults_title',
|
||||
facet_groups: [vault.search_facet_group],
|
||||
facet_group: 'vaults',
|
||||
disable_facet_tabs: false,
|
||||
search_all_entries: true,
|
||||
tabs_in_sidebar: true,
|
||||
custom_actions: [
|
||||
{
|
||||
$type: 'add',
|
||||
hide_cond: []
|
||||
},
|
||||
{
|
||||
$type: 'batch_remove',
|
||||
hide_cond: []
|
||||
}
|
||||
],
|
||||
columns: [
|
||||
'cn',
|
||||
'ipavaulttype'
|
||||
],
|
||||
policies: [
|
||||
vault.config_sidebar_policy
|
||||
]
|
||||
}
|
||||
],
|
||||
adder_dialog: {
|
||||
$factory: vault.custom_adder_dialog,
|
||||
name: 'add',
|
||||
method: 'add_internal',
|
||||
policies: [
|
||||
{ $factory: vault.adder_policy }
|
||||
]
|
||||
},
|
||||
deleter_dialog: {
|
||||
// Each parametr is present only in one facet. It could cause errors
|
||||
// in case that table on each facet gather more columns with these names.
|
||||
// I.e. facet with user vaults get column with name 'service', then
|
||||
// the value of 'service' column will be also added to command options.
|
||||
additional_table_attrs: ['username', 'service', 'shared']
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This function extends general details facet - so the same declaration
|
||||
* of facet (which would differ only in several lines)
|
||||
* should not be present six times.
|
||||
*/
|
||||
var update_facet_spec = function(facet, facet_type) {
|
||||
facet.sections[0].fields.push(facet_type);
|
||||
facet.refresh_attribute = facet_type;
|
||||
facet.update_attribute = facet_type;
|
||||
var user_members = facet.sections[2].fields[0];
|
||||
var group_members = facet.sections[2].fields[1];
|
||||
var service_members = facet.sections[2].fields[2];
|
||||
var user_owners = facet.sections[3].fields[0];
|
||||
var group_owners = facet.sections[3].fields[1];
|
||||
var service_owners = facet.sections[3].fields[2];
|
||||
|
||||
var attributes = {
|
||||
refresh_attribute: facet_type,
|
||||
additional_add_del_field: facet_type
|
||||
};
|
||||
|
||||
$.extend(user_members, attributes);
|
||||
$.extend(user_owners, attributes);
|
||||
$.extend(group_members, attributes);
|
||||
$.extend(group_owners, attributes);
|
||||
$.extend(service_members, attributes);
|
||||
$.extend(service_owners, attributes);
|
||||
};
|
||||
|
||||
// Create details page for my vauls:
|
||||
var details_spec = make_vaults_details_page_spec();
|
||||
entity.facets.push(details_spec);
|
||||
|
||||
// Create details page for user vaults and modify it
|
||||
details_spec = make_vaults_details_page_spec();
|
||||
|
||||
details_spec.name = 'vault_user';
|
||||
update_facet_spec(details_spec, 'username');
|
||||
details_spec.redirect_info = {
|
||||
facet: 'user_search'
|
||||
};
|
||||
|
||||
entity.facets.push(details_spec);
|
||||
|
||||
// Create details page for service vaults and modify it
|
||||
details_spec = make_vaults_details_page_spec();
|
||||
|
||||
details_spec.name = 'vault_service';
|
||||
update_facet_spec(details_spec, 'service');
|
||||
details_spec.redirect_info = {
|
||||
facet: 'service_search'
|
||||
};
|
||||
|
||||
entity.facets.push(details_spec);
|
||||
|
||||
// Create details page for shared vaults and modify it
|
||||
details_spec = make_vaults_details_page_spec();
|
||||
|
||||
details_spec.name = 'vault_shared';
|
||||
update_facet_spec(details_spec, 'shared');
|
||||
details_spec.redirect_info = {
|
||||
facet: 'shared_search'
|
||||
};
|
||||
|
||||
entity.facets.push(details_spec);
|
||||
|
||||
return entity;
|
||||
};
|
||||
|
||||
|
||||
vault.custom_details_facet = function(spec) {
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.details_facet(spec);
|
||||
|
||||
that.load = function(data) {
|
||||
that.details_facet_load(data);
|
||||
|
||||
// show fields according to the type of vault
|
||||
|
||||
var type_f = that.fields.get_field('ipavaulttype');
|
||||
var type = type_f.value[0];
|
||||
var salt_w = that.fields.get_field('ipavaultsalt').widget;
|
||||
var pub_key_w = that.fields.get_field('ipavaultpublickey').widget;
|
||||
|
||||
if (type === 'symmetric') {
|
||||
pub_key_w.set_visible(false);
|
||||
salt_w.set_visible(true);
|
||||
} else if (type === 'asymmetric') {
|
||||
pub_key_w.set_visible(true);
|
||||
salt_w.set_visible(false);
|
||||
} else {
|
||||
pub_key_w.set_visible(false);
|
||||
salt_w.set_visible(false);
|
||||
}
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
|
||||
vault.public_key_widget = function(spec) {
|
||||
spec = spec || {};
|
||||
|
||||
var that = IPA.sshkey_widget(spec);
|
||||
|
||||
that.set_user_value = function(value) {
|
||||
|
||||
var previous = that.key;
|
||||
that.key = value;
|
||||
that.update_link();
|
||||
|
||||
if (value !== previous) {
|
||||
that.value_changed.notify([], that);
|
||||
that.emit('value-change', { source: that });
|
||||
}
|
||||
};
|
||||
|
||||
that.update = function(value) {
|
||||
var key = value[0];
|
||||
|
||||
if (key) that.key = key;
|
||||
|
||||
if (that.key && that.key !== '') {
|
||||
that.originally_set = true;
|
||||
that.original_key = that.key;
|
||||
}
|
||||
that.update_link();
|
||||
that.on_value_changed(value);
|
||||
};
|
||||
|
||||
that.get_status = function() {
|
||||
|
||||
var status = '';
|
||||
var value = that.key;
|
||||
|
||||
if (that.original_key) {
|
||||
|
||||
if (value !== that.original_key) {
|
||||
if (value === '') {
|
||||
status = text.get('@i18n:objects.publickey.status_mod_ns');
|
||||
} else {
|
||||
status = text.get('@i18n:objects.publickey.status_mod_s');
|
||||
}
|
||||
} else {
|
||||
// f00c is code of check icon
|
||||
var decimal_check_i = parseInt('f00c', 16);
|
||||
status = String.fromCharCode(decimal_check_i);
|
||||
}
|
||||
} else {
|
||||
status = text.get('@i18n:objects.publickey.status_new_ns');
|
||||
}
|
||||
|
||||
return status;
|
||||
};
|
||||
|
||||
that.create_edit_dialog = function() {
|
||||
|
||||
var writable = that.is_writable();
|
||||
|
||||
var dialog = IPA.dialog({
|
||||
name: 'pubkey-edit-dialog',
|
||||
title: '@i18n:objects.publickey.set_dialog_title',
|
||||
width: 500,
|
||||
height: 380
|
||||
});
|
||||
|
||||
dialog.message = text.get('@i18n:objects.publickey.set_dialog_help');
|
||||
|
||||
dialog.create_button({
|
||||
name: 'update',
|
||||
label: '@i18n:buttons.set',
|
||||
click: function() {
|
||||
var value = dialog.textarea.val();
|
||||
that.set_user_value(value);
|
||||
dialog.close();
|
||||
}
|
||||
});
|
||||
|
||||
dialog.create_button({
|
||||
name: 'cancel',
|
||||
label: '@i18n:buttons.cancel',
|
||||
click: function() {
|
||||
dialog.close();
|
||||
}
|
||||
});
|
||||
|
||||
dialog.create_content = function() {
|
||||
|
||||
dialog.container.append(dialog.message);
|
||||
|
||||
dialog.textarea = $('<textarea/>', {
|
||||
'class': 'certificate',
|
||||
disabled: !that.enabled
|
||||
}).appendTo(dialog.container);
|
||||
|
||||
var key = that.key || '';
|
||||
dialog.textarea.val(key);
|
||||
};
|
||||
|
||||
return dialog;
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adder policy handles realtime showing and hiding fields when user switch
|
||||
* between User/Service/Shared vault in adder dialog.
|
||||
*
|
||||
* @extends IPA.facet_policy
|
||||
*/
|
||||
vault.adder_policy = function(spec) {
|
||||
|
||||
var that = IPA.facet_policy(spec);
|
||||
|
||||
that.init = function() {
|
||||
var type_f = that.container.fields.get_field('type');
|
||||
on(type_f, 'value-change', that.on_type_change);
|
||||
};
|
||||
|
||||
that.on_type_change = function() {
|
||||
var type_f = that.container.fields.get_field('type');
|
||||
var user_f = that.container.fields.get_field('username');
|
||||
var service_f = that.container.fields.get_field('service');
|
||||
var mode = type_f.get_value()[0];
|
||||
var user = true;
|
||||
var service = true;
|
||||
|
||||
if (mode === 'user') service = false;
|
||||
else if (mode === 'service') user = false;
|
||||
else if (mode === 'shared') user = service = false;
|
||||
|
||||
user_f.set_enabled(user);
|
||||
user_f.widget.set_visible(user);
|
||||
service_f.set_enabled(service);
|
||||
service_f.widget.set_visible(service);
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Custom adder dialog.
|
||||
*
|
||||
* @extends IPA.entity_adder_dialog
|
||||
*/
|
||||
vault.custom_adder_dialog = function(spec) {
|
||||
spec = spec || {};
|
||||
|
||||
spec.sections = spec.sections || [];
|
||||
|
||||
var section_warn_arch_ret= {
|
||||
show_header: false,
|
||||
name: 'warning_ar',
|
||||
fields: [
|
||||
{
|
||||
field: false,
|
||||
$type: 'html',
|
||||
name: 'warn_arch_ret'
|
||||
}
|
||||
],
|
||||
layout: {
|
||||
$factory: widget.fluid_layout,
|
||||
widget_cls: "col-sm-12 controls",
|
||||
label_cls: "hide"
|
||||
}
|
||||
};
|
||||
|
||||
var section_f = {
|
||||
show_header: false,
|
||||
fields: [
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'type',
|
||||
flags: ['no_command'],
|
||||
label: '@i18n:objects.vault.type',
|
||||
options: [
|
||||
{
|
||||
value: 'user',
|
||||
label: '@i18n:objects.vault.user'
|
||||
},
|
||||
{
|
||||
value: 'service',
|
||||
label: '@i18n:objects.vault.service'
|
||||
},
|
||||
{
|
||||
value: 'shared',
|
||||
label: '@i18n:objects.vault.shared'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$type: 'entity_select',
|
||||
name: 'username',
|
||||
other_entity: 'user',
|
||||
other_field: 'uid'
|
||||
},
|
||||
{
|
||||
$type: 'entity_select',
|
||||
name: 'service',
|
||||
other_entity: 'service',
|
||||
other_field: 'krbprincipalname'
|
||||
},
|
||||
'cn',
|
||||
'description',
|
||||
{
|
||||
$type: 'radio',
|
||||
name: 'ipavaulttype',
|
||||
default_value: 'standard',
|
||||
read_only: true,
|
||||
options: [
|
||||
{
|
||||
value: 'standard',
|
||||
label: '@i18n:objects.vault.standard_type'
|
||||
},
|
||||
{
|
||||
label: '@i18n:objects.vault.symmetric_type'
|
||||
},
|
||||
{
|
||||
label: '@i18n:objects.vault.asymmetric_type'
|
||||
}
|
||||
],
|
||||
tooltip: "@i18n:objects.vault.type_tooltip"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
var section_warn_standard = {
|
||||
name: 'warning_st',
|
||||
fields: [
|
||||
{
|
||||
field: false,
|
||||
$type: 'html',
|
||||
name: 'warn_standard'
|
||||
}
|
||||
],
|
||||
layout: {
|
||||
$factory: widget.fluid_layout,
|
||||
widget_cls: "col-sm-12 controls",
|
||||
label_cls: "hide"
|
||||
}
|
||||
};
|
||||
|
||||
spec.sections.push(section_warn_arch_ret);
|
||||
spec.sections.push(section_f);
|
||||
spec.sections.push(section_warn_standard);
|
||||
|
||||
var that = IPA.entity_adder_dialog(spec);
|
||||
|
||||
that.create_add_command = function(record) {
|
||||
var command = that.entity_adder_dialog_create_add_command(record);
|
||||
|
||||
var type_f = that.fields.get_field('type');
|
||||
var type = type_f.save()[0];
|
||||
|
||||
if (type === 'shared') command.set_option(type, true);
|
||||
|
||||
return command;
|
||||
};
|
||||
|
||||
that.create_content = function() {
|
||||
var warn_arch_ret_w = that.widgets.get_widget('warning_ar.warn_arch_ret');
|
||||
var warn_st_w = that.widgets.get_widget('warning_st.warn_standard');
|
||||
|
||||
var warn_arch_text = text.get('@i18n:objects.vault.add_warn_arch_ret');
|
||||
var warn_st_text = text.get('@i18n:objects.vault.add_warn_standard');
|
||||
|
||||
var warn_arch_ret = IPA.alert_helper.create_alert('arch', warn_arch_text);
|
||||
var warn_standard = IPA.alert_helper.create_alert('standard',
|
||||
warn_st_text);
|
||||
|
||||
warn_st_w.html = IPA.alert_helper.render_alert(warn_standard);
|
||||
warn_arch_ret_w.html = IPA.alert_helper.render_alert(warn_arch_ret);
|
||||
|
||||
that.entity_adder_dialog_create_content();
|
||||
|
||||
var facet_name = that.entity.facet.name;
|
||||
facet_name = facet_name.substr(0, facet_name.indexOf('_'));
|
||||
if (facet_name === "") facet_name = 'user';
|
||||
|
||||
var type_f = that.fields.get_field('type');
|
||||
type_f.set_pristine_value([facet_name]);
|
||||
|
||||
if (IPA.is_selfservice) type_f.set_writable(false);
|
||||
};
|
||||
|
||||
that.on_success = function(data) {
|
||||
var result = data.result.result;
|
||||
var my_vaults = that.entity.get_facet('search');
|
||||
|
||||
function update_facet(name) {
|
||||
var fa = that.entity.get_facet(name);
|
||||
fa.set_expired_flag();
|
||||
}
|
||||
|
||||
if (result.service) {
|
||||
update_facet('service_search');
|
||||
} else if (result.shared) {
|
||||
update_facet('shared_search');
|
||||
} else {
|
||||
update_facet('user_search');
|
||||
my_vaults.set_expired_flag();
|
||||
}
|
||||
};
|
||||
|
||||
that.added.attach(that.on_success);
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates specification of search facet for User Vaults
|
||||
*/
|
||||
var make_user_vault_search_spec = function() {
|
||||
return {
|
||||
$type: 'search',
|
||||
entity: 'vault',
|
||||
managed_entity: 'vault',
|
||||
name: 'user_search',
|
||||
tab_label: '@i18n:objects.vault.user_vaults_title',
|
||||
label: '@i18n:objects.vault.user_vaults_title',
|
||||
facet_groups: [vault.search_facet_group],
|
||||
facet_group: 'vaults',
|
||||
custom_actions: [
|
||||
{
|
||||
$type: 'add',
|
||||
hide_cond: []
|
||||
},
|
||||
{
|
||||
$type: 'batch_remove',
|
||||
hide_cond: []
|
||||
}
|
||||
],
|
||||
additional_navigation_arguments: ['username'],
|
||||
show_values_with_dup_key: true,
|
||||
details_facet: 'vault_user',
|
||||
show_command_additional_attr: 'username',
|
||||
disable_facet_tabs: false,
|
||||
tabs_in_sidebar: true,
|
||||
command_options: {
|
||||
'users': true
|
||||
},
|
||||
columns: [
|
||||
'cn',
|
||||
'username',
|
||||
'ipavaulttype'
|
||||
],
|
||||
policies: [
|
||||
vault.config_sidebar_policy
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
var make_service_vault_spec = function() {
|
||||
return {
|
||||
$type: 'search',
|
||||
entity: 'vault',
|
||||
managed_entity: 'vault',
|
||||
name: 'service_search',
|
||||
tab_label: '@i18n:objects.vault.service_vaults_title',
|
||||
label: '@i18n:objects.vault.service_vaults_title',
|
||||
facet_groups: [vault.search_facet_group],
|
||||
facet_group: 'vaults',
|
||||
additional_navigation_arguments: ['service'],
|
||||
show_values_with_dup_key: true,
|
||||
details_facet: 'vault_service',
|
||||
show_command_additional_attr: 'service',
|
||||
disable_facet_tabs: false,
|
||||
tabs_in_sidebar: true,
|
||||
command_options: {
|
||||
'services': true
|
||||
},
|
||||
columns: [
|
||||
'cn',
|
||||
'service',
|
||||
'ipavaulttype'
|
||||
],
|
||||
policies: [
|
||||
vault.config_sidebar_policy
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
var make_shared_vault_spec = function() {
|
||||
return {
|
||||
$type: 'search',
|
||||
entity: 'vault',
|
||||
managed_entity: 'vault',
|
||||
tab_label: '@i18n:objects.vault.shared_vaults_title',
|
||||
name: 'shared_search',
|
||||
label: '@i18n:objects.vault.shared_vaults_title',
|
||||
facet_groups: [vault.search_facet_group],
|
||||
facet_group: 'vaults',
|
||||
additional_navigation_arguments: ['shared'],
|
||||
show_values_with_dup_key: true,
|
||||
show_command_additional_attr: 'shared',
|
||||
details_facet: 'vault_shared',
|
||||
disable_facet_tabs: false,
|
||||
tabs_in_sidebar: true,
|
||||
command_options: {
|
||||
'shared': true
|
||||
},
|
||||
columns: [
|
||||
'cn',
|
||||
'shared',
|
||||
'ipavaulttype'
|
||||
],
|
||||
policies: [
|
||||
vault.config_sidebar_policy
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
var make_vaultconfig_spec = function() {
|
||||
return {
|
||||
name: 'vaultconfig',
|
||||
facets: [
|
||||
{
|
||||
$type: 'details',
|
||||
label: '@i18n:objects.vault.config_title',
|
||||
tab_label: '@i18n:objects.vault.config_title',
|
||||
facet_groups: [vault.search_facet_group],
|
||||
facet_group: 'vaults',
|
||||
disable_facet_tabs: false,
|
||||
tabs_in_sidebar: true,
|
||||
check_rights: false,
|
||||
no_update: true,
|
||||
fields: [
|
||||
{
|
||||
$type: "multivalued",
|
||||
name: 'kra_server_server'
|
||||
},
|
||||
{
|
||||
$type: 'textarea',
|
||||
name: 'transport_cert',
|
||||
read_only: true,
|
||||
style: {
|
||||
width: '550px',
|
||||
height: '350px'
|
||||
}
|
||||
}
|
||||
],
|
||||
policies: [
|
||||
vault.config_sidebar_policy
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
vault.config_sidebar_policy = function(spec) {
|
||||
|
||||
var that = IPA.facet_policy(spec);
|
||||
|
||||
that.post_create = function(data) {
|
||||
if (IPA.is_selfservice && that.container &&
|
||||
that.container.tabs_in_sidebar) {
|
||||
var header = that.container.header;
|
||||
|
||||
if (header) header.tabs_widget.hide_tab('vaultconfig_details');
|
||||
}
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
|
||||
vault.remove_vault_menu_item = function() {
|
||||
if (IPA.vault_enabled) return;
|
||||
|
||||
var menu_location = IPA.is_selfservice ? 'vault' : 'network_services/vault';
|
||||
|
||||
menu.remove_item(menu_location);
|
||||
};
|
||||
|
||||
vault.my_vault_spec = make_my_vault_spec();
|
||||
|
||||
vault.user_vault_search_spec = make_user_vault_search_spec();
|
||||
|
||||
vault.service_vault_spec = make_service_vault_spec();
|
||||
|
||||
vault.shared_vault_spec = make_shared_vault_spec();
|
||||
|
||||
vault.vaultconfig_spec = make_vaultconfig_spec();
|
||||
|
||||
vault.register = function() {
|
||||
var e = reg.entity;
|
||||
var fa = reg.facet;
|
||||
var w = reg.widget;
|
||||
|
||||
w.register('pub_key', vault.public_key_widget);
|
||||
e.register({type: 'vault', spec: vault.my_vault_spec});
|
||||
e.register({type: 'vaultconfig', spec: vault.vaultconfig_spec});
|
||||
fa.register_from_spec('vault_user_search', vault.user_vault_search_spec);
|
||||
fa.register_from_spec('vault_service_search', vault.service_vault_spec);
|
||||
fa.register_from_spec('vault_shared_search', vault.shared_vault_spec);
|
||||
};
|
||||
|
||||
phases.on('registration', vault.register);
|
||||
phases.on('profile', vault.remove_vault_menu_item, 20);
|
||||
|
||||
return vault;
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user