<?php
namespace AppBundle\Controller;
use ApiBundle\Api\Exception\ErrorCode;
use AppBundle\Common\ArrayToolkit;
use AppBundle\Common\Exception\RuntimeException;
use AppBundle\Component\OAuthClient\OAuthClientFactory;
use Biz\Common\BizSms;
use CorporateTrainingBundle\System;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Security;
class LoginController extends BaseController
{
public function indexAction(Request $request)
{
$user = $this->getCurrentUser();
if ($user->isLogin()) {
return $this->createMessageResponse('info', 'login.message.repeat_login', null, 3000, $this->generateUrl('homepage'));
}
$error = $this->checkLoginError($request);
if ($error) {
$request->getSession()->remove(Security::AUTHENTICATION_ERROR);
} else {
$url = $this->checkInviteCodeLogin($request);
if (!empty($url)) {
return $this->redirect($url);
}
}
$this->callRemoteService($request, $user);
$_target_path = $this->getTargetPath($request);
$liveLogin = $this->checkLiveLogin($request, $_target_path);
return $this->render(
'login/index.html.twig',
[
'last_username' => $request->getSession()->get(Security::LAST_USERNAME),
'error' => $error,
'_target_path' => $_target_path,
'liveLogin' => $liveLogin,
]
);
}
protected function callRemoteService(Request $request, $user)
{
if (in_array('ROLE_SUPER_ADMIN', $user['roles'])) {
$siteInfo = $this->getSettingService()->get('site_info', []);
if (!empty($siteInfo) && false == $siteInfo['status']) {
$siteInfo['applicationVersion'] = System::CT_VERSION;
$siteInfo['domainName'] = $request->getHttpHost();
if (empty($siteInfo['cloud_key'])) {
$settings = $this->getSettingService()->get('storage', []);
if (!empty($settings['cloud_access_key'])) {
$siteInfo['accessKey'] = $settings['cloud_access_key'];
$this->postRequest('http://ct.edusoho.com/api/app_install', json_encode($siteInfo));
}
}
}
}
}
public function externalLoginAction(Request $request)
{
// 新增开关校验
$setting = $this->getSettingService()->get('api');
if (empty($setting['external_switch'])) {
throw new BadRequestHttpException('API设置未开启', null, ErrorCode::INVALID_ARGUMENT);
}
$token = $request->get('token', '');
if (!$token) {
throw new BadRequestHttpException('请求参数错误', null, ErrorCode::INVALID_ARGUMENT);
}
$data = JWT::decode($token, new Key($setting['api_app_secret_key'], 'HS256'));
if (empty($data) || empty($data->identifyValue) || empty($data->identifyType) || !in_array($data->identifyType, ['username', 'mobile', 'email'])) {
throw new BadRequestHttpException('请求参数错误', null, ErrorCode::INVALID_ARGUMENT);
}
$user = $this->getUserService()->getUserByLoginTypeAndField($data->identifyType, $data->identifyValue);
if (empty($user)) {
return $this->createMessageResponse('error', 'external.login.message.error', null, 0);
}
$this->authenticateUser($user);
return $this->redirect($this->generateUrl('homepage'));
}
protected function checkLiveLogin(Request $request, &$_target_path)
{
$liveLogin = preg_match('/\/live\/(.*?)\/(.*)/', $_target_path, $match);
if ($liveLogin && in_array($match[2], ['login', 'entry', 'show', 'replay'])) {
$_target_path = $this->generateUrl('live_activity_play', ['activityId' => $match[1]]);
}
return $liveLogin ? $match[1] : 0;
}
public function ajaxAction(Request $request)
{
$clients = OAuthClientFactory::clients();
return $this->render('login/ajax.html.twig', [
'_target_path' => $this->getTargetPath($request),
'clients' => $clients,
]);
}
public function checkEmailAction(Request $request)
{
$email = $request->query->get('value');
$user = $this->getUserService()->getUserByEmail($email);
if ($user) {
$response = ['success' => true, 'message' => '该Email地址可以登录'];
} else {
$response = ['success' => false, 'message' => '该Email地址尚未注册'];
}
return $this->createJsonResponse($response);
}
public function oauth2LoginsBlockAction($targetPath, $displayName = true, $isMayday = 0)
{
$clients = OAuthClientFactory::clients();
return $this->render('login/oauth2-logins-block.html.twig', [
'clients' => $clients,
'targetPath' => $targetPath,
'displayName' => $displayName,
'isMayday' => $isMayday,
]);
}
public function smsAction(Request $request)
{
$user = $this->getCurrentUser();
if ($user->isLogin()) {
return $this->createMessageResponse('info', '你已经登录了', null, 3000, $this->getTargetPath($request));
}
if ($request->isMethod('POST')) {
if (!$this->checkSmsCode($request)) {
throw new RuntimeException('短信验证码错误!');
}
// 按手机号获取用户,没有就注册
$user = $this->getUserService()->getUserByVerifiedMobile($request->request->get('login_mobile'));
if (empty($user)) {
throw new RuntimeException('该手机账号不存在');
}
if ($user['locked']) {
throw new RuntimeException('该用户已被封禁!');
}
$this->authenticateUser($user);
return $this->createJsonResponse(['goto' => $this->getTargetPath($request)]);
}
return $this->render('login/sms.html.twig', [
'_target_path' => $this->getTargetPath($request),
]);
}
public function checkMobileAction(Request $request)
{
$mobile = $request->request->get('mobile', '');
$result = !empty($mobile) && !empty($this->getUserService()->getUserByVerifiedMobile($mobile));
return $this->createJsonResponse($result);
}
public function checkSmsCodeAction(Request $request)
{
return $this->createJsonResponse($this->checkSmsCode($request));
}
public function captchaCheckAction(Request $request)
{
$captchaFilledByUser = strtolower($request->request->get('value'));
if ($request->getSession()->get('captcha_code') == $captchaFilledByUser) {
$response = true;
} else {
$request->getSession()->set('captcha_code', mt_rand(0, 999999999));
$response = false;
}
return $this->createJsonResponse($response);
}
protected function checkInviteCodeLogin(Request $request)
{
if ($this->getWebExtension()->isMicroMessenger() && $this->setting('login_bind.enabled', 0) && $this->setting('login_bind.weixinmob_enabled', 0)) {
$inviteCode = $request->query->get('inviteCode', '');
return $this->generateUrl('login_bind', ['type' => 'weixinmob', '_target_path' => $this->getTargetPath($request), 'inviteCode' => $inviteCode]);
}
if ($this->getCTWebExtension()->isDingTalk() && $this->setting('login_bind.enabled', 0) && $this->setting('login_bind.dingtalkmob_enabled', 0)) {
$inviteCode = $request->query->get('inviteCode', '');
return $this->generateUrl('login_bind', ['type' => 'dingtalkmob', '_target_path' => $this->getTargetPath($request), 'inviteCode' => $inviteCode]);
}
if ($this->getCTWebExtension()->isWorkWechat() && $this->setting('login_bind.enabled', 0) && $this->setting('login_bind.workwechatmob_enabled', 0)) {
$inviteCode = $request->query->get('inviteCode', '');
return $this->generateUrl('login_bind', ['type' => 'workwechatmob', '_target_path' => $this->getTargetPath($request), 'inviteCode' => $inviteCode]);
}
if ($this->getCTWebExtension()->isFeiShu() && $this->setting('login_bind.enabled', 0) && $this->setting('login_bind.feishumob_enabled', 0)) {
$inviteCode = $request->query->get('inviteCode', '');
return $this->generateUrl('login_bind', ['type' => 'feishumob', '_target_path' => $this->getTargetPath($request), 'inviteCode' => $inviteCode]);
}
return 0;
}
protected function getCTWebExtension()
{
return $this->container->get('corporatetrainingbundle.twig.web_extension');
}
protected function checkLoginError(Request $request)
{
if ($request->attributes->has(Security::AUTHENTICATION_ERROR)) {
return $request->attributes->get(Security::AUTHENTICATION_ERROR);
}
return $request->getSession()->get(Security::AUTHENTICATION_ERROR);
}
protected function checkSmsCode(Request $request)
{
$fields = $request->request->all();
if (!ArrayToolkit::requireds($fields, ['login_mobile', 'sms_token', 'login_sms_code'])) {
return false;
}
// 检查短信验证码
$status = $this->getBizSms()->check(BizSms::SMS_LOGIN, $fields['login_mobile'], $fields['sms_token'], $fields['login_sms_code']);
if (BizSms::STATUS_SUCCESS !== $status) {
return false;
}
return true;
}
protected function getTargetPath(Request $request)
{
if ($request->query->get('goto')) {
$targetPath = $request->query->get('goto');
} elseif ($request->getSession()->has('_target_path')) {
$targetPath = $request->getSession()->get('_target_path');
} else {
$targetPath = $request->headers->get('Referer', '');
}
if ($targetPath == $this->generateUrl('login', [], UrlGeneratorInterface::ABSOLUTE_URL)) {
return $this->generateUrl('homepage');
}
$url = explode('?', $targetPath);
if ($url[0] == $this->generateUrl('partner_logout', [], UrlGeneratorInterface::ABSOLUTE_URL)) {
return $this->generateUrl('homepage');
}
if ($url[0] == $this->generateUrl('password_reset_update', [], UrlGeneratorInterface::ABSOLUTE_URL)) {
$targetPath = $this->generateUrl('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL);
}
if (0 === strpos($targetPath, '/app.php')) {
$targetPath = str_replace('/app.php', '', $targetPath);
}
return $targetPath;
}
protected function getWebExtension()
{
return $this->container->get('web.twig.extension');
}
/**
* @return BizSms
*/
protected function getBizSms()
{
$biz = $this->getBiz();
return $biz['biz_sms'];
}
protected function getSettingService()
{
return $this->container->get('biz')->service('System:SettingService');
}
}