mirror of
https://github.com/nuxsmin/sysPass.git
synced 2026-03-09 01:46:57 +01:00
* [DEV] New LDAP implementation
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
use SP\Auth\Ldap\LdapMsAds;
|
||||
use SP\Auth\Ldap\LdapStd;
|
||||
use SP\Core\Init;
|
||||
use SP\Core\SessionUtil;
|
||||
@@ -55,23 +56,28 @@ if (!$sk || !SessionUtil::checkSessionKey($sk)) {
|
||||
$frmType = Request::analyze('type');
|
||||
|
||||
if ($frmType === 'ldap') {
|
||||
$frmLdapServer = Request::analyze('ldap_server');
|
||||
$frmLdapBase = Request::analyze('ldap_base');
|
||||
$frmLdapGroup = Request::analyze('ldap_group');
|
||||
$frmLdapBindUser = Request::analyze('ldap_binduser');
|
||||
$frmLdapBindPass = Request::analyzeEncrypted('ldap_bindpass');
|
||||
$ldapServer = Request::analyze('ldap_server');
|
||||
$ldapBase = Request::analyze('ldap_base');
|
||||
$ldapGroup = Request::analyze('ldap_group');
|
||||
$ldapBindUser = Request::analyze('ldap_binduser');
|
||||
$ldapBindPass = Request::analyzeEncrypted('ldap_bindpass');
|
||||
|
||||
if (!$frmLdapServer || !$frmLdapBase || !$frmLdapBindUser || !$frmLdapBindPass) {
|
||||
if (!$ldapServer || !$ldapBase || !$ldapBindUser || !$ldapBindPass) {
|
||||
$Json->setDescription(_('Los parámetros de LDAP no están configurados'));
|
||||
Json::returnJson($Json);
|
||||
}
|
||||
|
||||
$Ldap = new LdapStd();
|
||||
$Ldap->setServer($frmLdapServer);
|
||||
$Ldap->setSearchBase($frmLdapBase);
|
||||
$Ldap->setGroup($frmLdapGroup);
|
||||
$Ldap->setBindDn($frmLdapBindUser);
|
||||
$Ldap->setBindPass($frmLdapBindPass);
|
||||
if (Request::analyze('ldap_enabled', false, false, true)) {
|
||||
$Ldap = new LdapMsAds();
|
||||
} else {
|
||||
$Ldap = new LdapStd();
|
||||
}
|
||||
|
||||
$Ldap->setServer($ldapServer);
|
||||
$Ldap->setSearchBase($ldapBase);
|
||||
$Ldap->setGroup($ldapGroup);
|
||||
$Ldap->setBindDn($ldapBindUser);
|
||||
$Ldap->setBindPass($ldapBindPass);
|
||||
|
||||
$resCheckLdap = $Ldap->checkConnection();
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ if ($resLdap !== false) {
|
||||
$Log->addDetails(_('Tipo'), 'MySQL');
|
||||
|
||||
// Autentificamos con la BBDD
|
||||
if (!Auth::authUserMySQL($UserData->getUserLogin(), $UserData->getUserPass())) {
|
||||
if (!Auth::authUserMySQL($UserData)) {
|
||||
$Log->addDescription(_('Login incorrecto'));
|
||||
$Log->addDetails(_('Usuario'), $UserData->getUserLogin());
|
||||
$Log->writeLog();
|
||||
|
||||
@@ -389,8 +389,6 @@ class AccountHistory extends AccountBase implements AccountInterface
|
||||
*/
|
||||
public function getAccountPassData()
|
||||
{
|
||||
debugLog($this->getId());
|
||||
|
||||
$query = /** @lang SQL */
|
||||
'SELECT acchistory_name AS account_name,'
|
||||
. 'acchistory_userId AS account_userId,'
|
||||
|
||||
@@ -103,7 +103,7 @@ abstract class ApiBase
|
||||
$UserPass = UserPass::getItem($UserData);
|
||||
|
||||
if (!$UserData->isUserIsDisabled()
|
||||
&& Auth::authUserMySQL($UserData->getUserLogin(), $UserData->getUserPass())
|
||||
&& Auth::authUserMySQL($UserData)
|
||||
&& $UserPass->loadUserMPass()
|
||||
&& UserPass::checkUserUpdateMPass($UserData->getUserId())
|
||||
) {
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
namespace SP\Auth;
|
||||
|
||||
use SP\Auth\Ldap\LdapMads;
|
||||
use SP\Auth\Ldap\LdapMsAds;
|
||||
use SP\Auth\Ldap\LdapStd;
|
||||
use SP\Config\Config;
|
||||
use SP\Core\Exceptions\SPException;
|
||||
@@ -63,7 +63,7 @@ class Auth
|
||||
public static function authUserLDAP(UserData $UserData)
|
||||
{
|
||||
if (Config::getConfig()->isLdapAds()) {
|
||||
$Ldap = new LdapMads();
|
||||
$Ldap = new LdapMsAds();
|
||||
} else {
|
||||
$Ldap = new LdapStd();
|
||||
}
|
||||
@@ -83,7 +83,7 @@ class Auth
|
||||
self::$status = 701;
|
||||
|
||||
return false;
|
||||
} elseif ($LdapAuthData->isInGroup()) {
|
||||
} elseif (!$LdapAuthData->isInGroup()) {
|
||||
self::$status = 702;
|
||||
|
||||
return false;
|
||||
@@ -98,19 +98,18 @@ class Auth
|
||||
* Esta función comprueba la clave del usuario. Si el usuario necesita ser migrado desde phpPMS,
|
||||
* se ejecuta el proceso para actualizar la clave.
|
||||
*
|
||||
* @param string $userLogin con el login del usuario
|
||||
* @param string $userPass con la clave del usuario
|
||||
* @param UserData $UserData
|
||||
* @return bool
|
||||
*/
|
||||
public static function authUserMySQL($userLogin, $userPass)
|
||||
public static function authUserMySQL(UserData $UserData)
|
||||
{
|
||||
if (UserMigrate::checkUserIsMigrate($userLogin)) {
|
||||
if (UserMigrate::checkUserIsMigrate($UserData->getUserLogin())) {
|
||||
try {
|
||||
UserMigrate::migrateUser($userLogin, $userPass);
|
||||
UserMigrate::migrateUser($UserData->getUserLogin(), $UserData->getUserPass());
|
||||
} catch (SPException $e) {
|
||||
$Log = new Log(__FUNCTION__);
|
||||
$Log->addDescription($e->getMessage());
|
||||
$Log->addDetails(_('Login'), $userLogin);
|
||||
$Log->addDetails(_('Login'), $UserData->getUserLogin());
|
||||
$Log->writeLog();
|
||||
|
||||
return false;
|
||||
@@ -126,14 +125,14 @@ class Auth
|
||||
$Data = new QueryData();
|
||||
$Data->setMapClassName('SP\DataModel\UserPassData');
|
||||
$Data->setQuery($query);
|
||||
$Data->addParam($userLogin);
|
||||
$Data->addParam($UserData->getUserLogin());
|
||||
|
||||
/** @var UserPassData $queryRes */
|
||||
$queryRes = DB::getResults($Data);
|
||||
|
||||
return ($queryRes !== false
|
||||
&& $Data->getQueryNumRows() === 1
|
||||
&& $queryRes->getUserPass() === crypt($userPass, $queryRes->getUserHashSalt()));
|
||||
&& $queryRes->getUserPass() === crypt($UserData->getUserPass(), $queryRes->getUserHashSalt()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -35,6 +35,10 @@ class LdapAuthData
|
||||
* @var string
|
||||
*/
|
||||
protected $dn;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $groupDn;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
@@ -191,4 +195,20 @@ class LdapAuthData
|
||||
{
|
||||
$this->ldapStatus = $ldapStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getGroupDn()
|
||||
{
|
||||
return $this->groupDn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $groupDn
|
||||
*/
|
||||
public function setGroupDn($groupDn)
|
||||
{
|
||||
$this->groupDn = $groupDn;
|
||||
}
|
||||
}
|
||||
@@ -144,8 +144,8 @@ abstract class LdapBase implements LdapInterface, AuthInterface
|
||||
throw new SPException(SPException::SP_ERROR, $Log->getDescription());
|
||||
}
|
||||
|
||||
@ldap_set_option($this->ldapHandler, LDAP_OPT_NETWORK_TIMEOUT, 10); // Set timeout
|
||||
@ldap_set_option($this->ldapHandler, LDAP_OPT_PROTOCOL_VERSION, 3); // Set LDAP version
|
||||
@ldap_set_option($this->ldapHandler, LDAP_OPT_NETWORK_TIMEOUT, 10);
|
||||
@ldap_set_option($this->ldapHandler, LDAP_OPT_PROTOCOL_VERSION, 3);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -315,7 +315,7 @@ abstract class LdapBase implements LdapInterface, AuthInterface
|
||||
*/
|
||||
public function setUserLogin($userLogin)
|
||||
{
|
||||
$this->userLogin = $userLogin;
|
||||
$this->userLogin = strtolower($userLogin);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -331,7 +331,7 @@ abstract class LdapBase implements LdapInterface, AuthInterface
|
||||
}
|
||||
|
||||
try {
|
||||
$this->userLogin = $UserData->getUserLogin();
|
||||
$this->setUserLogin($UserData->getUserLogin());
|
||||
|
||||
$this->connect();
|
||||
$this->bind();
|
||||
@@ -407,6 +407,8 @@ abstract class LdapBase implements LdapInterface, AuthInterface
|
||||
$count = (int)$values['count'];
|
||||
|
||||
if ($count > 1) {
|
||||
unset($values['count']);
|
||||
|
||||
$res[$validAttributes[$normalizedAttribute]] = $values;
|
||||
} else {
|
||||
// Almacenamos 1 solo valor
|
||||
@@ -422,6 +424,14 @@ abstract class LdapBase implements LdapInterface, AuthInterface
|
||||
$this->LdapUserData->setEmail($res['mail']);
|
||||
$this->LdapUserData->setExpire($res['expire']);
|
||||
$this->LdapUserData->setGroups($res['group']);
|
||||
|
||||
if ($this->group !== null
|
||||
&& $this->group !== ''
|
||||
&& $this->group !== '*'
|
||||
) {
|
||||
$this->LdapUserData->setGroupDn($this->searchGroupDN());
|
||||
}
|
||||
|
||||
$this->LdapUserData->setInGroup($this->searchUserInGroup());
|
||||
|
||||
return $this->LdapUserData;
|
||||
@@ -514,7 +524,19 @@ abstract class LdapBase implements LdapInterface, AuthInterface
|
||||
*/
|
||||
protected function escapeLdapDN($dn)
|
||||
{
|
||||
$chars = ['/(,)(?!uid|cn|ou|dc)/i', '/(?<!uid|cn|ou|dc)(=)/i', '/(")/', '/(;)/', '/(>)/', '/(<)/', '/(\+)/', '/(#)/', '/\G(\s)/', '/(\s)(?=\s*$)/', '/(\/)/'];
|
||||
$chars = [
|
||||
'/(,)(?!uid|cn|ou|dc)/i',
|
||||
'/(?<!uid|cn|ou|dc)(=)/i',
|
||||
'/(")/',
|
||||
'/(;)/',
|
||||
'/(>)/',
|
||||
'/(<)/',
|
||||
'/(\+)/',
|
||||
'/(#)/',
|
||||
'/\G(\s)/',
|
||||
'/(\s)(?=\s*$)/',
|
||||
'/(\/)/'
|
||||
];
|
||||
return preg_replace($chars, '\\\$1', $dn);
|
||||
}
|
||||
|
||||
@@ -527,8 +549,8 @@ abstract class LdapBase implements LdapInterface, AuthInterface
|
||||
protected function searchGroupDN()
|
||||
{
|
||||
$Log = new Log(__FUNCTION__);
|
||||
$filter = $this->getGroupName() ?: $this->group;
|
||||
$filter = '(cn=' . $filter . ')';
|
||||
$group = $this->getGroupName() ?: $this->group;
|
||||
$filter = '(cn=' . $group . ')';
|
||||
|
||||
$searchRes = @ldap_search($this->ldapHandler, $this->searchBase, $filter, ['dn', 'cn']);
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
namespace SP\Auth\Ldap;
|
||||
|
||||
use Auth\Ldap\LdapBase;
|
||||
use SP\Config\Config;
|
||||
use SP\Core\Exceptions\SPException;
|
||||
use SP\Log\Log;
|
||||
|
||||
@@ -33,7 +33,7 @@ use SP\Log\Log;
|
||||
*
|
||||
* @package SP\Auth\Ldap
|
||||
*/
|
||||
class LdapMads extends LdapBase
|
||||
class LdapMsAds extends LdapBase
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -45,7 +45,6 @@ class LdapMads extends LdapBase
|
||||
{
|
||||
$groupDN = (!empty($this->group)) ? $this->searchGroupDN() : '*';
|
||||
|
||||
|
||||
return '(&(|(memberOf=' . $groupDN . ')(groupMembership=' . $groupDN . ')(memberof:1.2.840.113556.1.4.1941:=' . $groupDN . '))(|(objectClass=inetOrgPerson)(objectClass=person)(objectClass=simpleSecurityObject)))';
|
||||
}
|
||||
|
||||
@@ -56,12 +55,14 @@ class LdapMads extends LdapBase
|
||||
*/
|
||||
protected function pickServer()
|
||||
{
|
||||
if (preg_match('/[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}/', $this->server)) {
|
||||
return $this->server;
|
||||
$server = Config::getConfig()->getLdapServer();
|
||||
|
||||
if (preg_match('/[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}/', $server)) {
|
||||
return $server;
|
||||
}
|
||||
|
||||
$serverDomain = '';
|
||||
$serverFQDN = explode('.', $this->server);
|
||||
$serverFQDN = explode('.', $server);
|
||||
|
||||
for ($i = 1; $i <= count($serverFQDN) - 1; $i++) {
|
||||
$serverDomain .= $serverFQDN[$i] . '.';
|
||||
@@ -71,7 +72,7 @@ class LdapMads extends LdapBase
|
||||
$records = dns_get_record($dnsServerQuery, DNS_NS);
|
||||
|
||||
if (count($records) === 0) {
|
||||
return $this->server;
|
||||
return $server;
|
||||
}
|
||||
|
||||
$ads = [];
|
||||
@@ -80,7 +81,9 @@ class LdapMads extends LdapBase
|
||||
$ads[] = $record['target'];
|
||||
};
|
||||
|
||||
return count($ads) > 0 ? $ads[mt_rand(0, count($ads) - 1)] : $this->server;
|
||||
$nAds = count($ads);
|
||||
|
||||
return $nAds > 0 ? $ads[mt_rand(0, $nAds)] : $server;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,13 +106,11 @@ class LdapMads extends LdapBase
|
||||
{
|
||||
$Log = new Log(__FUNCTION__);
|
||||
|
||||
$groupDN = $this->getGroupName() ?: $this->group;
|
||||
|
||||
// Comprobar si está establecido el filtro de grupo o el grupo coincide con
|
||||
// los grupos del usuario
|
||||
if (!$this->group
|
||||
|| $this->group === '*'
|
||||
|| in_array($groupDN, $this->LdapUserData->getGroups())
|
||||
|| in_array($this->LdapUserData->getGroupDn(), $this->LdapUserData->getGroups())
|
||||
) {
|
||||
$Log->addDescription(_('Usuario verificado en grupo'));
|
||||
$Log->writeLog();
|
||||
@@ -117,6 +118,7 @@ class LdapMads extends LdapBase
|
||||
return true;
|
||||
}
|
||||
|
||||
$groupDN = $this->LdapUserData->getGroupDn();
|
||||
$filter = '(memberof:1.2.840.113556.1.4.1941:=' . $groupDN . ')';
|
||||
|
||||
$searchRes = @ldap_search($this->ldapHandler, $this->searchBase, $filter, ['sAMAccountName']);
|
||||
@@ -143,12 +145,17 @@ class LdapMads extends LdapBase
|
||||
throw new SPException(SPException::SP_ERROR, $Log->getDescription());
|
||||
}
|
||||
|
||||
foreach (ldap_get_entries($this->ldapHandler, $searchRes) as $entry) {
|
||||
if ($this->userLogin === $entry['samaccountname'][0]) {
|
||||
$Log->addDescription(_('Usuario verificado en grupo'));
|
||||
$Log->writeLog();
|
||||
$entries = ldap_get_entries($this->ldapHandler, $searchRes);
|
||||
|
||||
return true;
|
||||
foreach ($entries as $entry) {
|
||||
if (is_array($entry)) {
|
||||
if ($this->userLogin === strtolower($entry['samaccountname'][0])) {
|
||||
$Log->addDescription(_('Usuario verificado en grupo'));
|
||||
$Log->addDetails(_('Grupo'), $groupDN);
|
||||
$Log->writeLog();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,4 +165,16 @@ class LdapMads extends LdapBase
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function connect()
|
||||
{
|
||||
parent::connect();
|
||||
|
||||
@ldap_set_option($this->ldapHandler, LDAP_OPT_REFERRALS, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -77,14 +77,11 @@ class LdapStd extends LdapBase
|
||||
{
|
||||
$Log = new Log(__FUNCTION__);
|
||||
|
||||
$groupDN = $this->getGroupName() ?: $this->group;
|
||||
$userDN = $this->escapeLdapDN($this->LdapUserData->getDn());
|
||||
|
||||
// Comprobar si está establecido el filtro de grupo o el grupo coincide con
|
||||
// los grupos del usuario
|
||||
if (!$this->group
|
||||
|| $this->group === '*'
|
||||
|| in_array($groupDN, $this->LdapUserData->getGroups())
|
||||
|| in_array($this->LdapUserData->getGroupDn(), $this->LdapUserData->getGroups())
|
||||
) {
|
||||
$Log->addDescription(_('Usuario verificado en grupo'));
|
||||
$Log->writeLog();
|
||||
@@ -92,15 +89,18 @@ class LdapStd extends LdapBase
|
||||
return true;
|
||||
}
|
||||
|
||||
$filter = '(&(cn=' . $groupDN . ')(|(member=' . $userDN . ')(uniqueMember=' . $userDN . '))(|(objectClass=groupOfNames)(objectClass=groupOfUniqueNames)(objectClass=group)))';
|
||||
$userDN = $this->LdapUserData->getDn();
|
||||
$groupName = $this->getGroupName() ?: $this->group;
|
||||
|
||||
$filter = '(&(cn=' . $groupName . ')(|(member=' . $userDN . ')(uniqueMember=' . $userDN . '))(|(objectClass=groupOfNames)(objectClass=groupOfUniqueNames)(objectClass=group)))';
|
||||
|
||||
$searchRes = @ldap_search($this->ldapHandler, $this->searchBase, $filter, ['member', 'uniqueMember']);
|
||||
|
||||
if (!$searchRes) {
|
||||
$Log->setLogLevel(Log::ERROR);
|
||||
$Log->addDescription(_('Error al buscar el grupo de usuarios'));
|
||||
$Log->addDetails(_('Grupo'), $groupDN);
|
||||
$Log->addDetails(_('Usuario'), $this->LdapUserData->getDn());
|
||||
$Log->addDetails(_('Grupo'), $groupName);
|
||||
$Log->addDetails(_('Usuario'), $userDN);
|
||||
$Log->addDetails('LDAP ERROR', sprintf('%s (%d)', ldap_error($this->ldapHandler), ldap_errno($this->ldapHandler)));
|
||||
$Log->addDetails('LDAP FILTER', $filter);
|
||||
$Log->writeLog();
|
||||
@@ -110,15 +110,14 @@ class LdapStd extends LdapBase
|
||||
|
||||
if (@ldap_count_entries($this->ldapHandler, $searchRes) === 0) {
|
||||
$Log->addDescription(_('Usuario no pertenece al grupo'));
|
||||
$Log->addDetails(_('Usuario'), $this->LdapUserData->getDn());
|
||||
$Log->addDetails(_('Grupo'), $groupDN);
|
||||
$Log->addDetails(_('Usuario'), $userDN);
|
||||
$Log->addDetails(_('Grupo'), $groupName);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$Log->addDescription(_('Usuario verificado en grupo'));
|
||||
$Log->addDescription($groupDN);
|
||||
$Log->addDescription($filter);
|
||||
$Log->addDescription($groupName);
|
||||
$Log->writeLog();
|
||||
|
||||
return true;
|
||||
|
||||
@@ -254,6 +254,7 @@
|
||||
<input type="hidden" name="ldap_enabled" value="0"/>
|
||||
<?php endif; ?>
|
||||
|
||||
<input type="hidden" name="type" value="ldap"/>
|
||||
<input type="hidden" name="activeTab" value="<?php echo $ldap_tabIndex; ?>"/>
|
||||
<input type="hidden" name="actionId" value="<?php echo $ldap_actionId; ?>"/>
|
||||
<input type="hidden" name="sk" value="">
|
||||
|
||||
@@ -261,6 +261,7 @@
|
||||
<input type="hidden" name="wiki_enabled" value="1"/>
|
||||
<?php endif; ?>
|
||||
|
||||
<input type="hidden" name="type" value="dokuwiki"/>
|
||||
<input type="hidden" name="activeTab" value="<?php echo $wiki_tabIndex; ?>"/>
|
||||
<input type="hidden" name="actionId" value="<?php echo $wiki_actionId; ?>"/>
|
||||
<input type="hidden" name="sk" value="">
|
||||
|
||||
@@ -317,46 +317,25 @@ sysPass.Actions = function (Common) {
|
||||
log.info("checks:ldap");
|
||||
|
||||
var $form = $($obj.data("src"));
|
||||
|
||||
var ldapBindPass = $form.find("[name='ldap_bindpass']").val();
|
||||
|
||||
var data = {
|
||||
type: "ldap",
|
||||
ldap_server: $form.find("[name='ldap_server']").val(),
|
||||
ldap_base: $form.find("[name='ldap_base']").val(),
|
||||
ldap_group: $form.find("[name='ldap_group']").val(),
|
||||
ldap_binduser: $form.find("[name='ldap_binduser']").val(),
|
||||
ldap_bindpass: Common.config().PK !== "" ? Common.config().CRYPT.encrypt(ldapBindPass) : ldapBindPass,
|
||||
sk: Common.sk.get(),
|
||||
isAjax: 1
|
||||
};
|
||||
$form.find("[name='sk']").val(Common.sk.get());
|
||||
|
||||
var opts = Common.appRequests().getRequestOpts();
|
||||
opts.url = ajaxUrl.checks;
|
||||
opts.data = data;
|
||||
opts.data = $form.serialize();
|
||||
|
||||
Common.appRequests().getActionCall(opts, function (json) {
|
||||
Common.msg.out(json);
|
||||
});
|
||||
|
||||
},
|
||||
wiki: function ($obj) {
|
||||
log.info("checks:wiki");
|
||||
|
||||
var $form = $($obj.data("src"));
|
||||
|
||||
var data = {
|
||||
type: "dokuwiki",
|
||||
dokuwiki_url: $form.find("[name='dokuwiki_url']").val(),
|
||||
dokuwiki_user: $form.find("[name='dokuwiki_user']").val(),
|
||||
dokuwiki_pass: $form.find("[name='dokuwiki_pass']").val(),
|
||||
isAjax: 1,
|
||||
sk: Common.sk.get()
|
||||
};
|
||||
$form.find("[name='sk']").val(Common.sk.get());
|
||||
|
||||
var opts = Common.appRequests().getRequestOpts();
|
||||
opts.url = ajaxUrl.checks;
|
||||
opts.data = data;
|
||||
opts.data = $form.serialize();
|
||||
|
||||
Common.appRequests().getActionCall(opts, function (json) {
|
||||
Common.msg.out(json);
|
||||
|
||||
Reference in New Issue
Block a user