feat(global config & single login): global config & single login
Description: 全局配置与单点登录 Log: 无
This commit is contained in:
parent
2b8038b74d
commit
953fb420e5
|
@ -35,6 +35,7 @@ void KeyWatcher::run()
|
|||
current.c_cc[VMIN] = 1;
|
||||
current.c_cc[VTIME] = 0;
|
||||
tcsetattr(0, TCSANOW, ¤t);
|
||||
bool isInputEnd = false;
|
||||
|
||||
while(!isInterruptionRequested()){
|
||||
|
||||
|
@ -52,11 +53,18 @@ void KeyWatcher::run()
|
|||
break;
|
||||
default:
|
||||
// 'q' | 'Q' or Esc
|
||||
if((ch = getchar()) == 'q' || ch == 'Q' || ch == 27){
|
||||
if((ch = getchar()) == 'q' || ch == 'Q' || ch == 27 || ch == EOF){
|
||||
tcsetattr(0, TCSANOW, &save);
|
||||
emit exit();
|
||||
if (ch == EOF) {
|
||||
isInputEnd = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isInputEnd) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tcsetattr(0, TCSANOW, &save); // 恢复原来的终端属性,以免干扰shall和之后的程序运行
|
||||
|
|
|
@ -93,6 +93,22 @@ void showMessage(const QString &message, int type)
|
|||
fprintf(stdout, RESET_COLOR);
|
||||
}
|
||||
|
||||
static bool isQuickInput() {
|
||||
fd_set readfds;
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(0, &readfds); // stdin
|
||||
struct timeval timeout = {0, 10*1000};
|
||||
switch (select(32, &readfds, NULL, NULL, &timeout)) {
|
||||
case 0: // time out
|
||||
break;
|
||||
case -1: // error
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QString inputPinCode()
|
||||
{
|
||||
struct termios current;
|
||||
|
@ -241,7 +257,7 @@ int main(int argc, char *argv[])
|
|||
a.installTranslator(&translator_bin);
|
||||
|
||||
QCommandLineParser parser;
|
||||
QCommandLineOption serviceOption({"s", "service"}, QObject::tr("Sevice Name"));
|
||||
QCommandLineOption serviceOption({"s", "service"}, QObject::tr("Sevice Name"), "service", "");
|
||||
QCommandLineOption displayOption({"x", "display"}, QObject::tr("DISPLAY env"), "display", ":0");
|
||||
QCommandLineOption usernameOption({"u", "user"}, QObject::tr("User"), "user", "");
|
||||
QCommandLineOption debugOption({"d", "debug"}, QObject::tr("Display debug information"));
|
||||
|
@ -258,6 +274,11 @@ int main(int argc, char *argv[])
|
|||
logPrefix = "[pam-diaglog]:";
|
||||
qInstallMessageHandler(outputMessage);
|
||||
|
||||
QString serverName = parser.value(serviceOption);
|
||||
if (serverName == "sudo" && isQuickInput()) {
|
||||
exit(BIO_ERROR);
|
||||
}
|
||||
|
||||
QString userName = parser.value(usernameOption);
|
||||
if(userName.isEmpty())
|
||||
exit(BIO_ERROR);
|
||||
|
@ -298,12 +319,13 @@ int main(int argc, char *argv[])
|
|||
});
|
||||
QObject::connect(&bioAuth, &BioAuth::authComplete, &a, [&](uid_t uid_, int result, int retErrNo){
|
||||
Q_UNUSED(retErrNo);
|
||||
|
||||
watcher.stop();
|
||||
bool isBioEnable = bioDevices.GetBioAuthEnable(uid_);
|
||||
bool isUkeyDevice = false;
|
||||
if(deviceInfo && deviceInfo->biotype == 6){
|
||||
isUkeyDevice = true;
|
||||
}
|
||||
bool isUkeyDevice = false;
|
||||
if(deviceInfo && deviceInfo->biotype == 6){
|
||||
isUkeyDevice = true;
|
||||
}
|
||||
if(!isBioEnable && !isUkeyDevice){
|
||||
showMessage(QObject::tr("BIOMETRIC AUTHENTICATION IS CLOSED"), RESULT);
|
||||
exit(BIO_IGNORE);
|
||||
|
@ -328,11 +350,11 @@ int main(int argc, char *argv[])
|
|||
showMessage(QObject::tr("Unable to verify %1, please enter password.").arg(bioDevices.bioTypeToString_tr(curDeviceInfo->biotype)),RESULT);
|
||||
exit(BIO_IGNORE);
|
||||
}
|
||||
Option option = showOption(bioDevices.count() > 1);
|
||||
Option option = showOption(bioDevices.getAllDevices().count() > 1);
|
||||
switch(option) {
|
||||
case OPTION_TRY_AGAIN:
|
||||
|
||||
if(deviceInfo->biotype == 6){
|
||||
if(deviceInfo->biotype == 6){
|
||||
QString code = inputPinCode();
|
||||
bioAuth.SetExtraInfo("pincode",code);
|
||||
}
|
||||
|
@ -346,7 +368,7 @@ int main(int argc, char *argv[])
|
|||
*deviceInfo = showDevices(bioDevices.getAllDevices());
|
||||
bioAuth.setDevice(deviceInfo);
|
||||
|
||||
if(deviceInfo->biotype == 6){
|
||||
if(deviceInfo->biotype == 6){
|
||||
QString code = inputPinCode();
|
||||
bioAuth.SetExtraInfo("pincode",code);
|
||||
}
|
||||
|
@ -360,12 +382,12 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
exit(BIO_ERROR);
|
||||
}else{
|
||||
if(deviceInfo->biotype == 6){
|
||||
showMessage(QObject::tr("AUTHENTICATION END"), START);
|
||||
if(deviceInfo->biotype == 6){
|
||||
showMessage(QObject::tr("AUTHENTICATION END"), START);
|
||||
}else{
|
||||
showMessage(QObject::tr("BIOMETRIC AUTHENTICATION END"), START);
|
||||
}
|
||||
exit(BIO_IGNORE);
|
||||
showMessage(QObject::tr("BIOMETRIC AUTHENTICATION END"), START);
|
||||
}
|
||||
exit(BIO_IGNORE);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -375,8 +397,8 @@ int main(int argc, char *argv[])
|
|||
});
|
||||
|
||||
if(deviceInfo->biotype == 6){
|
||||
QString code = inputPinCode();
|
||||
bioAuth.SetExtraInfo("pincode",code);
|
||||
QString code = inputPinCode();
|
||||
bioAuth.SetExtraInfo("pincode",code);
|
||||
}
|
||||
|
||||
bioAuth.startAuth();
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="mn">
|
||||
<context>
|
||||
<name>BioAuthWidget</name>
|
||||
<message>
|
||||
<location filename="../src/bioauthwidget.ui" line="14"/>
|
||||
<source>Form</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>More</source>
|
||||
<translation type="vanished">更多</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/bioauthwidget.ui" line="146"/>
|
||||
<location filename="../src/bioauthwidget.cpp" line="41"/>
|
||||
<source>Retry</source>
|
||||
<translation>ᠳᠠᠬᠢᠨ ᠲᠤᠷᠰᠢᠬᠤ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Too many unsuccessful attempts,please enter password.</source>
|
||||
<translation type="vanished">验证失败达最大次数,请使用密码解锁</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bioauth authentication failed, you still have %1 verification opportunities</source>
|
||||
<translation type="vanished">生物认证失败,您还有%1次尝试机会</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Password</source>
|
||||
<translation>ᠨᠢᠭᠤᠴᠠ ᠺᠣᠳ᠋</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Current Device: </source>
|
||||
<translation type="vanished">当前设备:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/bioauthwidget.cpp" line="96"/>
|
||||
<location filename="../src/bioauthwidget.cpp" line="212"/>
|
||||
<source>%1 too many unsuccessful attempts,please enter password.</source>
|
||||
<translation>%1 ᠢᠯᠠᠭᠳᠠᠭᠰᠠᠨ ᠲᠤᠷᠰᠢᠬᠤ ᠤᠳᠠᠭᠠ ᠲᠣᠭᠠ ᠬᠡᠳᠦ ᠣᠯᠠᠨ ᠂ ᠨᠢᠭᠤᠴᠠ ᠺᠣᠳ᠋ ᠣᠷᠣᠭᠤᠯᠤᠭᠠᠷᠠᠢ ᠃</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/bioauthwidget.cpp" line="102"/>
|
||||
<source>%1 authentication failure,there are still %2 remaining opportunities</source>
|
||||
<translation>%1 ᠪᠡᠶᠡᠶ᠋ᠢᠨ ᠬᠢᠷᠢᠶ᠋ᠢᠨ ᠰᠢᠯᠭᠠᠨ ᠪᠠᠲᠤᠯᠠᠯᠲᠠ ᠢᠯᠠᠭᠳᠠᠪᠠ ᠂ ᠮᠥᠨ %2 ᠦᠯᠡᠳᠡᠬᠦ ᠲᠣᠬᠢᠶᠠᠯ ᠪᠣᠢ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/bioauthwidget.cpp" line="226"/>
|
||||
<source>Please use wechat to scan the code</source>
|
||||
<translation>ᠸᠢᠴᠠᠲᠢ᠋ᠶ᠋ᠠᠷ ᠦᠰᠦᠭ ᠰᠢᠷᠪᠢᠬᠦ ᠪᠣᠯᠪᠠᠤ</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>BioDevices</name>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="78"/>
|
||||
<source>Unplugging of %1 device detected</source>
|
||||
<translation>%1 ᠲᠥᠬᠥᠭᠡᠷᠦᠮᠵᠢᠶ᠋ᠢ ᠰᠤᠭᠤᠯᠵᠤ ᠭᠠᠷᠭᠠᠨ ᠠ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="88"/>
|
||||
<source>%1 device insertion detected</source>
|
||||
<translation>%1 ᠲᠥᠬᠥᠭᠡᠷᠦᠮᠵᠢ ᠬᠠᠪᠴᠢᠭᠤᠯᠤᠭᠰᠠᠨᠢ᠋ ᠪᠠᠢᠴᠠᠭᠠᠨ ᠣᠯᠪᠠ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="97"/>
|
||||
<source>ukui-biometric-manager</source>
|
||||
<translation>ᠠᠮᠢᠳᠤ ᠪᠣᠳᠠᠰᠤ᠋ᠨ ᠣᠨᠴᠠᠯᠢᠭ ᠬᠠᠮᠢᠶᠠᠷᠤᠯᠲᠠᠶ᠋ᠢᠨ ᠪᠠᠭᠠᠵᠢ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="100"/>
|
||||
<source>biometric</source>
|
||||
<translation>ᠠᠮᠢᠳᠤ ᠪᠣᠳᠠᠰᠤ᠋ᠨ ᠣᠨᠴᠠᠯᠢᠭ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="647"/>
|
||||
<source>FingerPrint</source>
|
||||
<translation>ᠬᠤᠷᠤᠭᠤᠨ ᠬᠡ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="649"/>
|
||||
<source>FingerVein</source>
|
||||
<translation>ᠬᠤᠷᠤᠭᠤᠨ ᠨᠠᠮᠵᠢᠭᠤᠨ ᠰᠤᠳᠠᠰᠤ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="651"/>
|
||||
<source>Iris</source>
|
||||
<translation>ᠰᠣᠯᠣᠩᠭᠠ ᠪᠦᠷᠬᠦᠭᠦᠯ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="653"/>
|
||||
<source>Face</source>
|
||||
<translation>ᠬᠥᠮᠦᠨᠦ᠌ ᠨᠢᠭᠤᠷ ᠲᠠᠨᠢᠬᠤ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="655"/>
|
||||
<source>VoicePrint</source>
|
||||
<translation>ᠳᠠᠭᠤᠨ ᠡᠷᠢᠶᠡᠨ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="657"/>
|
||||
<source>ukey</source>
|
||||
<translation>ᠠᠶᠤᠯᠭᠦᠢ ᠨᠢᠭᠤᠴᠠ ᠲᠦᠯᠬᠢᠭᠦᠷ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="659"/>
|
||||
<source>QRCode</source>
|
||||
<translation>ᠬᠣᠶᠠᠷ ᠬᠡᠮᠵᠢᠯᠲᠦ ᠺᠣᠳ᠋</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Wechat</source>
|
||||
<translation type="vanished">微信</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>BioDevicesWidget</name>
|
||||
<message>
|
||||
<location filename="../src/biodeviceswidget.ui" line="14"/>
|
||||
<source>Form</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Device types:</source>
|
||||
<translation type="vanished">设备类型:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Back</source>
|
||||
<translation type="vanished">返回</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>OK</source>
|
||||
<translation type="vanished">确定</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FingerPrint</source>
|
||||
<translation type="vanished">指纹</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LoginOptionsWidget</name>
|
||||
<message>
|
||||
<location filename="../src/loginoptionswidget.cpp" line="61"/>
|
||||
<source>Login Options</source>
|
||||
<translation>ᠲᠡᠮᠳᠡᠭᠯᠡᠬᠦ ᠰᠤᠩᠭᠤᠭᠳᠠᠬᠤᠨ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/loginoptionswidget.cpp" line="294"/>
|
||||
<source>Password</source>
|
||||
<translation>ᠨᠢᠭᠤᠴᠠ ᠺᠣᠳ᠋</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Wechat</source>
|
||||
<translation type="vanished">微信</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Biometric</source>
|
||||
<translation type="vanished">生物识别</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QObject</name>
|
||||
<message>
|
||||
<source>FingerPrint</source>
|
||||
<translation type="vanished">指纹</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FingerVein</source>
|
||||
<translation type="vanished">指静脉</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Iris</source>
|
||||
<translation type="vanished">虹膜</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Face</source>
|
||||
<translation type="vanished">人脸</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>VoicePrint</source>
|
||||
<translation type="vanished">声纹</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
|
@ -100,8 +100,8 @@
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="657"/>
|
||||
<source>ukey</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<source>Ukey</source>
|
||||
<translation>安全密钥</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="659"/>
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="zh_Hant">
|
||||
<context>
|
||||
<name>BioAuthWidget</name>
|
||||
<message>
|
||||
<location filename="../src/bioauthwidget.ui" line="14"/>
|
||||
<source>Form</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>More</source>
|
||||
<translation type="vanished">更多</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/bioauthwidget.ui" line="146"/>
|
||||
<location filename="../src/bioauthwidget.cpp" line="41"/>
|
||||
<source>Retry</source>
|
||||
<translation>重試</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Too many unsuccessful attempts,please enter password.</source>
|
||||
<translation type="vanished">验证失败达最大次数,请使用密码解锁</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bioauth authentication failed, you still have %1 verification opportunities</source>
|
||||
<translation type="vanished">生物认证失败,您还有%1次尝试机会</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Password</source>
|
||||
<translation>密碼</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Current Device: </source>
|
||||
<translation type="vanished">当前设备:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/bioauthwidget.cpp" line="96"/>
|
||||
<location filename="../src/bioauthwidget.cpp" line="212"/>
|
||||
<source>%1 too many unsuccessful attempts,please enter password.</source>
|
||||
<translation>%1失敗的嘗試次數太多,請輸入密碼</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/bioauthwidget.cpp" line="102"/>
|
||||
<source>%1 authentication failure,there are still %2 remaining opportunities</source>
|
||||
<translation>%1 身份驗證失敗,仍有 %2 個剩餘機會</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/bioauthwidget.cpp" line="226"/>
|
||||
<source>Please use wechat to scan the code</source>
|
||||
<translation>請使用微信掃碼</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>BioDevices</name>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="78"/>
|
||||
<source>Unplugging of %1 device detected</source>
|
||||
<translation>檢測到 %1 設備的拔出</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="88"/>
|
||||
<source>%1 device insertion detected</source>
|
||||
<translation>檢測到 %1 個設備插入</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="97"/>
|
||||
<source>ukui-biometric-manager</source>
|
||||
<translation>生物特徵管理工具</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="100"/>
|
||||
<source>biometric</source>
|
||||
<translation>生物特徵管理工具</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="647"/>
|
||||
<source>FingerPrint</source>
|
||||
<translation>指紋</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="649"/>
|
||||
<source>FingerVein</source>
|
||||
<translation>指靜脈</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="651"/>
|
||||
<source>Iris</source>
|
||||
<translation>虹膜</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="653"/>
|
||||
<source>Face</source>
|
||||
<translation>人臉</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="655"/>
|
||||
<source>VoicePrint</source>
|
||||
<translation>聲紋</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="657"/>
|
||||
<source>ukey</source>
|
||||
<translation>安全金鑰</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/biodevices.cpp" line="659"/>
|
||||
<source>QRCode</source>
|
||||
<translation>微信掃碼</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Wechat</source>
|
||||
<translation type="vanished">微信</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>BioDevicesWidget</name>
|
||||
<message>
|
||||
<location filename="../src/biodeviceswidget.ui" line="14"/>
|
||||
<source>Form</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Device types:</source>
|
||||
<translation type="vanished">设备类型:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Back</source>
|
||||
<translation type="vanished">返回</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>OK</source>
|
||||
<translation type="vanished">确定</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FingerPrint</source>
|
||||
<translation type="vanished">指纹</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LoginOptionsWidget</name>
|
||||
<message>
|
||||
<location filename="../src/loginoptionswidget.cpp" line="61"/>
|
||||
<source>Login Options</source>
|
||||
<translation>登錄選項</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/loginoptionswidget.cpp" line="294"/>
|
||||
<source>Password</source>
|
||||
<translation>密碼</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Wechat</source>
|
||||
<translation type="vanished">微信</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Biometric</source>
|
||||
<translation type="vanished">生物识别</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QObject</name>
|
||||
<message>
|
||||
<source>FingerPrint</source>
|
||||
<translation type="vanished">指纹</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FingerVein</source>
|
||||
<translation type="vanished">指静脉</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Iris</source>
|
||||
<translation type="vanished">虹膜</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Face</source>
|
||||
<translation type="vanished">人脸</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>VoicePrint</source>
|
||||
<translation type="vanished">声纹</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
|
@ -62,6 +62,7 @@ public:
|
|||
|
||||
signals:
|
||||
void authComplete(int uid, bool result, int retErrNo);
|
||||
void authFinished();
|
||||
void notify(const QString &message);
|
||||
void notifyDetail(int deviceId, const QString &message);
|
||||
void frameWritten(int deviceId);
|
||||
|
|
|
@ -57,6 +57,7 @@ public:
|
|||
void setIsShowHotPlug(bool isShow);
|
||||
int GetUserDevFeatureCount(int uid,int drvid);
|
||||
int GetUserDevCount(int uid);
|
||||
FeatureMap GetUserFeatures(int uid);
|
||||
bool getUseFirstDevice();
|
||||
int getFailedTimes();
|
||||
bool GetHiddenSwitchButton();
|
||||
|
@ -71,6 +72,8 @@ public:
|
|||
*/
|
||||
StatusReslut UpdateStatus(int drvid);
|
||||
bool GetBioAuthEnable(uid_t uid);
|
||||
bool GetDirveIsIdle(int drvid);
|
||||
void recordAuthDrive(QString appName,int drvid,bool insert);
|
||||
|
||||
private:
|
||||
void connectToService();
|
||||
|
|
|
@ -225,6 +225,9 @@ Q_DECLARE_METATYPE(DeviceInfo)
|
|||
typedef std::shared_ptr<DeviceInfo> DeviceInfoPtr;
|
||||
typedef QList<DeviceInfoPtr> DeviceList;
|
||||
typedef QMap<int, DeviceList> DeviceMap;
|
||||
typedef std::shared_ptr<FeatureInfo> FeatureInfoPtr;
|
||||
typedef QList<FeatureInfoPtr> FeatureList;
|
||||
typedef QMap<QString, FeatureList> FeatureMap;
|
||||
|
||||
QDBusArgument &operator<<(QDBusArgument &argument, const DeviceInfo &deviceInfo);
|
||||
const QDBusArgument &operator>>(const QDBusArgument &argument, DeviceInfo &deviceInfo);
|
||||
|
|
|
@ -100,6 +100,7 @@ public:
|
|||
public slots:
|
||||
void readDevicesInfo();
|
||||
void onIdentifyComplete(int uid, bool ret, int retErrNo);
|
||||
void onAuthFinished();
|
||||
void onStatusChanged(int drvid, const QString &message);
|
||||
void onFrameWritten(int drvid);
|
||||
void onUSBDeviceCountChange(int newNum);
|
||||
|
|
|
@ -61,9 +61,13 @@ public Q_SLOTS:
|
|||
bool getUseFirstDevice();
|
||||
// 获取是否隐藏切换按钮
|
||||
bool getHiddenSwitchButton();
|
||||
|
||||
// 获取正在认证的应用
|
||||
QStringList getAuthingApp();
|
||||
// 获取应用认证的驱动
|
||||
int getAuthingAppDrivd(QString appName);
|
||||
public:
|
||||
bool isActivatable();
|
||||
void recordAuthDrive(QString appName,int drvid,bool insert);
|
||||
|
||||
Q_SIGNALS:
|
||||
//默认设备改变
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
**/
|
||||
#include "bioauth.h"
|
||||
#include <QList>
|
||||
#include <unistd.h>
|
||||
|
||||
BioAuth::BioAuth(qint32 uid, const DeviceInfoPtr deviceInfo, QObject *parent)
|
||||
: QObject(parent),
|
||||
|
@ -110,6 +111,11 @@ void BioAuth::startAuth()
|
|||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, &BioAuth::onIdentityComplete);
|
||||
}else{
|
||||
//使用sudo等命令时,不停止设备,当存在其他可认证设备时,使用其他可认证设备,否则使用密码
|
||||
if(qAppName() != "bioauth"){
|
||||
//stopops在identify之前使用时,不要调用getFeaturelist,否则会出现identify被停止的现象,应该时框架的bug。
|
||||
serviceInterface->call("StopOps", QVariant(deviceInfo->device_id), QVariant(3000));
|
||||
}
|
||||
QDBusPendingCall call = serviceInterface->asyncCallWithArgumentList("Identify", args);
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, &BioAuth::onIdentityComplete);
|
||||
|
@ -175,6 +181,7 @@ void BioAuth::stopAuth()
|
|||
|
||||
QDBusReply<int> reply = serviceInterface->call("StopOps", QVariant(deviceInfo->device_id), QVariant(3000));
|
||||
|
||||
emit authFinished();
|
||||
if(!reply.isValid())
|
||||
qWarning() << "StopOps error: " << reply.error();
|
||||
|
||||
|
@ -188,6 +195,7 @@ bool BioAuth::isAuthenticating()
|
|||
|
||||
void BioAuth::onIdentityComplete(QDBusPendingCallWatcher *watcher)
|
||||
{
|
||||
emit authFinished();
|
||||
QDBusPendingReply<qint32, qint32> reply = *watcher;
|
||||
if(reply.isError()){
|
||||
isInAuthentication = false;
|
||||
|
@ -227,6 +235,11 @@ void BioAuth::onStatusChanged(int deviceId, int statusType)
|
|||
LOG() << msg.errorMessage();
|
||||
return;
|
||||
}
|
||||
|
||||
if(deviceInfo && deviceInfo->device_id != deviceId){
|
||||
return ;
|
||||
}
|
||||
|
||||
QString message = msg.arguments().at(0).toString();
|
||||
LOG() << message;
|
||||
Q_EMIT notify(message);
|
||||
|
|
|
@ -94,7 +94,7 @@ void BioDevices::onUSBDeviceHotPlug(int deviceId, int action, int devNumNow)
|
|||
"org.freedesktop.Notifications",
|
||||
QDBusConnection::sessionBus());
|
||||
QList<QVariant> args;
|
||||
args<<(tr("ukui-biometric-manager"))
|
||||
args<<(tr("Biometric Manager"))
|
||||
<<((unsigned int) 0)
|
||||
<<"biometric-manager"
|
||||
<<tr("biometric")
|
||||
|
@ -200,10 +200,32 @@ int BioDevices::GetUserDevCount(int uid)
|
|||
|
||||
}
|
||||
|
||||
FeatureMap BioDevices::GetUserFeatures(int uid)
|
||||
{
|
||||
FeatureMap featureMap;
|
||||
QList<QDBusVariant> qlist;
|
||||
int listsize;
|
||||
QDBusMessage result = serviceInterface->call(QStringLiteral("GetAllFeatureList"), uid, 0, -1);
|
||||
if(result.type() == QDBusMessage::ErrorMessage)
|
||||
{
|
||||
qWarning() << "GetDevList error:" << result.errorMessage();
|
||||
return featureMap;
|
||||
}
|
||||
|
||||
QList<QVariant> variantList = result.arguments();
|
||||
listsize = variantList[0].value<int>();
|
||||
variantList[1].value<QDBusArgument>() >> qlist;
|
||||
for (int i = 0; i < listsize; i++) {
|
||||
FeatureInfoPtr pFeatureInfo = std::make_shared<FeatureInfo>();
|
||||
qlist[i].variant().value<QDBusArgument>() >> *pFeatureInfo;
|
||||
featureMap[pFeatureInfo->device_shortname].append(pFeatureInfo);
|
||||
}
|
||||
|
||||
return featureMap;
|
||||
}
|
||||
|
||||
int BioDevices::GetUserDevFeatureCount(int uid,int drvid)
|
||||
{
|
||||
// stop last option
|
||||
serviceInterface->call("StopOps", QVariant(drvid), QVariant(3000));
|
||||
QDBusMessage FeatureResult = serviceInterface->call(QStringLiteral("GetFeatureList"),drvid,uid,0,-1);
|
||||
if(FeatureResult.type() == QDBusMessage::ErrorMessage)
|
||||
{
|
||||
|
@ -218,7 +240,6 @@ int BioDevices::getFeatureCount(int uid, int indexStart, int indexEnd)
|
|||
int res = 0;
|
||||
for(int i = 0; i < deviceInfos.count(); i++) {
|
||||
DeviceInfoPtr deviceInfo = deviceInfos.at(i);
|
||||
QDBusReply<int> reply = serviceInterface->call("StopOps", QVariant(deviceInfo->device_id), QVariant(3000));
|
||||
QDBusMessage featurecount = serviceInterface->call("GetFeatureList",deviceInfo->device_id,uid,indexStart,indexEnd);
|
||||
if(featurecount.type() == QDBusMessage::ErrorMessage)
|
||||
{
|
||||
|
@ -237,6 +258,10 @@ QMap<int, QList<DeviceInfo>> BioDevices::getAllDevices()
|
|||
for(auto deviceInfo : deviceInfos) {
|
||||
if (deviceInfo->biotype == REMOTE_QRCODE_TYPE) // 终端不使用扫码
|
||||
continue;
|
||||
|
||||
if(!GetDirveIsIdle(deviceInfo->device_id))
|
||||
continue;
|
||||
|
||||
devices[deviceInfo->biotype].push_back(*deviceInfo);
|
||||
}
|
||||
|
||||
|
@ -406,6 +431,7 @@ DeviceInfoPtr BioDevices::getDefaultDevice(uid_t uid,int bioType)
|
|||
if(deviceInfos.size() <= 0)
|
||||
return nullptr;
|
||||
|
||||
FeatureMap mapFeatures = GetUserFeatures(uid);
|
||||
if (m_uniAuthService && m_uniAuthService->isActivatable()) {
|
||||
QString defaultDeviceName = "";
|
||||
struct passwd *pwdInfo = getpwuid(uid);
|
||||
|
@ -416,7 +442,8 @@ DeviceInfoPtr BioDevices::getDefaultDevice(uid_t uid,int bioType)
|
|||
if(!strDeviceName.isEmpty()) {
|
||||
ptrDevInfo = findDevice(strDeviceName);
|
||||
if (ptrDevInfo) {
|
||||
if (GetUserDevFeatureCount(uid,ptrDevInfo->device_id) > 0) {
|
||||
int isIdle = GetDirveIsIdle(ptrDevInfo->device_id);
|
||||
if(isIdle && mapFeatures.contains(ptrDevInfo->device_shortname)){
|
||||
defaultDeviceName = strDeviceName;
|
||||
}
|
||||
}
|
||||
|
@ -454,9 +481,11 @@ DeviceInfoPtr BioDevices::getDefaultDevice(uid_t uid,int bioType)
|
|||
bool defValid = false;
|
||||
DeviceInfoPtr ptrDevInfo = findDevice(defaultDeviceName);
|
||||
if (ptrDevInfo) {
|
||||
if (GetUserDevFeatureCount(uid,ptrDevInfo->device_id) > 0) {
|
||||
int isIdle = GetDirveIsIdle(ptrDevInfo->device_id);
|
||||
if(isIdle && mapFeatures.contains(ptrDevInfo->device_shortname)){
|
||||
defValid = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!defValid) {
|
||||
|
@ -467,11 +496,34 @@ DeviceInfoPtr BioDevices::getDefaultDevice(uid_t uid,int bioType)
|
|||
}
|
||||
}
|
||||
|
||||
void BioDevices::recordAuthDrive(QString appName, int drvid, bool insert)
|
||||
{
|
||||
if(m_uniAuthService && m_uniAuthService->isActivatable()){
|
||||
m_uniAuthService->recordAuthDrive(appName,drvid,insert);
|
||||
}
|
||||
}
|
||||
|
||||
bool BioDevices::GetDirveIsIdle(int drvid)
|
||||
{
|
||||
if(m_uniAuthService && m_uniAuthService->isActivatable()){
|
||||
QStringList appList = m_uniAuthService->getAuthingApp();
|
||||
for(QString appName : appList){
|
||||
int id = m_uniAuthService->getAuthingAppDrivd(appName);
|
||||
if(id == drvid){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DeviceInfoPtr BioDevices::getDefaultDevice(uid_t uid)
|
||||
{
|
||||
if(deviceInfos.size() <= 0)
|
||||
return nullptr;
|
||||
|
||||
FeatureMap mapFeatures = GetUserFeatures(uid);
|
||||
if (m_uniAuthService && m_uniAuthService->isActivatable()) {
|
||||
QString defaultDeviceName = "";
|
||||
struct passwd *pwdInfo = getpwuid(uid);
|
||||
|
@ -483,7 +535,8 @@ DeviceInfoPtr BioDevices::getDefaultDevice(uid_t uid)
|
|||
if(!strDeviceName.isEmpty()) {
|
||||
ptrDevInfo = findDevice(strDeviceName);
|
||||
if (ptrDevInfo) {
|
||||
if (GetUserDevFeatureCount(uid,ptrDevInfo->device_id) > 0) {
|
||||
int isIdle = GetDirveIsIdle(ptrDevInfo->device_id);
|
||||
if(isIdle && mapFeatures.contains(ptrDevInfo->device_shortname)){
|
||||
defaultDeviceName = strDeviceName;
|
||||
break;
|
||||
}
|
||||
|
@ -525,7 +578,7 @@ DeviceInfoPtr BioDevices::getDefaultDevice(uid_t uid)
|
|||
bool defValid = false;
|
||||
DeviceInfoPtr ptrDevInfo = findDevice(defaultDeviceName);
|
||||
if (ptrDevInfo) {
|
||||
if (GetUserDevFeatureCount(uid,ptrDevInfo->device_id) > 0) {
|
||||
if (mapFeatures.contains(ptrDevInfo->device_shortname)) {
|
||||
defValid = true;
|
||||
}
|
||||
}
|
||||
|
@ -654,7 +707,7 @@ QString BioDevices::bioTypeToString_tr(int type)
|
|||
case BIOTYPE_VOICEPRINT:
|
||||
return tr("VoicePrint");
|
||||
case LOGINOPT_TYPE_GENERAL_UKEY:
|
||||
return tr("ukey");
|
||||
return tr("Ukey");
|
||||
case REMOTE_QRCODE_TYPE:
|
||||
return tr("QRCode");
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ LoginOptionsWidget::LoginOptionsWidget(QWidget *parent)
|
|||
, m_bioDevices(new BioDevices())
|
||||
, w_timer(nullptr)
|
||||
{
|
||||
m_bioDevices->recordAuthDrive("polkit",0,false);
|
||||
initUI();
|
||||
initConnections();
|
||||
m_mapDisableDev.clear();
|
||||
|
@ -161,6 +162,9 @@ void LoginOptionsWidget::initConnections()
|
|||
|
||||
connect(m_biomericProxy, &BioAuth::authComplete,
|
||||
this, &LoginOptionsWidget::onIdentifyComplete);
|
||||
|
||||
connect(m_biomericProxy, &BioAuth::authFinished,
|
||||
this, &LoginOptionsWidget::onAuthFinished);
|
||||
}
|
||||
if (m_bioDevices) {
|
||||
connect(m_bioDevices, &BioDevices::deviceCountChanged,
|
||||
|
@ -399,6 +403,9 @@ void LoginOptionsWidget::readDevicesInfo()
|
|||
bool isQRCodeEnable = m_bioDevices->GetQRCodeEnable();
|
||||
DeviceList deviceList = m_bioDevices->GetDevList();
|
||||
QStringList listDefDevices = m_bioDevices->getAllDefDevices();
|
||||
FeatureMap mapFeatures = m_bioDevices->GetUserFeatures(m_uid);
|
||||
qDebug() << m_uid <<",count:"<<mapFeatures.size();
|
||||
|
||||
for(auto pDeviceInfo : deviceList)
|
||||
{
|
||||
int nDevFeatureCount = 0;
|
||||
|
@ -407,8 +414,8 @@ void LoginOptionsWidget::readDevicesInfo()
|
|||
} else {
|
||||
if (m_uid == -1) {
|
||||
nDevFeatureCount = 0;
|
||||
} else {
|
||||
nDevFeatureCount = m_bioDevices->GetUserDevFeatureCount(m_uid, pDeviceInfo->device_id);
|
||||
} else if(mapFeatures.contains(pDeviceInfo->device_shortname)){
|
||||
nDevFeatureCount = mapFeatures[pDeviceInfo->device_shortname].size();
|
||||
}
|
||||
}
|
||||
qDebug() << *pDeviceInfo << ",FeatureCount:"<<nDevFeatureCount;
|
||||
|
@ -496,6 +503,7 @@ void LoginOptionsWidget::startAuth_()
|
|||
m_labelFaceLoad->show();
|
||||
}
|
||||
w_timer->start();
|
||||
m_bioDevices->recordAuthDrive("polkit",m_curDevInfo->device_id,true);
|
||||
m_biomericProxy->startAuth(m_uid, m_curDevInfo);
|
||||
}
|
||||
|
||||
|
@ -530,6 +538,13 @@ void LoginOptionsWidget::updatePixmap()
|
|||
}
|
||||
}
|
||||
|
||||
void LoginOptionsWidget::onAuthFinished()
|
||||
{
|
||||
if(m_bioDevices){
|
||||
m_bioDevices->recordAuthDrive("polkit",0,false);
|
||||
}
|
||||
}
|
||||
|
||||
void LoginOptionsWidget::onIdentifyComplete(int uid, bool ret, int retErrNo)
|
||||
{
|
||||
if(m_isStopped == true)
|
||||
|
|
|
@ -245,6 +245,45 @@ bool UniAuthService::getHiddenSwitchButton()
|
|||
}
|
||||
}
|
||||
|
||||
// 获取正在认证的应用
|
||||
QStringList UniAuthService::getAuthingApp()
|
||||
{
|
||||
QDBusMessage result = call(QStringLiteral("getAllAuthApp"));
|
||||
if(result.type() == QDBusMessage::ErrorMessage)
|
||||
{
|
||||
qWarning() << "getAuthingApp error:" << result.errorMessage();
|
||||
return QStringList();
|
||||
}
|
||||
QList<QVariant> varResult = result.arguments();
|
||||
if (varResult.size() > 0) {
|
||||
return varResult.takeFirst().toStringList();
|
||||
} else {
|
||||
return QStringList();
|
||||
}
|
||||
}
|
||||
|
||||
// 获取应用认证的驱动
|
||||
int UniAuthService::getAuthingAppDrivd(QString appName)
|
||||
{
|
||||
QDBusMessage result = call(QStringLiteral("getAppAuthDrive"),appName);
|
||||
if(result.type() == QDBusMessage::ErrorMessage)
|
||||
{
|
||||
qWarning() << "getAuthingAppDrivd error:" << result.errorMessage();
|
||||
return -1;
|
||||
}
|
||||
QList<QVariant> varResult = result.arguments();
|
||||
if (varResult.size() > 0) {
|
||||
return varResult.takeFirst().toInt();
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void UniAuthService::recordAuthDrive(QString appName,int drvid,bool insert)
|
||||
{
|
||||
call(QStringLiteral("recordAuthDrive"),appName,drvid,insert);
|
||||
}
|
||||
|
||||
bool UniAuthService::isActivatable()
|
||||
{
|
||||
return m_isActivatable;
|
||||
|
|
|
@ -16,7 +16,10 @@ Build-Depends: cmake (>= 2.6),
|
|||
qttools5-dev,
|
||||
qttools5-dev-tools,
|
||||
libkysdk-sysinfo-dev,
|
||||
libukui-log4qt-dev
|
||||
libukui-log4qt-dev,
|
||||
libssl-dev,
|
||||
libkf5windowsystem-dev,
|
||||
liblightdm-qt5-3-dev
|
||||
Standards-Version: 4.5.0
|
||||
Rules-Requires-Root: no
|
||||
Homepage: https://github.com/ukui/ukui-biometric-auth
|
||||
|
|
|
@ -1 +1 @@
|
|||
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16"><defs><clipPath id="clip-path"><circle cx="8" cy="8" r="8" fill="none"/></clipPath></defs><g clip-path="url(#clip-path)"><path d="M8.2,4.33H8A2.3,2.3,0,0,0,5.73,5.91a3.59,3.59,0,0,0-.09,1.5,14.1,14.1,0,0,1-1.3,8.89.45.45,0,0,0,.18.61.54.54,0,0,0,.21.05.46.46,0,0,0,.4-.24,15,15,0,0,0,1.4-9.43,2.83,2.83,0,0,1,.06-1.11c.13-.4.41-.87,1.49-.95H8.2a1.26,1.26,0,0,1,1.24.85A11.83,11.83,0,0,1,10,8.35,8.18,8.18,0,0,1,10,9.58v.57a.85.85,0,0,1,0,.16.44.44,0,0,0,.38.5h.06a.45.45,0,0,0,.45-.39,1.51,1.51,0,0,0,0-.3V9.58a10.42,10.42,0,0,0-.07-1.36,13.39,13.39,0,0,0-.56-2.43A2.16,2.16,0,0,0,8.2,4.33Z" fill="#1a1a1a"/><path d="M8.05,1a6.57,6.57,0,0,0-1.23.12,5.81,5.81,0,0,0-4.6,6.76c.08.52.14,1,.21,1.57l.09.74a.44.44,0,0,0,.45.39H3a.44.44,0,0,0,.38-.5l-.09-.74c-.06-.53-.13-1.06-.21-1.6A4.91,4.91,0,0,1,7,2,5.33,5.33,0,0,1,8,1.9a5.33,5.33,0,0,1,3.8,1.69.43.43,0,0,0,.31.13.42.42,0,0,0,.32-.13.45.45,0,0,0,0-.64A6.15,6.15,0,0,0,8.05,1Z" fill="#1a1a1a"/><path d="M5.54,4.88h0M5.3,3.93a.49.49,0,0,0-.2,0,1.64,1.64,0,0,0-.58.56,4.38,4.38,0,0,0-.6,3.38,13.61,13.61,0,0,1-.11,5,9.55,9.55,0,0,1-1,2.68A.45.45,0,0,0,3,16.2a.42.42,0,0,0,.22.05A.45.45,0,0,0,3.64,16,10.4,10.4,0,0,0,4.69,13.1a14.69,14.69,0,0,0,.12-5.31,3.4,3.4,0,0,1,.44-2.72,1,1,0,0,1,.25-.28.46.46,0,0,0,.2-.61.45.45,0,0,0-.4-.25Z" fill="#1a1a1a"/><path d="M8.15,2.72a5.46,5.46,0,0,0-1.51.22.45.45,0,0,0-.31.56.43.43,0,0,0,.43.32h.12a4.42,4.42,0,0,1,1.25-.19,3.07,3.07,0,0,1,3,2.23,13.82,13.82,0,0,1,.57,4.41,19.75,19.75,0,0,1-.91,5.93,3.74,3.74,0,0,1-.18.48.44.44,0,0,0,.21.6.43.43,0,0,0,.19,0,.45.45,0,0,0,.41-.25c.09-.19.16-.39.23-.58a20.8,20.8,0,0,0,.95-6.22A14.66,14.66,0,0,0,12,5.56,3.93,3.93,0,0,0,8.15,2.72Z" fill="#1a1a1a"/><path d="M3,13.15H3m-.5-.69a.45.45,0,0,0-.4.25,2.37,2.37,0,0,0-.18.53,3,3,0,0,1-.1.32c-.07.16-.15.32-.23.49a6.25,6.25,0,0,0-.31.69.45.45,0,0,0,.26.58.44.44,0,0,0,.16,0,.45.45,0,0,0,.42-.29,4.57,4.57,0,0,1,.28-.6c.09-.18.18-.36.25-.54a2.44,2.44,0,0,0,.14-.44,1.89,1.89,0,0,1,.12-.36.46.46,0,0,0-.21-.61.45.45,0,0,0-.2,0Z" fill="#1a1a1a"/><path d="M13.25,4.89h-.1a.46.46,0,0,0-.34.54,22.64,22.64,0,0,1,.58,5.38,18,18,0,0,1-.66,4.74l0,.14v0a.45.45,0,0,0,.05.57.46.46,0,0,0,.33.13.47.47,0,0,0,.31-.12.81.81,0,0,0,.21-.46.15.15,0,0,1,0-.07,18.82,18.82,0,0,0,.69-5,23.9,23.9,0,0,0-.6-5.59.45.45,0,0,0-.44-.34Z" fill="#1a1a1a"/><path d="M10.35,11.43a.44.44,0,0,0-.45.39,17.13,17.13,0,0,1-1.28,5.06.45.45,0,0,0,.22.6.43.43,0,0,0,.19,0,.45.45,0,0,0,.41-.26,18.25,18.25,0,0,0,1.35-5.33.45.45,0,0,0-.39-.5Z" fill="#1a1a1a"/><path d="M8,15.61H8m-.49-.69a.46.46,0,0,0-.41.26l-.64,1.37a.45.45,0,0,0,.21.6.46.46,0,0,0,.19,0,.44.44,0,0,0,.41-.26l.64-1.37A.44.44,0,0,0,7.71,15a.49.49,0,0,0-.19-.05Z" fill="#1a1a1a"/><path d="M8.06,6.56H8a.46.46,0,0,0-.37.52,17.57,17.57,0,0,1-.07,6.52.45.45,0,0,0,.35.53H8a.44.44,0,0,0,.44-.35A18.12,18.12,0,0,0,8.5,6.93a.43.43,0,0,0-.44-.37Z" fill="#1a1a1a"/></g></svg>
|
||||
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#262626;}</style></defs><path class="cls-1" d="M2.79,13.45a2.53,2.53,0,0,1,.12-.36.46.46,0,0,0-.21-.61H2.5v0a.46.46,0,0,0-.4.25,2.19,2.19,0,0,0-.17.49,6.9,6.9,0,0,0,.71.72v0A2.25,2.25,0,0,0,2.79,13.45Z"/><path class="cls-1" d="M10.4,11.39l-.05,0a.44.44,0,0,0-.45.39A16.89,16.89,0,0,1,9,15.93a6.54,6.54,0,0,0,1-.19,18.07,18.07,0,0,0,.81-3.85A.44.44,0,0,0,10.4,11.39Z"/><path class="cls-1" d="M7.71,15A.41.41,0,0,0,7.52,15v0a.46.46,0,0,0-.41.26l-.33.72c.3,0,.61.07.92.08l.22-.46A.43.43,0,0,0,7.71,15Z"/><path class="cls-1" d="M6.53,7.29a3,3,0,0,1,.06-1.11c.13-.4.41-.87,1.49-.95H8.2a1.25,1.25,0,0,1,1.24.85A12,12,0,0,1,10,8.35a8.42,8.42,0,0,1,0,1.23v.57a.43.43,0,0,1,0,.16.44.44,0,0,0,.37.5h.07a.45.45,0,0,0,.45-.39,1.5,1.5,0,0,0,0-.3V9.58a10.33,10.33,0,0,0-.07-1.36,13.39,13.39,0,0,0-.56-2.43A2.15,2.15,0,0,0,8.2,4.33H8A2.31,2.31,0,0,0,5.73,5.91a3.46,3.46,0,0,0-.09,1.5,14.16,14.16,0,0,1-.85,7.91,8.36,8.36,0,0,0,.83.32A15,15,0,0,0,6.53,7.29Z"/><path class="cls-1" d="M12.43,3A6.14,6.14,0,0,0,8.05,1a6.41,6.41,0,0,0-1.23.12,5.81,5.81,0,0,0-4.6,6.76c.08.52.14,1,.21,1.57l.09.74a.44.44,0,0,0,.45.39H3a.44.44,0,0,0,.38-.49h0l-.09-.74c-.06-.53-.13-1.06-.21-1.6A4.92,4.92,0,0,1,7,2H7a5.56,5.56,0,0,1,1-.1,5.38,5.38,0,0,1,3.8,1.69.44.44,0,0,0,.31.13.42.42,0,0,0,.32-.13.45.45,0,0,0,0-.64Z"/><path class="cls-1" d="M4.81,7.79a3.43,3.43,0,0,1,.44-2.72,1,1,0,0,1,.25-.28.46.46,0,0,0,.2-.61.46.46,0,0,0-.4-.25.67.67,0,0,0-.2,0,1.64,1.64,0,0,0-.58.56,4.38,4.38,0,0,0-.6,3.38,13.56,13.56,0,0,1-.11,5,9.89,9.89,0,0,1-.5,1.6A7.11,7.11,0,0,0,4.1,15a10.26,10.26,0,0,0,.59-1.88A14.81,14.81,0,0,0,4.81,7.79Z"/><path class="cls-1" d="M12,5.56A3.93,3.93,0,0,0,8.15,2.72a5.51,5.51,0,0,0-1.51.22.45.45,0,0,0-.31.55h0a.43.43,0,0,0,.43.32h.12a4.46,4.46,0,0,1,1.25-.19,3.07,3.07,0,0,1,3,2.23,13.72,13.72,0,0,1,.57,4.41A19.83,19.83,0,0,1,11,15.41a8.06,8.06,0,0,0,1.06-.53,20.79,20.79,0,0,0,.53-4.65A14.73,14.73,0,0,0,12,5.56Z"/><path class="cls-1" d="M13.72,5.15a.45.45,0,0,0-.44-.34l0,.08h-.1a.46.46,0,0,0-.34.54,22.63,22.63,0,0,1,.58,5.38,18.5,18.5,0,0,1-.35,3.4,7.35,7.35,0,0,0,1.12-1.11,18.59,18.59,0,0,0,.16-2.36A23.88,23.88,0,0,0,13.72,5.15Z"/><path class="cls-1" d="M8.06,6.56H8a.46.46,0,0,0-.37.52,17.65,17.65,0,0,1-.07,6.52.45.45,0,0,0,.35.53H8a.44.44,0,0,0,.44-.35A17.94,17.94,0,0,0,8.5,6.93.43.43,0,0,0,8.06,6.56Z"/></svg>
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.4 KiB |
|
@ -8,9 +8,11 @@
|
|||
<description>Run the biometric authentication control tool</description>
|
||||
<description xml:lang="zh">运行生物识别认证控制工具</description>
|
||||
<description xml:lang="bo">འཁོར་སྐྱོད་སྐྱེ་དངོས་ཀྱི་ངོས་འཛིན་ཁས་ལེན་ཚོད་འཛིན་ཡོ་བྱད།།</description>
|
||||
<description xml:lang="mn">ᠠᠵᠢᠯᠯᠠᠭᠠᠨ ᠤ ᠠᠮᠢᠳᠤ ᠪᠣᠳᠠᠰ ᠢ ᠢᠯᠭᠠᠨ ᠲᠠᠨᠢᠵᠤ ᠭᠡᠷᠡᠴᠢᠯᠡᠬᠦ ᠡᠵᠡᠮᠳᠡᠯ ᠦᠨ ᠪᠠᠭᠠᠵᠢ ᠶᠢ ᠢᠯᠭᠠᠨ ᠲᠠᠨᠢᠬᠤ ᠬᠡᠷᠡᠭᠲᠡᠶ ᠃</description>
|
||||
<message>Authentication is required to enable or disable biometric authentication</message>
|
||||
<message xml:lang="zh">开启或关闭生物识别认证需要进行身份验证</message>
|
||||
<message xml:lang="bo">སྒོ་རྒྱག་པའམ་ཡང་ན་སྒོ་རྒྱག་པའི་སྐྱེ་དངོས་ངོས་འཛིན་བདེན་དཔངར་སྤྲོད་བྱེད་པར་ཐོབ་ཐང་གི་ཚོད་ལྟསར་སྤྲོད་བྱ་དགོས།</message>
|
||||
<message xml:lang="mn">ᠠᠮᠢᠳᠤ ᠪᠣᠳᠠᠰ ᠢ ᠢᠯᠭᠠᠨ ᠲᠠᠨᠢᠬᠤ ᠭᠡᠷᠡᠴᠢᠯᠡᠭᠡ ᠶᠢ ᠨᠡᠭᠡᠭᠡᠬᠦ ᠪᠤᠶᠤ ᠬᠠᠭᠠᠬᠤ ᠳᠤ ᠪᠡᠶᠡ ᠶᠢᠨ ᠭᠠᠷᠤᠯ ᠤᠨ ᠭᠡᠷᠡᠴᠢᠯᠡᠯ ᠬᠢᠬᠦ ᠴᠢᠬᠤᠯᠠ ᠲᠠᠶ ᠪᠠᠶᠢᠨᠠ᠃</message>
|
||||
<icon_name>stock_person</icon_name>
|
||||
<defaults>
|
||||
<allow_any>no</allow_any>
|
||||
|
|
|
@ -8,9 +8,11 @@
|
|||
<description>Run the biometric device driver control tool</description>
|
||||
<description xml:lang="zh">运行生物识别设备驱动控制工具</description>
|
||||
<description xml:lang="bo">སྐྱ་དངོས་དབྱེ་འབྱེད་སྒྲག་ཆས་ཀྱི་ཁ་ལོ་བའི་ཚོད་འཛིན་ཡོ་བྱད་</description>
|
||||
<description xml:lang="mn">ᠠᠮᠢᠳᠤ ᠪᠣᠳᠠᠰ ᠢ ᠢᠯᠭᠠᠨ ᠲᠠᠨᠢᠬᠤ ᠲᠥᠬᠥᠭᠡᠷᠦᠮᠵᠢ ᠪᠡᠷ ᠬᠥᠳᠡᠯᠭᠡᠭᠦᠷ ᠪᠣᠯᠭᠠᠬᠤ ᠡᠵᠡᠮᠳᠡᠯ ᠦᠨ ᠪᠠᠭᠠᠵᠢ ᠶᠢ ᠠᠵᠢᠯᠯᠠᠭᠤᠯᠤᠨᠠ ᠃</description>
|
||||
<message>Authentication is required to change the status of biometric device's driver</message>
|
||||
<message xml:lang="zh">改变生物识别设备驱动状态需要进行身份验证</message>
|
||||
<message xml:lang="bo">སྐྱ་དངོས་དབྱེ་འབྱེད་སྒྲག་ཆས་ཀྱི་ཁ་ལོ་བའི་གནས་ཚུལ་ལ་འགྱུར་ལྡོག་གཏོང་བར་བདེན་དཔང་ར་སྤྲད་བྱ་དགོས།</message>
|
||||
<message xml:lang="bo">སྐྱ་དངོས་དབྱེ་འབྱེད་སྒྲག་ཆས་ཀྱི་ཁ་ལོ་བའི་གནས་ཚུལ་ལ་འགྱུར་ལྡོག་གཏོང་བར་བདེན་དཔང་ར་སྤྲད་བྱ་དགོས།</message>
|
||||
<message xml:lang="mn">ᠠᠮᠢᠳᠤ ᠪᠣᠳᠠᠰ ᠢ ᠢᠯᠭᠠᠨ ᠲᠠᠨᠢᠬᠤ ᠲᠥᠬᠥᠭᠡᠷᠦᠮᠵᠢ ᠶᠢᠨ ᠬᠥᠳᠡᠯᠭᠡᠭᠦᠷ ᠪᠣᠯᠭᠠᠬᠤ ᠪᠠᠶᠢᠳᠠᠯ ᠢ ᠬᠤᠪᠢᠷᠠᠭᠤᠯᠬᠤ ᠳᠤ ᠪᠡᠶᠡ ᠶᠢᠨ ᠭᠠᠷᠤᠯ ᠤᠨ ᠭᠡᠷᠡᠴᠢᠯᠡᠯ ᠬᠢᠬᠦ ᠴᠢᠬᠤᠯᠠ ᠲᠠᠶ ᠪᠠᠶᠢᠬᠤ ᠬᠡᠷᠡᠭᠲᠡᠶ᠃</message>
|
||||
<icon_name>stock_person</icon_name>
|
||||
<defaults>
|
||||
<allow_any>auth_admin</allow_any>
|
||||
|
|
|
@ -8,9 +8,11 @@
|
|||
<description>Restart Service</description>
|
||||
<description xml:lang="zh">重启生物特征服务</description>
|
||||
<description xml:lang="bo">བསྐྱར་དུ་ཞབས་འདེགས་ཞུ་བ</description>
|
||||
<description xml:lang="mn">ᠠᠮᠢᠳᠤ ᠪᠣᠳᠠᠰ ᠤᠨ ᠣᠨᠴᠠᠯᠢᠭ ᠤᠨ ᠦᠢᠯᠡᠴᠢᠯᠡᠭᠡ ᠶᠢ ᠳᠠᠬᠢᠨ ᠡᠭᠢᠯᠡᠭᠦᠯᠪᠡ᠃</description>
|
||||
<message>Authentication is required to restart biometric service</message>
|
||||
<message xml:lang="zh">重启生物特征服务需要身份验证</message>
|
||||
<message xml:lang="bo">སྐྱ་དངོས་དབྱེ་འབྱེད་ཞབས་ཞུ་སླར་གསོ་བྱེད་པར་བདེན་དཔང་ར་སྤྲད་བྱ་དགོས།</message>
|
||||
<message xml:lang="bo">སྐྱ་དངོས་དབྱེ་འབྱེད་ཞབས་ཞུ་སླར་གསོ་བྱེད་པར་བདེན་དཔང་ར་སྤྲད་བྱ་དགོས།</message>
|
||||
<message xml:lang="mn">ᠠᠮᠢᠳᠤ ᠪᠣᠳᠠᠰ ᠤᠨ ᠣᠨᠴᠠᠯᠢᠭ ᠰᠢᠨᠵᠢ ᠲᠡᠮᠳᠡᠭ ᠦᠨ ᠦᠢᠯᠡᠴᠢᠯᠡᠭᠡ ᠶᠢ ᠳᠠᠬᠢᠨ ᠰᠡᠩᠬᠡᠷᠡᠭᠦᠯᠬᠦ ᠳᠦ ᠪᠡᠶᠡ ᠶᠢᠨ ᠭᠠᠷᠤᠯ ᠢ ᠰᠢᠯᠭᠠᠨ ᠭᠡᠷᠡᠴᠢᠯᠡᠬᠦ ᠴᠢᠬᠤᠯᠠ ᠲᠠᠶ ᠪᠠᠶᠢᠨᠠ ᠃</message>
|
||||
<icon_name>stock_person</icon_name>
|
||||
<defaults>
|
||||
<allow_any>auth_admin</allow_any>
|
||||
|
|
|
@ -8,6 +8,7 @@ isShownInControlCenter=false
|
|||
UseFirstDevice=true
|
||||
MaxFailedTimes=5
|
||||
HiddenSwitchButton=false
|
||||
FaceTimeoutTimes=1
|
||||
|
||||
[Functions]
|
||||
EnableQRCode=true
|
||||
|
|
|
@ -6,6 +6,7 @@ pkg_check_modules(KDKINFO REQUIRED kysdk-sysinfo)
|
|||
|
||||
find_package(PolkitQt5-1 REQUIRED 0.103.0)
|
||||
find_package(Qt5 COMPONENTS Core Widgets DBus X11Extras Xml Network Svg)
|
||||
find_package(KF5WindowSystem)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
@ -59,7 +60,7 @@ set(polkit_SRCS
|
|||
|
||||
add_executable(polkit-ukui-authentication-agent-1 ${polkit_SRCS})
|
||||
target_link_libraries(polkit-ukui-authentication-agent-1
|
||||
Qt5::Core Qt5::Widgets Qt5::DBus ${EXTRA_LIBS}
|
||||
Qt5::Core Qt5::Widgets Qt5::DBus ${EXTRA_LIBS} KF5::WindowSystem
|
||||
${POLKITQT-1_LIBRARIES}
|
||||
BioAuthWidgets
|
||||
-lrt
|
||||
|
|
|
@ -0,0 +1,441 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="mn">
|
||||
<context>
|
||||
<name>BioAuthWidget</name>
|
||||
<message>
|
||||
<source>Retry</source>
|
||||
<translation type="obsolete">重试</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%1 too many unsuccessful attempts,please enter password.</source>
|
||||
<translation type="obsolete">%1验证失败达最大次数,请使用密码登录</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%1 authentication failure,there are still %2 remaining opportunities</source>
|
||||
<translation type="obsolete">%1认证失败,还剩%2次尝试机会</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Please use wechat to scan the code</source>
|
||||
<translation type="vanished">请使用微信扫码</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>BioDevices</name>
|
||||
<message>
|
||||
<source>FingerPrint</source>
|
||||
<translation type="obsolete">指纹</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FingerVein</source>
|
||||
<translation type="obsolete">指静脉</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Iris</source>
|
||||
<translation type="obsolete">虹膜</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Face</source>
|
||||
<translation type="obsolete">人脸</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>VoicePrint</source>
|
||||
<translation type="obsolete">声纹</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Wechat</source>
|
||||
<translation type="vanished">微信</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>QRCode</source>
|
||||
<translation type="vanished">二维码</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LoginOptionsWidget</name>
|
||||
<message>
|
||||
<source>Login Options</source>
|
||||
<translation type="vanished">登录选项</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Wechat</source>
|
||||
<translation type="vanished">微信</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="65"/>
|
||||
<source>Authentication</source>
|
||||
<translation>ᠡᠷᠬᠡ ᠤᠯᠭᠤᠬᠤ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Fingerprint authentication failed, you still have %1 verification opportunities</source>
|
||||
<translation type="vanished">指纹验证失败,您还有%1次尝试机会</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.ui" line="26"/>
|
||||
<source>Form</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>More</source>
|
||||
<translation type="obsolete">更多</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Restart</source>
|
||||
<translation type="obsolete">重新开始</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Password</source>
|
||||
<translation type="vanished">密码</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.ui" line="409"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1075"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1146"/>
|
||||
<source>Biometric</source>
|
||||
<translation>ᠠᠮᠢᠳᠤ ᠪᠤᠳᠠᠰ ᠢ᠋ ᠬᠡᠷᠡᠭᠯᠡᠵᠤ ᠢᠯᠭᠠᠨ ᠳᠠᠨᠢᠬᠤ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.ui" line="480"/>
|
||||
<source>use password</source>
|
||||
<translation>ᠰᠢᠯᠭᠠᠨ ᠪᠠᠳᠤᠯᠠᠭᠰᠠᠨ ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠢ᠋ ᠬᠡᠷᠡᠭᠯᠡᠬᠦ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DeviceType:</source>
|
||||
<translation type="obsolete">设备类型:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Back</source>
|
||||
<translation type="obsolete">返回</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Details</source>
|
||||
<translation type="vanished">详细</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Action Id:</source>
|
||||
<translation type="obsolete">动作:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Description:</source>
|
||||
<translation type="vanished">描述:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Polkit.subject-pid:</source>
|
||||
<translation type="vanished">Polkit.subject-pid:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Retry</source>
|
||||
<translation type="obsolete">重试</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Device types:</source>
|
||||
<translation type="obsolete">设备类型:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Vendor:</source>
|
||||
<translation type="vanished">发行商:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Action:</source>
|
||||
<translation type="vanished">动作:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Polkit.caller-pid:</source>
|
||||
<translation type="vanished">Polkit.caller-pid:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.ui" line="441"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1077"/>
|
||||
<source>Cancel</source>
|
||||
<translation>ᠦᠬᠡᠢᠰᠭᠡᠬᠦ᠌</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.ui" line="460"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1073"/>
|
||||
<source>Authenticate</source>
|
||||
<translation>ᠡᠷᠬᠡ ᠤᠯᠭᠤᠬᠤ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="1079"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1189"/>
|
||||
<source>Use password</source>
|
||||
<translation>ᠰᠢᠯᠭᠠᠨ ᠪᠠᠳᠤᠯᠠᠭᠰᠠᠨ ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠢ᠋ ᠬᠡᠷᠡᠭᠯᠡᠬᠦ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Auth</source>
|
||||
<translation type="obsolete">授权</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Too many unsuccessful attempts,please enter password.</source>
|
||||
<translation type="vanished">指纹验证失败达最大次数,请使用密码解锁</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%1 authentication failure,there are still %2 remaining opportunities</source>
|
||||
<translation type="vanished">%1认证失败,还剩%2次尝试机会</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%1 too many unsuccessful attempts,please enter password.</source>
|
||||
<translation type="vanished">%1验证失败达最大次数,请使用密码登录</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>in authentication, please wait...</source>
|
||||
<translation type="vanished">认证中,请稍等...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="1225"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1298"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1299"/>
|
||||
<source>Please try again in %1 minutes.</source>
|
||||
<translation>%1 ᠮᠢᠨᠦ᠋ᠲᠦᠨ ᠳᠠᠷᠠᠭᠠ ᠳᠠᠬᠢᠵᠤ ᠳᠤᠷᠱᠢᠭᠠᠷᠠᠢ.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="1236"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1308"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1309"/>
|
||||
<source>Please try again in %1 seconds.</source>
|
||||
<translation>%1 ᠮᠢᠨᠦ᠋ᠲᠦᠨ ᠳᠠᠷᠠᠭᠠ ᠳᠠᠬᠢᠵᠤ ᠳᠤᠷᠱᠢᠭᠠᠷᠠᠢ.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="1246"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1247"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1317"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1318"/>
|
||||
<source>Account locked permanently.</source>
|
||||
<translation>ᠳᠠᠩᠰᠠ ᠨᠢᠭᠡᠨᠳᠡ ᠦᠨᠢᠳᠡ ᠤᠨᠢᠰᠤᠯᠠᠭᠳᠠᠪᠠ.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="834"/>
|
||||
<location filename="../src/mainwindow.cpp" line="835"/>
|
||||
<source>Password cannot be empty</source>
|
||||
<translation>ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠬᠤᠭᠤᠰᠤᠨ ᠪᠠᠢᠵᠤ ᠪᠤᠯᠬᠤ ᠦᠬᠡᠢ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Failed to verify %1, please enter password.</source>
|
||||
<translation type="vanished">验证%1失败,请输入密码.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to verify %1, please enter password.</source>
|
||||
<translation type="vanished">无法验证%1,请输入密码.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="242"/>
|
||||
<location filename="../src/mainwindow.cpp" line="246"/>
|
||||
<source>Failed to verify %1, you still have %2 verification opportunities</source>
|
||||
<translation>%1ᠶᠢᠨ/ᠦᠨ ᠰᠢᠯᠭᠠᠨ ᠪᠠᠢᠴᠠᠭᠠᠯᠳᠠ ᠢᠯᠠᠭᠳᠠᠪᠠ ᠂ ᠲᠠ ᠪᠠᠰᠠ%2 ᠤᠳᠠᠭᠠᠨᠤ ᠳᠤᠷᠱᠢᠬᠤ ᠵᠠᠪᠱᠢᠶᠠᠨ ᠲᠠᠢ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>An application is attempting to perform an action that requires privileges. Authentication is required to perform this action.</source>
|
||||
<translation type="vanished">一个程序正试图执行一个需要特权的动作。要求授权以执行该动作。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="731"/>
|
||||
<source>Password: </source>
|
||||
<translation>ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋᠄ </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="335"/>
|
||||
<source>Please enter your password or enroll your fingerprint </source>
|
||||
<translation>ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠪᠤᠶᠤ ᠬᠤᠷᠤᠭᠤᠨ ᠤ᠋ ᠤᠷᠤᠮ ᠵᠢᠨᠨ ᠤᠷᠤᠭᠤᠯᠤᠭᠠᠷᠠᠢ </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="259"/>
|
||||
<source>Abnormal network</source>
|
||||
<translation>ᠲᠤᠷ ᠰᠦᠯᠵᠢᠶᠡ ᠬᠡᠪ ᠤ᠋ᠨ ᠪᠤᠰᠤ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="665"/>
|
||||
<source>This operation requires the administrator's authorization. Please enter your password to allow this operation.</source>
|
||||
<translation>ᠳᠤᠰ ᠤᠳᠠᠭᠠᠨ ᠤ᠋ ᠠᠵᠢᠯᠯᠠᠬᠤᠢ ᠵᠢᠨ ᠬᠠᠮᠢᠶᠠᠷᠤᠭᠴᠢ ᠵᠢᠨ ᠡᠷᠬᠡ ᠤᠯᠭᠤᠯᠳᠠ ᠪᠡᠷ ᠰᠠᠶᠢ ᠦᠷᠬᠦᠯᠵᠢᠯᠡᠨ ᠬᠡᠷᠡᠭᠵᠢᠬᠦᠯᠦᠨᠡ᠂ ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠵᠢᠨᠨ ᠤᠷᠤᠭᠤᠯᠵᠤ ᠳᠤᠰ ᠠᠵᠢᠯᠯᠠᠬᠤᠢ ᠵᠢ ᠵᠦᠪᠰᠢᠶᠡᠷᠡᠭᠡᠷᠡᠢ.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="733"/>
|
||||
<source>_Password: </source>
|
||||
<translation>ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="735"/>
|
||||
<source>_Password:</source>
|
||||
<translation>ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="850"/>
|
||||
<source>Authentication failed, please try again.</source>
|
||||
<translation>ᠰᠢᠯᠭᠠᠨ ᠪᠠᠳᠤᠯᠠᠵᠤ ᠴᠢᠳᠠᠭᠰᠠᠨ ᠦᠬᠡᠢ᠂ ᠳᠠᠬᠢᠵᠤ ᠳᠤᠷᠰᠢᠭᠠᠷᠠᠢ.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="779"/>
|
||||
<source>days left</source>
|
||||
<translation>ᠡᠳᠦᠷ ᠤ᠋ᠨ ᠳᠠᠷᠠᠭᠠ ᠤᠨᠢᠰᠤ ᠳᠠᠢᠯᠤᠨᠠ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Biometric/code scan authentication failed too many times, please enter the password.</source>
|
||||
<translation type="vanished">生物/扫码验证失败达最大次数,请使用密码解锁.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bioauth/code scan authentication failed, you still have %1 verification opportunities</source>
|
||||
<translation type="vanished">生物/扫码验证失败,您还有%1次尝试机会</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="226"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1421"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1423"/>
|
||||
<source>Failed to verify %1, please enter password to unlock</source>
|
||||
<translation>%1ᠶᠢ/ᠢ ᠪᠠᠳᠤᠯᠭᠠᠵᠢᠭᠤᠯᠬᠤ ᠠᠷᠭᠠ ᠦᠬᠡᠢ ᠂ ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠤᠷᠤᠭᠤᠯᠵᠤ ᠤᠨᠢᠰᠤᠶᠢ ᠳᠠᠢᠯᠤᠭᠠᠷᠠᠢ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="231"/>
|
||||
<location filename="../src/mainwindow.cpp" line="233"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1425"/>
|
||||
<source>Unable to verify %1, please enter password to unlock</source>
|
||||
<translation>%1ᠶᠢ/ᠢ ᠪᠠᠳᠤᠯᠭᠠᠵᠢᠭᠤᠯᠬᠤ ᠠᠷᠭᠠ ᠦᠬᠡᠢ ᠂ ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠤᠷᠤᠭᠤᠯᠵᠤ ᠤᠨᠢᠰᠤᠶᠢ ᠳᠠᠢᠯᠤᠭᠠᠷᠠᠢ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>NET Exception</source>
|
||||
<translation type="vanished">网络异常</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="671"/>
|
||||
<source>A program is attempting to perform an action that requires privileges.It requires authorization to perform the action.</source>
|
||||
<translation>ᠨᠢᠭᠡ ᠫᠡᠷᠦᠭᠷᠡᠮ ᠶᠠᠭ ᠨᠢᠭᠡ ᠤᠨᠠᠴᠠ ᠡᠷᠬᠡ ᠬᠡᠷᠡᠭᠰᠡᠬᠦ ᠬᠦᠳᠡᠯᠬᠡᠬᠡᠨ ᠢ᠋ ᠬᠡᠷᠡᠭᠵᠢᠬᠦᠯᠬᠦ ᠪᠡᠷ ᠳᠤᠷᠰᠢᠵᠤ ᠪᠠᠢᠨᠠ᠂ ᠳᠤᠰ ᠬᠦᠳᠡᠯᠬᠡᠬᠡᠨ ᠢ᠋ ᠬᠦᠢᠴᠡᠳᠬᠡᠬᠦ ᠡᠷᠬᠡ ᠤᠯᠭᠤᠬᠤ ᠵᠢ ᠱᠠᠭᠠᠷᠳᠠᠵᠤ ᠪᠠᠢᠨᠠ.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="108"/>
|
||||
<location filename="../src/mainwindow.cpp" line="729"/>
|
||||
<source>Input Password</source>
|
||||
<translation>ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠤᠷᠤᠭᠤᠯᠬᠤ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="105"/>
|
||||
<source>Insert the ukey into the USB port</source>
|
||||
<translation>ᠠᠮᠤᠷ ᠲᠦᠪᠰᠢᠨ ᠦ ᠨᠢᠭᠤᠴᠠ ᠶᠢ USB ᠦᠵᠦᠭᠦᠷ ᠲᠦ ᠬᠠᠳᠬᠤᠵᠤ ᠣᠷᠣᠭᠠᠷᠠᠢ ᠃</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="107"/>
|
||||
<source>Enter the ukey password</source>
|
||||
<translation>ᠠᠮᠤᠷ ᠲᠦᠪᠰᠢᠨ ᠨᠢᠭᠤᠴᠠ ᠨᠣᠮᠧᠷ ᠢ ᠣᠷᠣᠭᠤᠯᠤᠨᠠ ᠃</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="783"/>
|
||||
<source>hours left</source>
|
||||
<translation>ᠨᠢᠭᠡ ᠴᠠᠭ ᠤ᠋ᠨ ᠳᠠᠷᠠᠭᠠ ᠤᠨᠢᠰᠤ ᠳᠠᠢᠯᠤᠨᠠ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="787"/>
|
||||
<source>minutes left</source>
|
||||
<translation>ᠮᠢᠨᠦ᠋ᠲ ᠤ᠋ᠨ ᠳᠠᠷᠠᠭᠠ ᠤᠨᠢᠰᠤ ᠳᠠᠢᠯᠤᠨᠠ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="791"/>
|
||||
<source>seconds left</source>
|
||||
<translation>ᠰᠸᠺᠦᠨ᠋ᠲ ᠤ᠋ᠨ ᠳᠠᠷᠠᠭᠠ ᠤᠨᠢᠰᠤ ᠳᠠᠢᠯᠤᠨᠠ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="880"/>
|
||||
<location filename="../src/mainwindow.cpp" line="888"/>
|
||||
<source>Input your password to authentication</source>
|
||||
<translation>ᠨᠢᠭᠤᠴᠠ ᠨᠣᠮᠧᠷ ᠣᠷᠣᠭᠤᠯᠬᠤ ᠳᠤ ᠡᠷᠬᠡ ᠣᠯᠭᠣᠨᠠ ᠃</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="1440"/>
|
||||
<source>Verify face recognition or enter password to unlock</source>
|
||||
<translation>ᠨᠢᠭᠤᠷ ᠱᠢᠷᠪᠢᠵᠤ ᠪᠠᠳᠤᠯᠭᠠᠵᠢᠭᠤᠯᠬᠤ ᠪᠤᠶᠤ ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠤᠷᠤᠭᠤᠯᠵᠤ ᠤᠨᠢᠰᠤᠶᠢ ᠳᠠᠢᠯᠤᠭᠠᠷᠠᠢ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="1445"/>
|
||||
<source>Press fingerprint or enter password to unlock</source>
|
||||
<translation>ᠬᠤᠷᠤᠭᠤᠨᠤ ᠤᠷᠤᠮ ᠳᠠᠷᠤᠬᠤ ᠪᠤᠶᠤ ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠤᠷᠤᠭᠤᠯᠵᠤ ᠤᠨᠢᠰᠤᠶᠢ ᠳᠠᠢᠯᠤᠭᠠᠷᠠᠢ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="1450"/>
|
||||
<source>Verify voiceprint or enter password to unlock</source>
|
||||
<translation>ᠳᠠᠭᠤᠪᠠᠷ ᠰᠢᠯᠭᠠᠨ ᠪᠠᠳᠤᠯᠠᠬᠤ ᠪᠤᠶᠤ ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠤᠷᠤᠭᠤᠯᠵᠤ ᠤᠨᠢᠰᠤᠶᠢ ᠳᠠᠢᠯᠤᠭᠠᠷᠠᠢ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="1455"/>
|
||||
<source>Verify finger vein or enter password to unlock</source>
|
||||
<translation>ᠬᠤᠷᠤᠭᠤᠨᠤ ᠨᠠᠮᠵᠢᠭᠤᠨ ᠰᠤᠳᠠᠯᠢᠶᠠᠷ ᠰᠢᠯᠭᠠᠨ ᠪᠠᠳᠤᠯᠠᠬᠤ ᠪᠤᠶᠤ ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠤᠷᠤᠭᠤᠯᠵᠤ ᠤᠨᠢᠰᠤᠶᠢ ᠳᠠᠢᠯᠤᠭᠠᠷᠠᠢ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="1460"/>
|
||||
<source>Verify iris or enter password to unlock</source>
|
||||
<translation>ᠰᠤᠯᠤᠩᠭᠠ ᠪᠦᠷᠬᠦᠪᠴᠢᠶᠢ ᠰᠢᠯᠭᠠᠨ ᠪᠠᠳᠤᠯᠠᠬᠤ ᠪᠤᠶᠤ ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠤᠷᠤᠭᠤᠯᠵᠤ ᠤᠨᠢᠰᠤᠶᠢ ᠳᠠᠢᠯᠤᠭᠠᠷᠠᠢ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="1465"/>
|
||||
<source>Use the bound wechat scanning code or enter the password to unlock</source>
|
||||
<translation>ᠤᠶᠠᠭᠰᠠᠨ ᠸᠢᠴᠠᠲᠢᠶᠠᠷ ᠺᠤᠳ᠋ ᠱᠢᠷᠪᠢᠬᠦ᠌ ᠪᠤᠶᠤ ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠤᠷᠤᠭᠤᠯᠵᠤ ᠤᠨᠢᠰᠤᠶᠢ ᠳᠠᠢᠯᠤᠭᠠᠷᠠᠢ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use the bound wechat scanning code or enter the password to log in</source>
|
||||
<translation type="vanished">使用绑定的微信扫码或输入密码登录</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="779"/>
|
||||
<location filename="../src/mainwindow.cpp" line="783"/>
|
||||
<location filename="../src/mainwindow.cpp" line="787"/>
|
||||
<location filename="../src/mainwindow.cpp" line="791"/>
|
||||
<source>Account locked,</source>
|
||||
<translation>ᠳᠠᠨᠭᠰᠠ ᠵᠢ ᠨᠢᠬᠡᠨᠳᠡ ᠤᠨᠢᠰᠤᠯᠠᠪᠠ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Authentication failed, please try again</source>
|
||||
<translation type="obsolete">认证失败,请重试</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PolkitListener</name>
|
||||
<message>
|
||||
<location filename="../src/PolkitListener.cpp" line="88"/>
|
||||
<source>Another client is already authenticating, please try again later.</source>
|
||||
<translation>ᠦᠬᠡᠷᠡ ᠨᠢᠭᠡ ᠬᠡᠷᠡᠭᠯᠡᠭᠴᠢ ᠵᠢᠨ ᠦᠵᠦᠬᠦᠷᠯᠢᠭ ᠢ᠋ ᠶᠠᠭ ᠨᠤᠳᠠᠯᠠᠵᠤ ᠪᠠᠢᠨᠠ᠂ ᠤᠳᠠᠰᠬᠢᠭᠠᠳ ᠳᠠᠬᠢᠨ ᠳᠤᠷᠰᠢᠭᠠᠷᠠᠢ.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/PolkitListener.cpp" line="261"/>
|
||||
<source>Authentication failure, please try again.</source>
|
||||
<translation>ᠰᠢᠯᠭᠠᠨ ᠪᠠᠳᠤᠯᠠᠵᠤ ᠴᠢᠳᠠᠭᠰᠠᠨ ᠦᠬᠡᠢ᠂ ᠳᠠᠬᠢᠵᠤ ᠳᠤᠷᠰᠢᠭᠠᠷᠠᠢ.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/PolkitListener.cpp" line="268"/>
|
||||
<source>Password input error!</source>
|
||||
<translation>ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠢ᠋ ᠪᠤᠷᠤᠭᠤ ᠤᠷᠤᠭᠤᠯᠪᠠ!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Account locked %1 minutes due to %2 fail attempts</source>
|
||||
<translation type="vanished">账户锁定%1分钟由于%2次错误尝试</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Authentication failure,there are still %1 remaining opportunities</source>
|
||||
<translation type="vanished">认证失败,还剩余%1次尝试机会</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QObject</name>
|
||||
<message>
|
||||
<source>FingerPrint</source>
|
||||
<translation type="obsolete">指纹</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FingerVein</source>
|
||||
<translation type="obsolete">指静脉</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Iris</source>
|
||||
<translation type="obsolete">虹膜</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Face</source>
|
||||
<translation type="obsolete">人脸</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>VoicePrint</source>
|
||||
<translation type="obsolete">声纹</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cancel</source>
|
||||
<translation type="obsolete">取消</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
|
@ -0,0 +1,441 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="zh_Hant">
|
||||
<context>
|
||||
<name>BioAuthWidget</name>
|
||||
<message>
|
||||
<source>Retry</source>
|
||||
<translation type="obsolete">重试</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%1 too many unsuccessful attempts,please enter password.</source>
|
||||
<translation type="obsolete">%1验证失败达最大次数,请使用密码登录</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%1 authentication failure,there are still %2 remaining opportunities</source>
|
||||
<translation type="obsolete">%1认证失败,还剩%2次尝试机会</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Please use wechat to scan the code</source>
|
||||
<translation type="vanished">请使用微信扫码</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>BioDevices</name>
|
||||
<message>
|
||||
<source>FingerPrint</source>
|
||||
<translation type="obsolete">指纹</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FingerVein</source>
|
||||
<translation type="obsolete">指静脉</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Iris</source>
|
||||
<translation type="obsolete">虹膜</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Face</source>
|
||||
<translation type="obsolete">人脸</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>VoicePrint</source>
|
||||
<translation type="obsolete">声纹</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Wechat</source>
|
||||
<translation type="vanished">微信</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>QRCode</source>
|
||||
<translation type="vanished">二维码</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LoginOptionsWidget</name>
|
||||
<message>
|
||||
<source>Login Options</source>
|
||||
<translation type="vanished">登录选项</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Wechat</source>
|
||||
<translation type="vanished">微信</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="67"/>
|
||||
<source>Authentication</source>
|
||||
<translation>授權</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Fingerprint authentication failed, you still have %1 verification opportunities</source>
|
||||
<translation type="vanished">指纹验证失败,您还有%1次尝试机会</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.ui" line="26"/>
|
||||
<source>Form</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>More</source>
|
||||
<translation type="obsolete">更多</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Restart</source>
|
||||
<translation type="obsolete">重新开始</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Password</source>
|
||||
<translation type="vanished">密码</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.ui" line="409"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1077"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1145"/>
|
||||
<source>Biometric</source>
|
||||
<translation>使用生物識別</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.ui" line="480"/>
|
||||
<source>use password</source>
|
||||
<translation>使用密碼驗證</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DeviceType:</source>
|
||||
<translation type="obsolete">设备类型:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Back</source>
|
||||
<translation type="obsolete">返回</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Details</source>
|
||||
<translation type="vanished">详细</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Action Id:</source>
|
||||
<translation type="obsolete">动作:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Description:</source>
|
||||
<translation type="vanished">描述:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Polkit.subject-pid:</source>
|
||||
<translation type="vanished">Polkit.subject-pid:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Retry</source>
|
||||
<translation type="obsolete">重试</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Device types:</source>
|
||||
<translation type="obsolete">设备类型:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Vendor:</source>
|
||||
<translation type="vanished">发行商:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Action:</source>
|
||||
<translation type="vanished">动作:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Polkit.caller-pid:</source>
|
||||
<translation type="vanished">Polkit.caller-pid:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.ui" line="441"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1079"/>
|
||||
<source>Cancel</source>
|
||||
<translation>取消</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.ui" line="460"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1075"/>
|
||||
<source>Authenticate</source>
|
||||
<translation>授權</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="1081"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1185"/>
|
||||
<source>Use password</source>
|
||||
<translation>使用密碼驗證</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Auth</source>
|
||||
<translation type="obsolete">授权</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Too many unsuccessful attempts,please enter password.</source>
|
||||
<translation type="vanished">指纹验证失败达最大次数,请使用密码解锁</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%1 authentication failure,there are still %2 remaining opportunities</source>
|
||||
<translation type="vanished">%1认证失败,还剩%2次尝试机会</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%1 too many unsuccessful attempts,please enter password.</source>
|
||||
<translation type="vanished">%1验证失败达最大次数,请使用密码登录</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>in authentication, please wait...</source>
|
||||
<translation type="vanished">认证中,请稍等...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="1221"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1294"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1295"/>
|
||||
<source>Please try again in %1 minutes.</source>
|
||||
<translation>請%1分鐘后再試</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="1232"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1304"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1305"/>
|
||||
<source>Please try again in %1 seconds.</source>
|
||||
<translation>請%1秒後再試</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="1242"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1243"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1313"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1314"/>
|
||||
<source>Account locked permanently.</source>
|
||||
<translation>帳號已被永久鎖定</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="836"/>
|
||||
<location filename="../src/mainwindow.cpp" line="837"/>
|
||||
<source>Password cannot be empty</source>
|
||||
<translation>密碼不能為空</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Failed to verify %1, please enter password.</source>
|
||||
<translation type="vanished">验证%1失败,请输入密码.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to verify %1, please enter password.</source>
|
||||
<translation type="vanished">无法验证%1,请输入密码.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="244"/>
|
||||
<location filename="../src/mainwindow.cpp" line="248"/>
|
||||
<source>Failed to verify %1, you still have %2 verification opportunities</source>
|
||||
<translation>驗證%1失敗,您還有%2次嘗試機會</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>An application is attempting to perform an action that requires privileges. Authentication is required to perform this action.</source>
|
||||
<translation type="vanished">一个程序正试图执行一个需要特权的动作。要求授权以执行该动作。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="733"/>
|
||||
<source>Password: </source>
|
||||
<translation>密碼: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="337"/>
|
||||
<source>Please enter your password or enroll your fingerprint </source>
|
||||
<translation>請輸入密碼或者錄入指紋 </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="261"/>
|
||||
<source>Abnormal network</source>
|
||||
<translation>網路異常</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="667"/>
|
||||
<source>This operation requires the administrator's authorization. Please enter your password to allow this operation.</source>
|
||||
<translation>本次操作需要通過管理員的授權才能繼續執行,請輸入密碼以允許本次操作。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="735"/>
|
||||
<source>_Password: </source>
|
||||
<translation>密碼: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="737"/>
|
||||
<source>_Password:</source>
|
||||
<translation>密碼:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="852"/>
|
||||
<source>Authentication failed, please try again.</source>
|
||||
<translation>認證失敗,請重試。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="781"/>
|
||||
<source>days left</source>
|
||||
<translation>天后解鎖</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Biometric/code scan authentication failed too many times, please enter the password.</source>
|
||||
<translation type="vanished">生物/扫码验证失败达最大次数,请使用密码解锁.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bioauth/code scan authentication failed, you still have %1 verification opportunities</source>
|
||||
<translation type="vanished">生物/扫码验证失败,您还有%1次尝试机会</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="228"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1417"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1419"/>
|
||||
<source>Failed to verify %1, please enter password to unlock</source>
|
||||
<translation>驗證%1失敗,請輸入密碼解鎖</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="233"/>
|
||||
<location filename="../src/mainwindow.cpp" line="235"/>
|
||||
<location filename="../src/mainwindow.cpp" line="1421"/>
|
||||
<source>Unable to verify %1, please enter password to unlock</source>
|
||||
<translation>無法驗證%1,請輸入密碼解鎖</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>NET Exception</source>
|
||||
<translation type="vanished">网络异常</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="673"/>
|
||||
<source>A program is attempting to perform an action that requires privileges.It requires authorization to perform the action.</source>
|
||||
<translation>一個程式正試圖執行一個需要特權的動作,要求授權以執行該動作。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="110"/>
|
||||
<location filename="../src/mainwindow.cpp" line="731"/>
|
||||
<source>Input Password</source>
|
||||
<translation>輸入密碼</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="107"/>
|
||||
<source>Insert the ukey into the USB port</source>
|
||||
<translation>請將安全金鑰插入USB埠</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="109"/>
|
||||
<source>Enter the ukey password</source>
|
||||
<translation>輸入安全金鑰密碼</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="785"/>
|
||||
<source>hours left</source>
|
||||
<translation>小時後解鎖</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="789"/>
|
||||
<source>minutes left</source>
|
||||
<translation>分鐘後解鎖</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="793"/>
|
||||
<source>seconds left</source>
|
||||
<translation>秒後解鎖</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="882"/>
|
||||
<location filename="../src/mainwindow.cpp" line="890"/>
|
||||
<source>Input your password to authentication</source>
|
||||
<translation>輸入密碼以認證</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="1436"/>
|
||||
<source>Verify face recognition or enter password to unlock</source>
|
||||
<translation>驗證人臉識別或輸入密碼解鎖</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="1441"/>
|
||||
<source>Press fingerprint or enter password to unlock</source>
|
||||
<translation>按壓指紋或輸入密碼解鎖</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="1446"/>
|
||||
<source>Verify voiceprint or enter password to unlock</source>
|
||||
<translation>驗證聲紋或輸入密碼解鎖</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="1451"/>
|
||||
<source>Verify finger vein or enter password to unlock</source>
|
||||
<translation>驗證指靜脈或輸入密碼解鎖</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="1456"/>
|
||||
<source>Verify iris or enter password to unlock</source>
|
||||
<translation>驗證虹膜或輸入密碼解鎖</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="1461"/>
|
||||
<source>Use the bound wechat scanning code or enter the password to unlock</source>
|
||||
<translation>使用綁定的微信掃碼或輸入密碼解鎖</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use the bound wechat scanning code or enter the password to log in</source>
|
||||
<translation type="vanished">使用绑定的微信扫码或输入密码登录</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.cpp" line="781"/>
|
||||
<location filename="../src/mainwindow.cpp" line="785"/>
|
||||
<location filename="../src/mainwindow.cpp" line="789"/>
|
||||
<location filename="../src/mainwindow.cpp" line="793"/>
|
||||
<source>Account locked,</source>
|
||||
<translation>帳戶已鎖定,</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Authentication failed, please try again</source>
|
||||
<translation type="obsolete">认证失败,请重试</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PolkitListener</name>
|
||||
<message>
|
||||
<location filename="../src/PolkitListener.cpp" line="90"/>
|
||||
<source>Another client is already authenticating, please try again later.</source>
|
||||
<translation>有另外一個用戶端正在認證,請稍後重試。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/PolkitListener.cpp" line="265"/>
|
||||
<source>Authentication failure, please try again.</source>
|
||||
<translation>認證失敗,請重試。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/PolkitListener.cpp" line="272"/>
|
||||
<source>Password input error!</source>
|
||||
<translation>密碼輸入錯誤!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Account locked %1 minutes due to %2 fail attempts</source>
|
||||
<translation type="vanished">账户锁定%1分钟由于%2次错误尝试</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Authentication failure,there are still %1 remaining opportunities</source>
|
||||
<translation type="vanished">认证失败,还剩余%1次尝试机会</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QObject</name>
|
||||
<message>
|
||||
<source>FingerPrint</source>
|
||||
<translation type="obsolete">指纹</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FingerVein</source>
|
||||
<translation type="obsolete">指静脉</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Iris</source>
|
||||
<translation type="obsolete">虹膜</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Face</source>
|
||||
<translation type="obsolete">人脸</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>VoicePrint</source>
|
||||
<translation type="obsolete">声纹</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cancel</source>
|
||||
<translation type="obsolete">取消</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
|
@ -357,6 +357,7 @@ void PolkitListener::onShowPrompt(const QString &prompt, bool echo)
|
|||
mainWindow->setPrompt(prompt, echo);
|
||||
}
|
||||
|
||||
mainWindow->setFixedSize(mainWindow->width(),mainWindow->height());
|
||||
mainWindow->show();
|
||||
// 重新开始认证不调整窗口位置
|
||||
// QPoint pos = QCursor::pos();
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <QFontMetrics>
|
||||
#include <QtMath>
|
||||
#include <QAbstractItemView>
|
||||
#include <KWindowSystem>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -61,6 +62,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
m_nCurLockMin(0),
|
||||
isbioSuccess(false)
|
||||
{
|
||||
KWindowSystem::setState(this->winId(), NET::SkipTaskbar | NET::SkipPager);
|
||||
ui->setupUi(this);
|
||||
setWindowTitle(tr("Authentication"));
|
||||
setWindowFlags(Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint);
|
||||
|
@ -97,6 +99,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
ui->titleTipLayout->addWidget(m_labelTip);
|
||||
ui->loginOptionsLayout->setAlignment(Qt::AlignTop|Qt::AlignCenter);
|
||||
ui->loginOptionsLayout->addWidget(m_loginOptsWidget);
|
||||
ui->loadingUkeyWidget->adjustSize();
|
||||
ui->loadingUkeyWidget->hide();
|
||||
ui->widgetUkeyAuth->hide();
|
||||
ui->loadingUkeyBtn->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||||
|
@ -105,14 +108,12 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
ui->loadingUkeyLbl->setAlignment(Qt::AlignTop|Qt::AlignHCenter);
|
||||
ui->ukeyTipLbl->setText(tr("Enter the ukey password"));
|
||||
ui->ukeyPassword->setPlaceholderText(tr("Input Password"));
|
||||
ui->loadingUkeyWidget->adjustSize();
|
||||
maxFailedTimes = bioDevices.getFailedTimes();
|
||||
isHiddenSwitchButton = bioDevices.GetHiddenSwitchButton();
|
||||
|
||||
connect(m_loginOptsWidget, &LoginOptionsWidget::optionSelected,
|
||||
this, [&](unsigned uCurLoginOptType, const DeviceInfoPtr &deviceInfo){
|
||||
|
||||
isLoadingUkey = false;
|
||||
isLoadingUkey = false;
|
||||
|
||||
if(uCurLoginOptType == LOGINOPT_TYPE_GENERAL_UKEY){
|
||||
stopLoadingUkey();
|
||||
|
@ -142,7 +143,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
|
||||
if (uCurLoginOptType == LOGINOPT_TYPE_GENERAL_UKEY && !deviceInfo){
|
||||
isLoadingUkey = true;
|
||||
startLoadingUkey();
|
||||
startLoadingUkey();
|
||||
m_loginOptsWidget->updateUkeyUIStatus(LOGINOPT_TYPE_GENERAL_UKEY);
|
||||
}else if(uCurLoginOptType == LOGINOPT_TYPE_GENERAL_UKEY && deviceInfo){
|
||||
stopLoadingUkey();
|
||||
|
@ -157,8 +158,8 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
return ;
|
||||
}
|
||||
|
||||
if(m_bioTimer)
|
||||
m_bioTimer->stop();
|
||||
if(m_bioTimer)
|
||||
m_bioTimer->stop();
|
||||
|
||||
m_deviceInfo = deviceInfo;
|
||||
switchLoginOptType(uCurLoginOptType);
|
||||
|
@ -365,24 +366,27 @@ void MainWindow::setUkeyTypeTip(QString text)
|
|||
|
||||
void MainWindow::startLoadingUkey()
|
||||
{
|
||||
m_loadingPixmap = QIcon::fromTheme("ukui-loading-0-symbolic").pixmap(27,27);
|
||||
ui->loadingUkeyBtn->setIcon(m_loadingPixmap);
|
||||
ui->loadingUkeyBtn->setIconSize(QSize(27, 27));
|
||||
|
||||
ui->loadingUkeyWidget->adjustSize();
|
||||
ui->cmbUsers->hide();
|
||||
ui->widgetUkeyAuth->hide();
|
||||
ui->lePassword->hide();
|
||||
|
||||
ui->widgetPasswdAuth->hide();
|
||||
|
||||
isLoadingUkey = true;
|
||||
ui->loadingUkeyWidget->show();
|
||||
|
||||
if(!m_loadingTimer)
|
||||
{
|
||||
m_loadingTimer = new QTimer(this);
|
||||
m_loadingTimer->setInterval(150);
|
||||
connect(m_loadingTimer, &QTimer::timeout, this, &MainWindow::updateLoadingPixmap);
|
||||
}
|
||||
|
||||
m_loadingPixmap = QIcon::fromTheme("ukui-loading-0-symbolic").pixmap(27,27);
|
||||
ui->loadingUkeyBtn->setIcon(m_loadingPixmap);
|
||||
ui->loadingUkeyBtn->setIconSize(QSize(27, 27));
|
||||
m_loadingTimer->start();
|
||||
ui->loadingUkeyWidget->adjustSize();
|
||||
ui->cmbUsers->hide();
|
||||
ui->widgetUkeyAuth->hide();
|
||||
ui->lePassword->hide();
|
||||
ui->widgetPasswdAuth->hide();
|
||||
}
|
||||
|
||||
void MainWindow::stopLoadingUkey()
|
||||
|
@ -391,9 +395,10 @@ void MainWindow::stopLoadingUkey()
|
|||
if(m_loadingTimer){
|
||||
m_loadingTimer->stop();
|
||||
}
|
||||
|
||||
ui->loadingUkeyWidget->hide();
|
||||
//ui->cmbUsers->show();
|
||||
ui->widgetUkeyAuth->show();
|
||||
//ui->widgetUkeyAuth->show();
|
||||
}
|
||||
|
||||
void MainWindow::updateLoadingPixmap()
|
||||
|
@ -874,6 +879,7 @@ void MainWindow::switchAuthMode(Mode mode)
|
|||
int count = m_loginOptsWidget->getLoginOptCount();
|
||||
enableBioAuth = count > 0;
|
||||
if (count < 1) {
|
||||
setLoginTypeTip(tr("Input your password to authentication"));
|
||||
m_loginOptsWidget->hide();
|
||||
} else {
|
||||
m_loginOptsWidget->show();
|
||||
|
@ -881,6 +887,7 @@ void MainWindow::switchAuthMode(Mode mode)
|
|||
}
|
||||
|
||||
if(m_loginOptsWidget->getHasUkeyOptions()){
|
||||
setLoginTypeTip(tr("Input your password to authentication"));
|
||||
m_loginOptsWidget->show();
|
||||
}
|
||||
|
||||
|
@ -1074,6 +1081,7 @@ void MainWindow::switchWidget(Mode mode)
|
|||
ui->returnButton->setText(tr("Use password"));
|
||||
ui->btnLoading->setDisabled(true);
|
||||
ui->returnButton->adjustSize();
|
||||
m_labelTip->adjustSize();
|
||||
if(is_Mavis){
|
||||
ui->cmbUsers->setFixedHeight(48);
|
||||
ui->lePassword->setFixedHeight(48);
|
||||
|
@ -1084,8 +1092,7 @@ void MainWindow::switchWidget(Mode mode)
|
|||
switch(mode){
|
||||
case PASSWORD:
|
||||
{
|
||||
setMinimumWidth(420);
|
||||
setMaximumWidth(420);
|
||||
setFixedWidth(420);
|
||||
|
||||
if (m_deviceInfo && m_loginOptsWidget->findDeviceById(m_deviceInfo->device_id)) {
|
||||
switchLoginOptType(m_loginOptsWidget->convertDeviceType(m_deviceInfo->biotype));
|
||||
|
@ -1121,18 +1128,16 @@ void MainWindow::switchWidget(Mode mode)
|
|||
+ ui->cmbUsers->height() + ui->lePassword->height() + ui->lblMessage->height()
|
||||
+ ui->btnAuth->height();
|
||||
}
|
||||
if (m_loginOptsWidget->isHidden()) {
|
||||
height -= 20 ;
|
||||
}
|
||||
// if (m_loginOptsWidget->isHidden()) {
|
||||
// height = height - m_labelTip->height() - 10;
|
||||
// }
|
||||
|
||||
unsigned uOptsWidgetHeight = m_loginOptsWidget->height();
|
||||
if (m_loginOptsWidget->isHidden()) {
|
||||
uOptsWidgetHeight = 0;
|
||||
height -= 20 ;
|
||||
height = height + m_labelTip->height() - 10;
|
||||
}
|
||||
setMinimumHeight(height + uOptsWidgetHeight + 10);
|
||||
setMaximumHeight(height + uOptsWidgetHeight + 10);
|
||||
|
||||
setFixedHeight(height + uOptsWidgetHeight + 10);
|
||||
|
||||
//m_loginOptsWidget->updateUIStatus();
|
||||
ui->btnBioAuth->setStyleSheet("QPushButton{font-size:14px;}QPushButton:hover{border:none;color:#3E6CE5;}QPushButton:pressed{border:none;}");
|
||||
|
@ -1163,14 +1168,11 @@ void MainWindow::switchWidget(Mode mode)
|
|||
break;
|
||||
|
||||
case BIOMETRIC:
|
||||
setMinimumWidth(420);
|
||||
setMaximumWidth(420);
|
||||
setFixedWidth(420);
|
||||
if(m_loginOptsWidget->getLoginOptCount() <= 1){
|
||||
setMinimumHeight(392+ui->cmbUsers->height()+ui->lblHeader->height());
|
||||
setMaximumHeight(392+ui->cmbUsers->height()+ui->lblHeader->height());
|
||||
setFixedHeight(392+ui->cmbUsers->height()+ui->lblHeader->height());
|
||||
} else {
|
||||
setMinimumHeight(482+ui->cmbUsers->height()+ui->lblHeader->height());
|
||||
setMaximumHeight(482+ui->cmbUsers->height()+ui->lblHeader->height());
|
||||
setFixedHeight(482+ui->cmbUsers->height()+ui->lblHeader->height());
|
||||
}
|
||||
|
||||
ui->btnCancel->hide();
|
||||
|
@ -1484,11 +1486,15 @@ void MainWindow::setLoginTypeTip(QString strLoginTypeTip)
|
|||
m_labelTip->hide();
|
||||
} else {
|
||||
QPalette pe;
|
||||
if(no_changes)
|
||||
if(no_changes) {
|
||||
pe.setColor(QPalette::WindowText,Qt::red);
|
||||
else
|
||||
pe.setColor(QPalette::WindowText,QColor(55, 144, 250, 255));
|
||||
m_labelTip->setPalette(pe);
|
||||
m_labelTip->setPalette(pe);
|
||||
} else {
|
||||
QColor color = palette().color(QPalette::WindowText);
|
||||
QPalette pal(this->palette());
|
||||
pal.setColor(QPalette::WindowText,QColor(color));
|
||||
m_labelTip->setPalette(pal);
|
||||
}
|
||||
m_labelTip->setText(m_strLoginTypeTip);
|
||||
m_labelTip->show();
|
||||
}
|
||||
|
@ -1499,7 +1505,7 @@ void MainWindow::startBioAuthDelay()
|
|||
if (m_deviceInfo) {
|
||||
if(m_deviceInfo->biotype == LOGINOPT_TYPE_GENERAL_UKEY){
|
||||
|
||||
}else{
|
||||
}else{
|
||||
m_loginOptsWidget->startAuth(m_deviceInfo, getUid(userName));
|
||||
}
|
||||
switchLoginOptType(m_loginOptsWidget->convertDeviceType(m_deviceInfo->biotype));
|
||||
|
@ -1589,17 +1595,14 @@ void MainWindow::onUpdateWndSize(unsigned uLoginOptType, unsigned uLoginOptSize)
|
|||
+ ui->btnAuth->height();
|
||||
}
|
||||
if (m_loginOptsWidget->isHidden()) {
|
||||
height -= 20 ;
|
||||
height = height + m_labelTip->height() - 10;
|
||||
}
|
||||
|
||||
if(uLoginOptType == LOGINOPT_TYPE_GENERAL_UKEY){
|
||||
|
||||
setMinimumHeight(height + uOptsWidgetHeight + 10);
|
||||
setMaximumHeight(height + uOptsWidgetHeight + 10);
|
||||
setLoginTypeTip("");
|
||||
setFixedSize(width(), height + uOptsWidgetHeight + 10);
|
||||
}else{
|
||||
|
||||
setMinimumHeight(height + uOptsWidgetHeight);
|
||||
setMaximumHeight(height + uOptsWidgetHeight);
|
||||
setFixedSize(width(), height + uOptsWidgetHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>459</width>
|
||||
<height>547</height>
|
||||
<height>646</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
|
@ -120,6 +120,9 @@
|
|||
</item>
|
||||
<item row="4" column="1">
|
||||
<layout class="QHBoxLayout" name="titleTipLayout">
|
||||
<property name="topMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
|
@ -380,19 +383,6 @@
|
|||
</property>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<property name="spacing">
|
||||
|
@ -410,7 +400,7 @@
|
|||
<item>
|
||||
<widget class="QPushButton" name="btnBioAuth">
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
<cursorShape>ArrowCursor</cursorShape>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
|
@ -442,7 +432,7 @@
|
|||
</sizepolicy>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
<cursorShape>ArrowCursor</cursorShape>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
|
@ -461,7 +451,7 @@
|
|||
</sizepolicy>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
<cursorShape>ArrowCursor</cursorShape>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
|
|
|
@ -39,7 +39,7 @@ void ModeButton::initUI()
|
|||
setModeIcon();
|
||||
setFixedSize(QSize(24, 24));
|
||||
setModeIcon();
|
||||
setCursor(Qt::PointingHandCursor);
|
||||
setCursor(Qt::ArrowCursor);
|
||||
setStyleSheet("QPushButton::pressed{border:none;background-color:transparent}"
|
||||
"QPushButton::hover::!pressed{border:none;background-color:transparent}");
|
||||
|
||||
|
|
|
@ -2,9 +2,12 @@ project(uniauth-backend)
|
|||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
|
||||
pkg_check_modules(LIGHTDM-QT5-3 REQUIRED liblightdm-qt5-3)
|
||||
|
||||
include_directories(
|
||||
${Qt5Core_INCLUDE_DIRS}
|
||||
${Qt5DBus_INCLUDE_DIRS}
|
||||
${LIGHTDM-QT5-3_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(bin_SRCS
|
||||
|
@ -16,10 +19,15 @@ set(bin_SRCS
|
|||
src/serviceinterface.cpp
|
||||
src/servicemanager.h
|
||||
src/servicemanager.cpp
|
||||
src/personalizeddata.h
|
||||
src/CSingleton.h
|
||||
src/personalizeddata.cpp
|
||||
src/rsac.h
|
||||
src/rsac.cpp
|
||||
)
|
||||
|
||||
add_executable(uniauth-backend ${bin_SRCS})
|
||||
target_link_libraries(uniauth-backend Qt5::Core Qt5::DBus -lukui-log4qt)
|
||||
target_link_libraries(uniauth-backend Qt5::Core Qt5::DBus -lukui-log4qt ${LIGHTDM-QT5-3_LIBRARIES} -lcrypto)
|
||||
|
||||
install(TARGETS uniauth-backend DESTINATION bin)
|
||||
install(FILES org.ukui.UniauthBackend.conf DESTINATION /etc/dbus-1/system.d/)
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
#ifndef CSINGLETON_H
|
||||
#define CSINGLETON_H
|
||||
|
||||
|
||||
template <typename T>
|
||||
class SingleTon
|
||||
{
|
||||
public:
|
||||
// 创建单例实例
|
||||
template<typename... Args>
|
||||
static T* instance(Args&&... args)
|
||||
{
|
||||
if (m_pInstance == nullptr)
|
||||
{
|
||||
m_pInstance = new T(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
return m_pInstance;
|
||||
}
|
||||
|
||||
// 获取单例
|
||||
static T* getInstance()
|
||||
{
|
||||
return m_pInstance;
|
||||
}
|
||||
|
||||
// 删除单例
|
||||
static void destroyInstance()
|
||||
{
|
||||
delete m_pInstance;
|
||||
m_pInstance = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
SingleTon();
|
||||
virtual ~SingleTon();
|
||||
|
||||
private:
|
||||
static T* m_pInstance;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
T* SingleTon<T>::m_pInstance = nullptr;
|
||||
|
||||
|
||||
#endif
|
|
@ -21,6 +21,7 @@
|
|||
#include <QDBusInterface>
|
||||
#include <QDBusArgument>
|
||||
#include <QDBusMetaType>
|
||||
#include <memory>
|
||||
|
||||
struct DeviceInfo {
|
||||
int device_id;
|
||||
|
@ -52,6 +53,10 @@ enum BioType {
|
|||
|
||||
Q_DECLARE_METATYPE(DeviceInfo)
|
||||
Q_DECLARE_METATYPE(QList<QDBusVariant>)
|
||||
|
||||
typedef std::shared_ptr<DeviceInfo> DeviceInfoPtr;
|
||||
typedef QList<DeviceInfoPtr> DeviceList;
|
||||
|
||||
void registerCustomTypes();
|
||||
QDBusArgument &operator<<(QDBusArgument &argument, const DeviceInfo &deviceInfo);
|
||||
const QDBusArgument &operator>>(const QDBusArgument &argument, DeviceInfo &deviceInfo);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
**/
|
||||
#include <QCoreApplication>
|
||||
#include "serviceinterface.h"
|
||||
#include "personalizeddata.h"
|
||||
#include <ukui-log4qt.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
@ -24,6 +25,8 @@ int main(int argc, char *argv[])
|
|||
initUkuiLog4qt("ukui-biometric-uniauth");
|
||||
QCoreApplication a(argc, argv);
|
||||
|
||||
KYLINUSERDATAMNG::instance();
|
||||
|
||||
ServiceInterface serviveInterface;
|
||||
Q_UNUSED(serviveInterface);
|
||||
|
||||
|
|
|
@ -0,0 +1,345 @@
|
|||
#include "personalizeddata.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonValue>
|
||||
#include <QJsonParseError>
|
||||
#include <QJsonArray>
|
||||
#include <QFile>
|
||||
#include <QDate>
|
||||
#include <QTime>
|
||||
|
||||
enum enum_operation
|
||||
{
|
||||
enum_operation_update = 0,
|
||||
enum_operation_add,
|
||||
enum_operation_del,
|
||||
};
|
||||
|
||||
PersonalizedData::PersonalizedData(QString user)
|
||||
{
|
||||
KyInfo() << user;
|
||||
m_user = user;
|
||||
m_usd_conf_path = QString("/var/lib/lightdm-data/%1/usd/config/ukui-settings-daemon.settings").arg(m_user);
|
||||
m_greeter_conf_path = QString("/var/lib/lightdm-data/%1/ukui-greeter.conf").arg(m_user);
|
||||
m_file_watch = new QFileSystemWatcher();
|
||||
connect(m_file_watch, &QFileSystemWatcher::fileChanged, this, &PersonalizedData::fileChanged);
|
||||
this->__load_conf_ukuigreeterconf();
|
||||
//无需读取usd配置
|
||||
//this->__load_conf_usd_conf();
|
||||
|
||||
}
|
||||
|
||||
PersonalizedData::~PersonalizedData()
|
||||
{
|
||||
KyInfo() << m_user;
|
||||
if(0 != m_conf_TimerID)
|
||||
{
|
||||
this->killTimer(m_conf_TimerID);
|
||||
m_conf_TimerID = 0;
|
||||
}
|
||||
if(nullptr != m_file_watch)
|
||||
{
|
||||
delete m_file_watch;
|
||||
m_file_watch = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void PersonalizedData::getJsonData(QJsonObject & json)
|
||||
{
|
||||
json["user"] = m_user;
|
||||
{
|
||||
QJsonObject json_1;
|
||||
json_1["dateType"] = m_dateType;
|
||||
json_1["fontSize"] = m_fontSize;
|
||||
json_1["timeType"] = m_timeType;
|
||||
json_1["backgroundPath"] = m_backgroundPath;
|
||||
json_1["color"] = m_color;
|
||||
json["greeter"] = json_1;
|
||||
}
|
||||
}
|
||||
|
||||
QString PersonalizedData::getJsonData()
|
||||
{
|
||||
QJsonObject json;
|
||||
this->getJsonData(json);
|
||||
json["operation"] = enum_operation_update;
|
||||
QJsonDocument document;
|
||||
document.setObject(json);
|
||||
return document.toJson(QJsonDocument::Compact);
|
||||
}
|
||||
|
||||
void PersonalizedData::fileChanged(const QString &path)
|
||||
{
|
||||
KyInfo() << path;
|
||||
if(m_greeter_conf_path == path)
|
||||
{
|
||||
m_greeter_conf_path_changed = true;
|
||||
}
|
||||
if(m_usd_conf_path == path)
|
||||
{
|
||||
m_usd_conf_path_changed = true;
|
||||
}
|
||||
|
||||
if(0 != m_conf_TimerID)
|
||||
{
|
||||
this->killTimer(m_conf_TimerID);
|
||||
m_conf_TimerID = 0;
|
||||
}
|
||||
m_conf_TimerID = this->startTimer(100);
|
||||
}
|
||||
|
||||
void PersonalizedData::timerEvent(QTimerEvent *event)
|
||||
{
|
||||
KyInfo() << m_file_watch->files();
|
||||
if(event->timerId() == m_conf_TimerID)
|
||||
{
|
||||
this->killTimer(m_conf_TimerID);
|
||||
m_conf_TimerID = 0;
|
||||
|
||||
if(m_greeter_conf_path_changed)
|
||||
{
|
||||
m_greeter_conf_path_changed = false;
|
||||
this->__load_conf_ukuigreeterconf();
|
||||
}
|
||||
if(m_usd_conf_path_changed)
|
||||
{
|
||||
m_usd_conf_path_changed = false;
|
||||
this->__load_conf_usd_conf();
|
||||
}
|
||||
emit KYLINUSERDATAMNG::getInstance()->conf_changed(this->getJsonData());
|
||||
}
|
||||
}
|
||||
|
||||
int PersonalizedData::__load_conf_ukuigreeterconf()
|
||||
{
|
||||
KyInfo();
|
||||
QSettings conf(m_greeter_conf_path, QSettings::IniFormat);
|
||||
if(QSettings::NoError != conf.status())
|
||||
{
|
||||
KyWarning() << m_greeter_conf_path << conf.status();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(conf.childGroups().contains("Greeter"))
|
||||
{
|
||||
conf.beginGroup("Greeter");
|
||||
|
||||
if(conf.contains("dateType"))
|
||||
m_dateType = conf.value("dateType", m_dateType).toString();
|
||||
|
||||
if(conf.contains("fontSize"))
|
||||
m_fontSize = conf.value("fontSize", m_fontSize).toInt();
|
||||
|
||||
if(conf.contains("timeType"))
|
||||
m_timeType = conf.value("timeType", m_timeType).toInt();
|
||||
|
||||
conf.endGroup();
|
||||
}
|
||||
|
||||
if(conf.childGroups().contains("greeter"))
|
||||
{
|
||||
conf.beginGroup("greeter");
|
||||
|
||||
if(conf.contains("backgroundPath"))
|
||||
{
|
||||
m_backgroundPath = conf.value("backgroundPath", m_backgroundPath).toString();
|
||||
if(!m_backgroundPath.isEmpty())
|
||||
{
|
||||
m_backgroundPath = this->__copy_file(m_backgroundPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(conf.contains("color"))
|
||||
m_color = conf.value("color", m_color).toString();
|
||||
|
||||
conf.endGroup();
|
||||
}
|
||||
|
||||
if(nullptr != m_file_watch && !m_file_watch->files().contains(m_greeter_conf_path))
|
||||
{
|
||||
m_file_watch->addPath(m_greeter_conf_path);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PersonalizedData::__load_conf_usd_conf()
|
||||
{
|
||||
KyInfo();
|
||||
QSettings conf(m_usd_conf_path, QSettings::IniFormat);
|
||||
if(QSettings::NoError != conf.status())
|
||||
{
|
||||
KyWarning() << m_usd_conf_path << conf.status();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(conf.childGroups().contains("xsettings"))
|
||||
{
|
||||
conf.beginGroup("xsettings");
|
||||
|
||||
if(conf.contains("cursor-size"))
|
||||
m_cursor_size = conf.value("cursor-size", m_cursor_size).toInt();
|
||||
|
||||
if(conf.contains("cursor-theme"))
|
||||
m_cursor_theme = conf.value("cursor-theme", m_cursor_theme).toString();
|
||||
|
||||
if(conf.contains("scaling-factor"))
|
||||
m_scaling_factor = conf.value("scaling-factor", m_scaling_factor).toInt();
|
||||
|
||||
conf.endGroup();
|
||||
}
|
||||
|
||||
if(nullptr != m_file_watch && !m_file_watch->files().contains(m_usd_conf_path))
|
||||
{
|
||||
m_file_watch->addPath(m_usd_conf_path);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
QString PersonalizedData::__copy_file(QString oldfile)
|
||||
{
|
||||
if(QFile::exists(oldfile))
|
||||
{
|
||||
QString newfile = "/tmp/loginBackground-" + m_user;
|
||||
QDate d =QDate::currentDate();
|
||||
newfile += d.toString("yyyy-MM-dd");
|
||||
if(QFile::exists(newfile))
|
||||
{
|
||||
QFile::remove(newfile);
|
||||
}
|
||||
if(QFile::copy(oldfile, newfile))
|
||||
{
|
||||
return newfile;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////PersonalizedDataMng//////////////////////////////////////
|
||||
|
||||
PersonalizedDataMng::PersonalizedDataMng(void)
|
||||
{
|
||||
m_usersModel = new QLightDM::UsersModel(this);
|
||||
connect(m_usersModel, &QAbstractListModel::rowsInserted, this, &PersonalizedDataMng::onUserAdded);
|
||||
connect(m_usersModel, &QAbstractListModel::rowsRemoved, this, &PersonalizedDataMng::onUserRemoved);
|
||||
this->__updateUsersInfo();
|
||||
}
|
||||
|
||||
PersonalizedDataMng::~PersonalizedDataMng()
|
||||
{
|
||||
if(nullptr != m_usersModel)
|
||||
{
|
||||
delete m_usersModel;
|
||||
m_usersModel = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
QString PersonalizedDataMng::GetConfInformation(QString name)
|
||||
{
|
||||
QJsonObject json;
|
||||
if(m_userPersonalizedData.contains(name))
|
||||
{
|
||||
QJsonObject json1;
|
||||
m_userPersonalizedData[name]->getJsonData(json1);
|
||||
json[name] = json1;
|
||||
}
|
||||
else if(name.isEmpty())
|
||||
{
|
||||
for(auto & it : m_userPersonalizedData.toStdMap())
|
||||
{
|
||||
QJsonObject json1;
|
||||
it.second->getJsonData(json1);
|
||||
json[it.first] = json1;
|
||||
}
|
||||
}
|
||||
else if("lightdm" == name)
|
||||
{
|
||||
QString tmp(m_lightdm_str);
|
||||
m_lightdm_str = "";
|
||||
return tmp;
|
||||
}
|
||||
|
||||
QJsonDocument document;
|
||||
document.setObject(json);
|
||||
QString strJson(document.toJson(QJsonDocument::Compact));
|
||||
KyDebug() << strJson;
|
||||
return strJson;
|
||||
}
|
||||
|
||||
void PersonalizedDataMng::SetLoginSynInformation(QString val)
|
||||
{
|
||||
m_lightdm_str = val;
|
||||
}
|
||||
|
||||
void PersonalizedDataMng::onUserAdded(const QModelIndex &, int left, int right)
|
||||
{
|
||||
if(!m_usersModel)
|
||||
return;
|
||||
|
||||
for(int i = left; i <= right; i++)
|
||||
{
|
||||
QString name = m_usersModel->index(i).data(QLightDM::UsersModel::NameRole).toString();
|
||||
KyInfo() << left << right << name;
|
||||
if(!name.isEmpty())
|
||||
{
|
||||
m_userPersonalizedData[name] = KylinUserDatePtr(new PersonalizedData(name));
|
||||
|
||||
QJsonObject json;
|
||||
m_userPersonalizedData[name]->getJsonData(json);
|
||||
json["operation"] = enum_operation_add;
|
||||
QJsonDocument document;
|
||||
document.setObject(json);
|
||||
emit conf_changed(document.toJson());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PersonalizedDataMng::onUserRemoved(const QModelIndex &, int, int)
|
||||
{
|
||||
if(!m_usersModel)
|
||||
return;
|
||||
|
||||
auto tmp = m_userPersonalizedData;
|
||||
for(int i = 0; i < m_usersModel->rowCount(QModelIndex()); i++)
|
||||
{
|
||||
QString name = m_usersModel->index(i).data(QLightDM::UsersModel::NameRole).toString();
|
||||
if(!name.isEmpty())
|
||||
tmp.remove(name);
|
||||
}
|
||||
|
||||
if(tmp.size() > 0)
|
||||
{
|
||||
KyInfo() << tmp.begin().key();
|
||||
m_userPersonalizedData.remove(tmp.begin().key());
|
||||
|
||||
QJsonObject json;
|
||||
json["operation"] = enum_operation_del;
|
||||
json["user"] = tmp.begin().key();
|
||||
QJsonDocument document;
|
||||
document.setObject(json);
|
||||
emit conf_changed(document.toJson());
|
||||
}
|
||||
}
|
||||
|
||||
void PersonalizedDataMng::__updateUsersInfo()
|
||||
{
|
||||
if (m_usersModel)
|
||||
{
|
||||
for(int i = 0; i < m_usersModel->rowCount(QModelIndex()); i++)
|
||||
{
|
||||
QString name = m_usersModel->index(i).data(QLightDM::UsersModel::NameRole).toString();
|
||||
if(!name.isEmpty())
|
||||
{
|
||||
m_userPersonalizedData[name] = KylinUserDatePtr(new PersonalizedData(name));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
#ifndef PERSONALIZEDDATA_H
|
||||
#define PERSONALIZEDDATA_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QSettings>
|
||||
#include <QMap>
|
||||
#include <QFile>
|
||||
#include <QTimer>
|
||||
#include <QEventLoop>
|
||||
#include <QTimerEvent>
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QSharedPointer>
|
||||
#include <QLightDM/Greeter>
|
||||
#include <QLightDM/SessionsModel>
|
||||
#include <QLightDM/UsersModel>
|
||||
#include <QModelIndex>
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonValue>
|
||||
#include <QJsonParseError>
|
||||
#include <QJsonArray>
|
||||
|
||||
#include "ukui-log4qt.h"
|
||||
#include "CSingleton.h"
|
||||
|
||||
|
||||
class PersonalizedData : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PersonalizedData(QString user);
|
||||
virtual ~PersonalizedData();
|
||||
|
||||
////////////////////ukui-greeter-conf//////////////////////////////
|
||||
QString dateType(void){ return m_dateType; }
|
||||
void dateType(QString val){ m_dateType = val; }
|
||||
|
||||
int fontSize(void){ return m_fontSize; }
|
||||
void fontSize(int val){ m_fontSize = val; }
|
||||
|
||||
int timeType(void){ return m_timeType; }
|
||||
void timeType(int val){ m_timeType = val; }
|
||||
|
||||
QString backgroundPath(void){ return m_backgroundPath; }
|
||||
void backgroundPath(QString val){ m_backgroundPath = val; }
|
||||
|
||||
QString color(void){ return m_color; }
|
||||
void color(QString val){ m_color = val; }
|
||||
|
||||
/////////////////////usd-ukui-settings-daemon////////////////////////////////
|
||||
int cursor_size(void){ return m_cursor_size; }
|
||||
void cursor_size(int val){ m_cursor_size = val; }
|
||||
|
||||
QString cursor_theme(void){ return m_cursor_theme; }
|
||||
void cursor_theme(QString val){ m_cursor_theme = val; }
|
||||
|
||||
int scaling_factor(void){ return m_scaling_factor; }
|
||||
void scaling_factor(int val){ m_scaling_factor = val; }
|
||||
|
||||
|
||||
void getJsonData(QJsonObject & json);
|
||||
QString getJsonData(void);
|
||||
|
||||
|
||||
protected slots:
|
||||
void fileChanged(const QString &path);
|
||||
|
||||
virtual void timerEvent( QTimerEvent *event);
|
||||
|
||||
private:
|
||||
int __load_conf_ukuigreeterconf(void);
|
||||
int __load_conf_usd_conf(void);
|
||||
QString __copy_file(QString);
|
||||
protected:
|
||||
//ukui-greeter-conf
|
||||
QString m_dateType = "cn";
|
||||
int m_fontSize = 5;
|
||||
int m_timeType = 24;
|
||||
QString m_backgroundPath;
|
||||
QString m_color;
|
||||
|
||||
//usd-ukui-settings-daemon
|
||||
int m_cursor_size = 48;
|
||||
QString m_cursor_theme;
|
||||
int m_scaling_factor = 1;
|
||||
|
||||
//用户名
|
||||
QString m_user;
|
||||
|
||||
QFileSystemWatcher * m_file_watch = nullptr;
|
||||
QString m_greeter_conf_path;
|
||||
bool m_greeter_conf_path_changed = false;
|
||||
QString m_usd_conf_path;
|
||||
bool m_usd_conf_path_changed = false;
|
||||
int m_conf_TimerID = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef QSharedPointer<PersonalizedData> KylinUserDatePtr;
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
/// \brief The PersonalizedDataMng class
|
||||
///
|
||||
|
||||
class PersonalizedDataMng : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
protected:
|
||||
explicit PersonalizedDataMng(void);
|
||||
virtual ~PersonalizedDataMng();
|
||||
|
||||
|
||||
public:
|
||||
QString GetConfInformation(QString);
|
||||
|
||||
void SetLoginSynInformation(QString val);
|
||||
|
||||
signals:
|
||||
void conf_changed(QString jsonstr);
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onUserAdded(const QModelIndex&, int, int);
|
||||
|
||||
void onUserRemoved(const QModelIndex&, int, int );
|
||||
|
||||
protected:
|
||||
void __updateUsersInfo();
|
||||
|
||||
protected:
|
||||
QMap<QString, KylinUserDatePtr > m_userPersonalizedData;
|
||||
QLightDM::UsersModel * m_usersModel = nullptr;
|
||||
QString m_lightdm_str;
|
||||
friend class SingleTon<PersonalizedDataMng>;
|
||||
};
|
||||
|
||||
typedef SingleTon<PersonalizedDataMng> KYLINUSERDATAMNG;
|
||||
|
||||
#endif // PERSONALIZEDDATA_H
|
|
@ -0,0 +1,199 @@
|
|||
#include "rsac.h"
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
RSA* publicKeyToRSA(const QByteArray &pubKey)
|
||||
{
|
||||
BIO *pBio = BIO_new_mem_buf(pubKey.data(), pubKey.size()); // 创建内存
|
||||
RSA* rsa = PEM_read_bio_RSA_PUBKEY(pBio, nullptr, nullptr, nullptr);
|
||||
BIO_free_all(pBio); // 释放内存
|
||||
return rsa;
|
||||
}
|
||||
|
||||
RSA* privateKeyToRSA(const QByteArray &priKey)
|
||||
{
|
||||
BIO *pBio = BIO_new_mem_buf(priKey.data(), priKey.size()); // 创建内存
|
||||
RSA* rsa = PEM_read_bio_RSAPrivateKey(pBio, nullptr, nullptr, nullptr);
|
||||
BIO_free_all(pBio); // 释放内存
|
||||
return rsa;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RSAC::generateKeyPair
|
||||
* 生成密钥对,并分别保存为文件
|
||||
* @param priKeyFile 私钥文件名
|
||||
* @param pubKeyFile 公钥文件名
|
||||
* @param bits 秘钥长度,一般建议1024及以上
|
||||
*/
|
||||
void RSAC::generateKeyPair(const QString &priKeyFile, const QString &pubKeyFile, int bits)
|
||||
{
|
||||
// 生成公钥
|
||||
RSA* rsa = RSA_generate_key(bits, RSA_F4, nullptr, nullptr);
|
||||
BIO *bp = BIO_new(BIO_s_file());
|
||||
BIO_write_filename(bp, (void*)pubKeyFile.toStdString().c_str());
|
||||
PEM_write_bio_RSAPublicKey(bp, rsa);
|
||||
BIO_free_all(bp);
|
||||
|
||||
// 生成私钥
|
||||
bp = BIO_new(BIO_s_file());
|
||||
BIO_write_filename(bp, (void*)priKeyFile.toStdString().c_str());
|
||||
PEM_write_bio_RSAPrivateKey(bp, rsa, nullptr, nullptr, 0, nullptr, nullptr);
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
BIO_free_all(bp);
|
||||
RSA_free(rsa);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RSAC::generateKeyPair
|
||||
* 生成密钥对数据
|
||||
* @param privateKey 私钥数据
|
||||
* @param publicKey 公钥数据
|
||||
* @param bits 秘钥长度,一般建议1024及以上
|
||||
*/
|
||||
void RSAC::generateKeyPair(QByteArray &privateKey, QByteArray &pubKey, int bits)
|
||||
{
|
||||
// 生成密钥对
|
||||
RSA *keyPair = RSA_generate_key(bits, RSA_F4, nullptr, nullptr);
|
||||
|
||||
BIO *pri = BIO_new(BIO_s_mem());
|
||||
BIO *pub = BIO_new(BIO_s_mem());
|
||||
|
||||
PEM_write_bio_RSAPrivateKey(pri, keyPair, nullptr, nullptr, 0, nullptr, nullptr);
|
||||
PEM_write_bio_RSA_PUBKEY(pub, keyPair);
|
||||
|
||||
// 获取长度
|
||||
int pri_len = BIO_pending(pri);
|
||||
int pub_len = BIO_pending(pub);
|
||||
|
||||
privateKey.resize(pri_len);
|
||||
pubKey.resize(pub_len);
|
||||
|
||||
BIO_read(pri, privateKey.data(), pri_len);
|
||||
BIO_read(pub, pubKey.data(), pub_len);
|
||||
|
||||
// 内存释放
|
||||
RSA_free(keyPair);
|
||||
BIO_free_all(pub);
|
||||
BIO_free_all(pri);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RSAC::encrypt
|
||||
* RSA加密函数,使用公钥对输入数据,进行加密
|
||||
* @param in 输入数据(明文)
|
||||
* @param out 输出数据(密文)
|
||||
* @param pubKey 公钥
|
||||
* @return 执行结果
|
||||
*/
|
||||
bool RSAC::encrypt(const QByteArray &in, QByteArray &out, const QByteArray& pubKey)
|
||||
{
|
||||
// 公钥数据转RSA
|
||||
RSA* rsa = publicKeyToRSA(pubKey);
|
||||
if (rsa == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 对任意长度数据进行加密,超长时,进行分段加密
|
||||
int keySize = RSA_size(rsa);
|
||||
int dataLen = in.size();
|
||||
const unsigned char *from = (const unsigned char *)in.data();
|
||||
QByteArray to(keySize, 0);
|
||||
int readLen = 0;
|
||||
do
|
||||
{
|
||||
int select = (keySize - 11) > dataLen ? dataLen : (keySize - 11);
|
||||
RSA_public_encrypt(select, (from + readLen), (unsigned char *)to.data(), rsa, RSA_PKCS1_PADDING);
|
||||
dataLen -= select;
|
||||
readLen += select;
|
||||
out.append(to);
|
||||
}while (dataLen > 0);
|
||||
RSA_free(rsa);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RSAC::private_decrypt
|
||||
* RSA解密函数,使用私钥对输入数据,进行解密
|
||||
* @param in 输入数据(密文)
|
||||
* @param out 输出数据(解密后的内容)
|
||||
* @param priKey 私钥
|
||||
* @return 执行结果
|
||||
*/
|
||||
bool RSAC::decrypt(const QByteArray &in, QByteArray &out, const QByteArray& priKey)
|
||||
{
|
||||
// 私钥数据转RSA
|
||||
RSA* rsa = privateKeyToRSA(priKey);
|
||||
if (rsa == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 对任意长度数据进行解密,超长时,进行分段解密
|
||||
int keySize = RSA_size(rsa);
|
||||
int dataLen = in.size();
|
||||
const unsigned char *from = (const unsigned char *)in.data();
|
||||
QByteArray to(keySize, 0);
|
||||
int readLen = 0;
|
||||
do
|
||||
{
|
||||
int size = RSA_private_decrypt(keySize, (from + readLen), (unsigned char *)to.data(), rsa, RSA_PKCS1_PADDING);
|
||||
dataLen -= keySize;
|
||||
readLen += keySize;
|
||||
out.append(to.data(), size);
|
||||
}while (dataLen > 0);
|
||||
RSA_free(rsa);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RSAC::sign
|
||||
* 使用私钥对摘要数据进行签名
|
||||
* @param digest 摘要数据
|
||||
* @param sign 签名后的数据
|
||||
* @param priKey 私钥
|
||||
* @return 执行结果
|
||||
*/
|
||||
bool RSAC::sign(const QByteArray &digest, QByteArray &sign, const QByteArray& priKey)
|
||||
{
|
||||
// 私钥数据转RSA
|
||||
RSA* rsa = privateKeyToRSA(priKey);
|
||||
if (rsa == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 对digest进行签名
|
||||
unsigned int siglen = 0;
|
||||
QByteArray temp(RSA_size(rsa), 0);
|
||||
RSA_sign(NID_sha1, (const unsigned char*)digest.data(), digest.size(),
|
||||
(unsigned char*)temp.data(), &siglen, rsa);
|
||||
sign.clear();
|
||||
sign.append(temp.data(), siglen);
|
||||
RSA_free(rsa);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RSAC::verify
|
||||
* 使用公钥对摘要数据进行验签
|
||||
* @param digest 摘要数据
|
||||
* @param sign 签名后的数据
|
||||
* @param pubKey 公钥
|
||||
* @return 执行结果
|
||||
*/
|
||||
bool RSAC::verify(const QByteArray &digest, const QByteArray &sign, const QByteArray& pubKey)
|
||||
{
|
||||
// 公钥数据转RSA
|
||||
RSA* rsa = publicKeyToRSA(pubKey);
|
||||
if (rsa == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 对digest、sign进行验签
|
||||
int ret = RSA_verify(NID_sha1, (const unsigned char*)digest.data(), digest.size(),
|
||||
(const unsigned char *)sign.data(), sign.size(), rsa);
|
||||
RSA_free(rsa);
|
||||
return (ret == 1);
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef RSAC_H
|
||||
#define RSAC_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
/**
|
||||
* @brief The RSAC class
|
||||
* RSA算法相关实现,包括密钥对生成,加密与解密,签名与验签。
|
||||
*/
|
||||
class RSAC
|
||||
{
|
||||
public:
|
||||
// 生成秘钥对
|
||||
void generateKeyPair(const QString& priKeyFile, const QString &pubKeyFile, int bits = 1024);
|
||||
void generateKeyPair(QByteArray& priKey, QByteArray& pubKey, int bits = 1024);
|
||||
|
||||
// 对数据进行加解密
|
||||
bool encrypt(const QByteArray& in, QByteArray& out, const QByteArray& pubKey);
|
||||
bool decrypt(const QByteArray& in, QByteArray& out, const QByteArray& priKey);
|
||||
|
||||
// 对摘要进行签名和验签
|
||||
bool sign(const QByteArray& digest, QByteArray& sign, const QByteArray &priKey);
|
||||
bool verify(const QByteArray& digest, const QByteArray &sign, const QByteArray &pubKey);
|
||||
};
|
||||
|
||||
#endif // RSAC_H
|
|
@ -19,6 +19,9 @@
|
|||
#include <QDBusConnection>
|
||||
#include <QSettings>
|
||||
#include <QDir>
|
||||
#include <QRegExp>
|
||||
#include <QFile>
|
||||
#include <QTimer>
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -29,11 +32,25 @@
|
|||
#include <QDBusMetaType>
|
||||
#include <QDBusConnectionInterface>
|
||||
#include <QDBusContext>
|
||||
#include <QDBusInterface>
|
||||
#include <QDBusMessage>
|
||||
#include "servicemanager.h"
|
||||
#include "personalizeddata.h"
|
||||
#include <unistd.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
#define UKUI_GREETER "/usr/sbin/ukui-greeter"
|
||||
#define UKUI_SCREENSAVER "/usr/bin/ukui-screensaver-dialog"
|
||||
|
||||
#define GREETER_DBUS_PATH "/"
|
||||
#define GREETER_DBUS_INTERFACE "org.ukui.greeter"
|
||||
#define SCREENSAVER_DBUS_PATH "/"
|
||||
#define SCREENSAVER_DBUS_INTERFACE "org.ukui.screensaver"
|
||||
#define COMM_CONFIG_PATH "/etc/biometric-auth/ukui-biometric.conf"
|
||||
#define USER_CONFIG_PATH "/home/%1/.biometric_auth/ukui_biometric.conf"
|
||||
#define OLD_990_USER_CONFIG_PATH "/home/%1/.biometric-auth/ukui-biometric.conf"
|
||||
#define PROC_CPUINFO "/proc/cpuinfo"
|
||||
|
||||
ServiceInterface::ServiceInterface()
|
||||
{
|
||||
|
@ -50,9 +67,10 @@ ServiceInterface::ServiceInterface()
|
|||
}
|
||||
|
||||
registerCustomTypes();
|
||||
checkIs990();
|
||||
m_serviceInterface = new QDBusInterface(DBUS_SERVICE, DBUS_PATH,
|
||||
DBUS_INTERFACE,
|
||||
QDBusConnection::systemBus());
|
||||
QDBusConnection::systemBus(), this);
|
||||
|
||||
m_serviceInterface->setTimeout(2147483647);
|
||||
connect(m_serviceInterface, SIGNAL(USBDeviceHotPlug(int, int, int)),
|
||||
|
@ -63,6 +81,9 @@ ServiceInterface::ServiceInterface()
|
|||
ServiceManager *sm = ServiceManager::instance();
|
||||
connect(sm, &ServiceManager::serviceStatusChanged,
|
||||
this, &ServiceInterface::onBiometricDbusChanged);
|
||||
|
||||
rsac.generateKeyPair(priKey, pubKey, 1024);
|
||||
connect(KYLINUSERDATAMNG::getInstance(), &PersonalizedDataMng::conf_changed, this, &ServiceInterface::updateUserInformation);
|
||||
}
|
||||
|
||||
void ServiceInterface::setDefaultDevice(QString userName, int bioDevType, QString deviceName)
|
||||
|
@ -475,8 +496,22 @@ bool ServiceInterface::getBioAuthStatus(QString userName, int bioAuthType)
|
|||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
//同步990旧的配置文件,然后删除
|
||||
if(getIs990() && (bioAuthType == ENABLETYPE_BIO)){
|
||||
QString oldConfigPath = QString(OLD_990_USER_CONFIG_PATH).arg(userName);
|
||||
QSettings oldSettings(oldConfigPath, QSettings::IniFormat);
|
||||
if(oldSettings.contains(strBioAuthType)){
|
||||
settings.setValue(strBioAuthType,oldSettings.value(strBioAuthType).toBool());
|
||||
oldSettings.remove(strBioAuthType);
|
||||
oldSettings.sync();
|
||||
}
|
||||
}
|
||||
if (settings.contains(strBioAuthType)) {
|
||||
return settings.value(strBioAuthType).toBool();
|
||||
}else if(getIs990() && (bioAuthType == ENABLETYPE_BIO)){
|
||||
//990默认为打开
|
||||
return true;
|
||||
} else {
|
||||
QSettings settings2(COMM_CONFIG_PATH, QSettings::IniFormat);
|
||||
if (settings2.contains(strBioAuthType)) {
|
||||
|
@ -496,6 +531,23 @@ int ServiceInterface::getMaxFailedTimes()
|
|||
return 3;
|
||||
}
|
||||
|
||||
int ServiceInterface::getFTimeoutTimes()
|
||||
{
|
||||
QSettings sysSettings(COMM_CONFIG_PATH, QSettings::IniFormat);
|
||||
if(sysSettings.contains("FaceTimeoutTimes"))
|
||||
return sysSettings.value("FaceTimeoutTimes").toInt();
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ServiceInterface::setFTimeoutTimes(int times)
|
||||
{
|
||||
if (times < 1)
|
||||
times = 1;
|
||||
QSettings settings(COMM_CONFIG_PATH, QSettings::IniFormat);
|
||||
settings.setValue("FaceTimeoutTimes", times);
|
||||
}
|
||||
|
||||
bool ServiceInterface::getQRCodeEnable()
|
||||
{
|
||||
bool isEnable = false;
|
||||
|
@ -576,6 +628,44 @@ void ServiceInterface::onUSBDeviceHotPlug(int drvid, int action, int deviceNum)
|
|||
}
|
||||
}
|
||||
|
||||
//记录当前生物认证信息
|
||||
void ServiceInterface::recordAuthDrive(QString appName,int drvid,bool insert)
|
||||
{
|
||||
if(insert){
|
||||
m_AuthingDriveList.insert(appName,drvid);
|
||||
}else{
|
||||
m_AuthingDriveList.remove(appName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//获取当前正在认证的应用
|
||||
QStringList ServiceInterface::getAllAuthApp()
|
||||
{
|
||||
return m_AuthingDriveList.keys();
|
||||
}
|
||||
|
||||
//根据应用名称获取认证的驱动
|
||||
int ServiceInterface::getAppAuthDrive(QString appName)
|
||||
{
|
||||
if(m_AuthingDriveList.contains(appName)){
|
||||
return m_AuthingDriveList.value(appName);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
QString ServiceInterface::GetUserInformation(QString username)
|
||||
{
|
||||
KyInfo() << username;
|
||||
return KYLINUSERDATAMNG::getInstance()->GetConfInformation(username);
|
||||
}
|
||||
|
||||
void ServiceInterface::SetLoginSynInformation(QString val)
|
||||
{
|
||||
KyInfo() << val;
|
||||
KYLINUSERDATAMNG::getInstance()->SetLoginSynInformation(val);
|
||||
}
|
||||
|
||||
void ServiceInterface::waitBiometricServiceStatus()
|
||||
{
|
||||
qDebug()<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~` get biometric status";
|
||||
|
@ -628,7 +718,7 @@ void ServiceInterface::updateCommDefaultDevice(int nDriId)
|
|||
QDBusArgument argument;
|
||||
QList<QDBusVariant> qlist;
|
||||
QDBusVariant item;
|
||||
DeviceInfo *deviceInfo;
|
||||
DeviceInfoPtr deviceInfo = nullptr;
|
||||
|
||||
/* 返回值为 i -- int 和 av -- array of variant */
|
||||
QDBusPendingReply<int, QList<QDBusVariant> > reply = m_serviceInterface->call("GetDrvList");
|
||||
|
@ -652,7 +742,7 @@ void ServiceInterface::updateCommDefaultDevice(int nDriId)
|
|||
variant = item.variant(); /* 转为普通QVariant对象 */
|
||||
/* 解封装得到 QDBusArgument 对象 */
|
||||
argument = variant.value<QDBusArgument>();
|
||||
deviceInfo = new DeviceInfo();
|
||||
deviceInfo = std::make_shared<DeviceInfo>();
|
||||
argument >> *deviceInfo; /* 提取最终的 DeviceInfo 结构体 */
|
||||
if (nDriId == deviceInfo->device_id) {
|
||||
if (getCommDefaultDevice(deviceInfo->biotype).isEmpty()) {
|
||||
|
@ -662,19 +752,13 @@ void ServiceInterface::updateCommDefaultDevice(int nDriId)
|
|||
}
|
||||
}
|
||||
} else {
|
||||
for (auto devInfo : m_listDeviceInfos) {
|
||||
if (devInfo) {
|
||||
delete devInfo;
|
||||
devInfo = nullptr;
|
||||
}
|
||||
}
|
||||
m_listDeviceInfos.clear();
|
||||
for (int i = 0; i < deviceCount; i++) {
|
||||
item = qlist[i]; /* 取出一个元素 */
|
||||
variant = item.variant(); /* 转为普通QVariant对象 */
|
||||
/* 解封装得到 QDBusArgument 对象 */
|
||||
argument = variant.value<QDBusArgument>();
|
||||
deviceInfo = new DeviceInfo();
|
||||
deviceInfo = std::make_shared<DeviceInfo>();
|
||||
argument >> *deviceInfo; /* 提取最终的 DeviceInfo 结构体 */
|
||||
m_listDeviceInfos.push_back(deviceInfo);
|
||||
}
|
||||
|
@ -797,3 +881,230 @@ void ServiceInterface::onBiometricDbusChanged(bool bActive)
|
|||
initData();
|
||||
}
|
||||
}
|
||||
|
||||
void ServiceInterface::checkIs990()
|
||||
{
|
||||
QRegExp r1("kirin.*9.0");
|
||||
r1.setCaseSensitivity(Qt::CaseInsensitive);
|
||||
QRegExp r2("pangu.*m900");
|
||||
r2.setCaseSensitivity(Qt::CaseInsensitive);
|
||||
|
||||
QFile file(PROC_CPUINFO);
|
||||
if(!file.exists()){
|
||||
is990 = false;
|
||||
}
|
||||
file.open(QFile::ReadOnly);
|
||||
QString str(file.readAll());
|
||||
is990 = (str.contains(r1) || str.contains(r2));
|
||||
file.close();
|
||||
}
|
||||
|
||||
bool ServiceInterface::getIs990()
|
||||
{
|
||||
return is990;
|
||||
}
|
||||
|
||||
QString ServiceInterface::getPublicEncrypt()
|
||||
{
|
||||
return pubKey;
|
||||
}
|
||||
|
||||
bool ServiceInterface::sendPassword(QString username,QByteArray password)
|
||||
{
|
||||
QByteArray decryptText;
|
||||
QByteArray encryptText;
|
||||
rsac.decrypt(password, decryptText, priKey); // 解密
|
||||
//如果处于登录状态
|
||||
|
||||
qDebug()<<"sendPassword"<<loginAppList.count();
|
||||
if(loginAppList.contains("lightdm")){
|
||||
qDebug()<<"login:";
|
||||
isFirstLogin = false;
|
||||
QString publicKey = getLoginPubKey(loginAppList.value("lightdm"),GREETER_DBUS_PATH,GREETER_DBUS_INTERFACE);
|
||||
rsac.encrypt(decryptText, encryptText, publicKey.toLatin1());
|
||||
return sendLoginPassword(loginAppList.value("lightdm"),GREETER_DBUS_PATH,GREETER_DBUS_INTERFACE,username,encryptText);
|
||||
}
|
||||
|
||||
//处于锁屏状态
|
||||
if(loginAppList.contains(username)){
|
||||
qDebug()<<"unlock:";
|
||||
isFirstLogin = false;
|
||||
QString publicKey = getLoginPubKey(loginAppList.value(username),SCREENSAVER_DBUS_PATH,SCREENSAVER_DBUS_INTERFACE);
|
||||
rsac.encrypt(decryptText, encryptText, publicKey.toLatin1());
|
||||
return sendLoginPassword(loginAppList.value(username),SCREENSAVER_DBUS_PATH,SCREENSAVER_DBUS_INTERFACE,username,encryptText);
|
||||
}
|
||||
|
||||
//如果是第一次调用,则配置自动登录
|
||||
if(isFirstLogin){
|
||||
qDebug()<<"isFirstLogin:";
|
||||
isFirstLogin = false;
|
||||
hasSaveLogin = true;
|
||||
return handleFirstSingleLogn(username,decryptText);
|
||||
}
|
||||
|
||||
isFirstLogin = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ServiceInterface::handleFirstSingleLogn(QString username,QByteArray decryptText)
|
||||
{
|
||||
QEventLoop loopTemp;
|
||||
bool ret = false;
|
||||
QByteArray encryptText;
|
||||
|
||||
qDebug()<<"handleFirstSingleLogn wait";
|
||||
QMetaObject::Connection connection = QObject::connect(this, &ServiceInterface::onLoginServicdRegisted, [&loopTemp]() {
|
||||
if (loopTemp.isRunning()) {
|
||||
loopTemp.quit();
|
||||
}
|
||||
});
|
||||
QTimer::singleShot(10000, &loopTemp, SLOT(quit()));
|
||||
loopTemp.exec();
|
||||
qDebug()<<"handleFirstSingleLogn finished";
|
||||
disconnect(connection);
|
||||
qDebug()<<loginAppList.count();
|
||||
if(loginAppList.contains("lightdm")){
|
||||
isFirstLogin = false;
|
||||
QString publicKey = getLoginPubKey(loginAppList.value("lightdm"),GREETER_DBUS_PATH,GREETER_DBUS_INTERFACE);
|
||||
if(publicKey.isEmpty()){
|
||||
qDebug()<<"get Login PubKey failed!";
|
||||
return false;
|
||||
}
|
||||
rsac.encrypt(decryptText, encryptText, publicKey.toLatin1());
|
||||
return sendLoginPassword(loginAppList.value("lightdm"),GREETER_DBUS_PATH,GREETER_DBUS_INTERFACE,username,encryptText);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString ServiceInterface::getLoginPubKey(QString service,QString path,QString interface)
|
||||
{
|
||||
QDBusInterface iface(service,
|
||||
path,
|
||||
interface,
|
||||
QDBusConnection::systemBus());
|
||||
QDBusReply<QString> stateReply = iface.call("getPublicEncrypt");
|
||||
|
||||
if(!stateReply.isValid()){
|
||||
qWarning()<< "Get state error:" << stateReply.error();
|
||||
qDebug()<<"getPublicEncrypt failed";
|
||||
return "";
|
||||
}
|
||||
return stateReply.value();
|
||||
}
|
||||
|
||||
bool ServiceInterface::sendSignalLoginFinished(QString username,bool res)
|
||||
{
|
||||
qDebug()<<"sendSignalLoginFinished "<<username<<res;
|
||||
emit onSignalLoginFinished(username,res);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ServiceInterface::sendLoginPassword(QString service,QString path,QString interface,QString username,QByteArray array)
|
||||
{
|
||||
QEventLoop loopTemp;
|
||||
bool ret = false;
|
||||
|
||||
qDebug()<<"sendLoginPassword";
|
||||
QMetaObject::Connection connection = QObject::connect(this, &ServiceInterface::onSignalLoginFinished, [&loopTemp,&ret](QString username,bool res) {
|
||||
qDebug()<<"onSignalLoginFinished:"<<username<<res;
|
||||
ret = res;
|
||||
if (loopTemp.isRunning()) {
|
||||
loopTemp.quit();
|
||||
}
|
||||
});
|
||||
|
||||
QDBusInterface iface(service,
|
||||
path,
|
||||
interface,
|
||||
QDBusConnection::systemBus());
|
||||
|
||||
QDBusReply<bool> stateReply = iface.call("sendPassword",username,array);
|
||||
if(!stateReply.isValid()){
|
||||
disconnect(connection);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!stateReply.value()){
|
||||
disconnect(connection);
|
||||
return stateReply.value();
|
||||
}
|
||||
|
||||
QTimer::singleShot(30000, &loopTemp, SLOT(quit()));
|
||||
|
||||
loopTemp.exec();
|
||||
disconnect(connection);
|
||||
|
||||
return ret;
|
||||
}
|
||||
QString ServiceInterface::getProcessNameFromPid(int pid)
|
||||
{
|
||||
QString filename = "/proc/" + QString::number(pid) + "/cmdline";
|
||||
qDebug()<<"filename is "<<filename;
|
||||
QFile file(filename);
|
||||
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
qDebug()<<"Can't open the file!"<<endl;
|
||||
return "";
|
||||
}
|
||||
QByteArray text = file.readAll();
|
||||
return QString(text);
|
||||
}
|
||||
|
||||
QString ServiceInterface::getUserNameFromUid(int uid)
|
||||
{
|
||||
struct passwd *pw = NULL;
|
||||
pw = getpwuid(uid);
|
||||
if(pw){
|
||||
return QString(pw->pw_name);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void ServiceInterface::onDbusNameOwnerChanged(QString name,QString oldOwner,QString newOwner)
|
||||
{
|
||||
if(newOwner.isEmpty()){
|
||||
for(QString str:loginAppList.keys()){
|
||||
if(name == loginAppList.value(str)){
|
||||
qDebug()<<"remove name "<<name;
|
||||
loginAppList.remove(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ServiceInterface::registerLoginApp()
|
||||
{
|
||||
QDBusConnection conn = connection();
|
||||
QDBusMessage msg = message();
|
||||
|
||||
qDebug() << "Sender Name" << conn.interface()->serviceOwner(msg.service()).value();
|
||||
qDebug() << "Sender Pid " << conn.interface()->servicePid(msg.service()).value();
|
||||
qDebug() << "Sender uid " << conn.interface()->serviceUid(msg.service()).value();
|
||||
|
||||
int pid = conn.interface()->servicePid(msg.service()).value();
|
||||
QString serviceOwner = conn.interface()->serviceOwner(msg.service()).value();
|
||||
int uid = conn.interface()->serviceUid(msg.service()).value();
|
||||
|
||||
QString appName = getProcessNameFromPid(pid);
|
||||
qDebug()<<"appName = "<<appName;
|
||||
|
||||
if(appName != UKUI_GREETER && appName != UKUI_SCREENSAVER){
|
||||
return false;
|
||||
}
|
||||
|
||||
QString appUser = getUserNameFromUid(uid);
|
||||
if(appUser.isEmpty())
|
||||
return false;
|
||||
|
||||
qDebug()<<"insert "<<appUser<<serviceOwner;
|
||||
loginAppList.insert(appUser,serviceOwner);
|
||||
|
||||
if(appUser == "lightdm" && hasSaveLogin){
|
||||
QTimer::singleShot(1000, this, [=](){
|
||||
emit onLoginServicdRegisted();
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,10 @@
|
|||
#include <QCoreApplication>
|
||||
#include <QDBusContext>
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QDBusInterface>
|
||||
#include "rsac.h"
|
||||
|
||||
#define DBUS_SERVICE "org.ukui.Biometric"
|
||||
#define DBUS_PATH "/org/ukui/Biometric"
|
||||
|
@ -57,6 +60,10 @@ public slots:
|
|||
void setBioAuthStatus(int bioAuthType, bool status);
|
||||
// 获取最大失败次数
|
||||
int getMaxFailedTimes();
|
||||
// 获取人脸识别超时停用次数
|
||||
int getFTimeoutTimes();
|
||||
// 设置人脸识别超时停用次数
|
||||
void setFTimeoutTimes(int times);
|
||||
// 获取是否使能微信扫码登录
|
||||
bool getQRCodeEnable();
|
||||
// 获取是否双认证
|
||||
|
@ -69,17 +76,39 @@ public slots:
|
|||
bool getUseFirstDevice();
|
||||
// 获取是否隐藏切换按钮
|
||||
bool getHiddenSwitchButton();
|
||||
|
||||
// 记录当前正在进行生物认证的设备
|
||||
void recordAuthDrive(QString appName,int drvid,bool insert);
|
||||
// 获取当前正在进行生物认证的应用
|
||||
QStringList getAllAuthApp();
|
||||
// 获取当前应用在认证的驱动
|
||||
int getAppAuthDrive(QString appName);
|
||||
//获取用户配置
|
||||
QString GetUserInformation(QString username);
|
||||
//同步登录界面配置
|
||||
void SetLoginSynInformation(QString val);
|
||||
// 获取公钥
|
||||
QString getPublicEncrypt();
|
||||
//发送用户名和密码
|
||||
bool sendPassword(QString username,QByteArray password);
|
||||
//前端注册到后端接口
|
||||
bool registerLoginApp();
|
||||
//发送认证结果
|
||||
bool sendSignalLoginFinished(QString username,bool res);
|
||||
private slots:
|
||||
void onUSBDeviceHotPlug(int drvid, int action, int deviceNum);
|
||||
void onBiometricDbusChanged(bool bActive);
|
||||
|
||||
void onDbusNameOwnerChanged(QString name,QString oldOwner,QString newOwner);
|
||||
signals:
|
||||
//默认设备改变
|
||||
void defaultDeviceChanged(QString userName, int bioDevType, QString deviceName);
|
||||
//开关状态改变
|
||||
void bioAuthStatusChanged(QString userName, int type, bool status);
|
||||
|
||||
//用户配置改变
|
||||
void updateUserInformation(QString jsonstring);
|
||||
//单点登录完成信号
|
||||
void onSignalLoginFinished(QString username,bool res);
|
||||
//登录服务以启动信号
|
||||
void onLoginServicdRegisted();
|
||||
private:
|
||||
//设置默认设备
|
||||
void setDefaultDevice(QString userName, int bioDevType, QString deviceName);
|
||||
|
@ -95,11 +124,34 @@ private:
|
|||
void updateCommDefaultDevice(int nDriId);
|
||||
// 等待生物识别服务
|
||||
void waitBiometricServiceStatus();
|
||||
|
||||
//判断系统是否为990
|
||||
void checkIs990();
|
||||
//获取系统是否为990
|
||||
bool getIs990();
|
||||
//根据pid获取进程名称
|
||||
QString getProcessNameFromPid(int pid);
|
||||
//根据uid获取用户名
|
||||
QString getUserNameFromUid(int uid);
|
||||
//获取登录锁屏界面的公钥
|
||||
QString getLoginPubKey(QString service,QString path,QString interface);
|
||||
//发送密码到登录锁屏界面
|
||||
bool sendLoginPassword(QString service,QString path,QString interface,QString username,QByteArray array);
|
||||
//处理首次登录逻辑
|
||||
bool handleFirstSingleLogn(QString username,QByteArray decryptText);
|
||||
private:
|
||||
QDBusInterface *m_serviceInterface = nullptr;
|
||||
QList<DeviceInfo *> m_listDeviceInfos;
|
||||
DeviceList m_listDeviceInfos;
|
||||
int deviceCount = 0;
|
||||
bool is990 = false;
|
||||
QMap<QString,int> m_AuthingDriveList;
|
||||
|
||||
QMap<QString,QString> loginAppList;
|
||||
RSAC rsac;
|
||||
QByteArray priKey, pubKey;
|
||||
bool isFirstLogin = true;
|
||||
bool hasSaveLogin = false;
|
||||
QString savedUsername;
|
||||
QByteArray savedPassword;
|
||||
};
|
||||
|
||||
#endif // SERVICEINTERFACE_H
|
||||
|
|
|
@ -83,6 +83,8 @@ void ServiceManager::onDBusNameOwnerChanged(const QString &name,
|
|||
<< (newOwner.isEmpty() ? "inactivate" : "activate");
|
||||
Q_EMIT serviceStatusChanged(!newOwner.isEmpty());
|
||||
}
|
||||
|
||||
Q_EMIT dbusNameOwnerChanged(name,oldOwner,newOwner);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -36,6 +36,7 @@ private:
|
|||
|
||||
Q_SIGNALS:
|
||||
void serviceStatusChanged(bool activate);
|
||||
void dbusNameOwnerChanged(QString name,QString oldOwner,QString newOwner);
|
||||
|
||||
public Q_SLOTS:
|
||||
void onDBusNameOwnerChanged(const QString &name,
|
||||
|
|
Loading…
Reference in New Issue