Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 2 years ago.
Improve this question
I am looking for Google chat api code with service account. I tried following code but getting some errors, not sure what I am missing.
include_once BP."/lib/google-api/vendor/autoload.php";
$client = new Google\Client();
$client->setAuthConfig(BP."/scripts/hangout/mytee-products-e6e5368c4246.json");
$client->setApplicationName("Client_Library_Examples");
$client->setScopes(['https://www.googleapis.com/auth/chat.bot']);
try{
$service = new Google_Service_HangoutsChat( $client );
print_r($service->spaces->listSpaces());
}
catch(Exception $e){
print $e->getMessage();
}
{ "error": { "code": 404, "message": "Requested entity was not found.", "errors": [ { "message": "Requested entity was not found.", "domain": "global", "reason": "notFound" } ], "status": "NOT_FOUND" } }
Consideration
Note: A recent commit to the google-api-php-client Github repository updated class names with namespace notation.
You are using namespace notation (Google\Client()) while not activating it beforehand. You should adopt a different notation if you don't intend to use namespaces.
Solution
Please refer to this syntax to use Google_Client PHP Class methods in your PHP script:
include_once __DIR__ . '/path/to/vendor/autoload.php';
$client = new Google_Client();
$client->setAuthConfig(__DIR__."/path/to/credentials.json");
$client->setApplicationName("Your_Application_Name");
$client->setScopes(['https://www.googleapis.com/auth/chat.bot']);
try {
$service = new Google_Service_HangoutsChat( $client );
print_r($service->spaces->listSpaces());
} catch(Exception $e) {
print $e->getMessage();
}
References
PHP Namespaces
Google PHP API Service Account
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
But can i implement face authentication using biometric prompt or any other android api's in my app.
If no, are there any sdk which I can use to implement this feature in my app??
You can use the BiometricPrompt class to create a prompt dialog that just uses any biometric credential the user has initialized (e.g. fingerprint but also face).
You can create a authentication dialog with the following steps:
Step 1: Add dependencies to your build.gradle file in app/
dependencies {
implementation 'androidx.biometric:biometric:1.0.1'
}
Step 2: display the authentication prompt
private Executor executor;
private BiometricPrompt biometricPrompt;
private BiometricPrompt.PromptInfo promptInfo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
executor = ContextCompat.getMainExecutor(this);
biometricPrompt = new BiometricPrompt(MainActivity.this,
executor, new BiometricPrompt.AuthenticationCallback() {
#Override
public void onAuthenticationSucceeded(
#NonNull BiometricPrompt.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
// authenticated
}
#Override
public void onAuthenticationFailed() {
super.onAuthenticationFailed();
// authentication failed
}
});
promptInfo = new BiometricPrompt.PromptInfo.Builder()
.setTitle("Biometric Authentication")
.setSubtitle("Log in with your biometric credentials")
.build();
}
The dialog will be displayed by calling this method:
biometricPrompt.authenticate(promptInfo);
Check the android doc for further information.
In one of our project we starting long time jobs on remote nodes. Those jobs sometimes can take few hours.
We've used old version some application which uses old version of Selenium WebDriver. And it works perfectly many years.
Now we've switched to new version of those application which uses new version of selenium WebDriver. And it stop to work.
I've reviewed all stack trace and see issue in class
org.openqa.selenium.remote.server.WebDriverServlet
When you execute any executor you hardcoded timeout for 10 minutes.
try {
execution.get(10, MINUTES);
} catch (ExecutionException e) {
resp.reset();
JeeInterop.execute(new ExceptionHandler(e), req, resp);
} catch (InterruptedException e) {
logger.log(Level.WARNING, "Unexpectedly interrupted: " + e.getMessage(), e);
invalidateSession = true;
Thread.currentThread().interrupt();
} catch (TimeoutException e) {
invalidateSession = true;
}
This is exactly what I'm seeing in our new application. I trying to set any timeout, but it closed session in 10 minutes.
Could you please explain why you do this?
Seems this is a bug.
Do you know any workaround to make it works?
Sincerely
I have a link which will open in WebView. The problem is it cannot be open until I override onReceivedSslError like this:
#Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed();
}
I am getting security alert from Google Play saying:
Security alert
Your application has an unsafe implementation of the WebViewClient.onReceivedSslError handler. Specifically, the implementation ignores all SSL certificate validation errors, making your app vulnerable to man-in-the-middle attacks. An attacker could change the affected WebView's content, read transmitted data (such as login credentials), and execute code inside the app using JavaScript.
To properly handle SSL certificate validation, change your code to invoke SslErrorHandler.proceed() whenever the certificate presented by the server meets your expectations, and invoke SslErrorHandler.cancel() otherwise. An email alert containing the affected app(s) and class(es) has been sent to your developer account address.
Please address this vulnerability as soon as possible and increment the version number of the upgraded APK. For more information about the SSL error handler, please see our documentation in the Developer Help Center. For other technical questions, you can post to https://www.stackoverflow.com/questions and use the tags “android-security” and “SslErrorHandler.” If you are using a 3rd party library that’s responsible for this, please notify the 3rd party and work with them to address the issue.
To confirm that you've upgraded correctly, upload the updated version to the Developer Console and check back after five hours. If the app hasn't been correctly upgraded, we will display a warning.
Please note, while these specific issues may not affect every app that uses WebView SSL, it's best to stay up to date on all security patches. Apps with vulnerabilities that expose users to risk of compromise may be considered dangerous products in violation of the Content Policy and section 4.4 of the Developer Distribution Agreement.
Please ensure all apps published are compliant with the Developer Distribution Agreement and Content Policy. If you have questions or concerns, please contact our support team through the Google Play Developer Help Center.
If I remove onReceivedSslError (handler.proceed()), then page won't open.
Is there any way I can open the page in WebView and avoid security alert?
To properly handle SSL certificate validation, change your code to
invoke SslErrorHandler.proceed() whenever the certificate presented by
the server meets your expectations, and invoke
SslErrorHandler.cancel() otherwise.
As email said, onReceivedSslError should handle user is going to a page with invalid cert, such like a notify dialog. You should not proceed it directly.
For example, I add an alert dialog to make user have confirmed and seems Google no longer shows warning.
#Override
public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.notification_error_ssl_cert_invalid);
builder.setPositiveButton("continue", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
handler.proceed();
}
});
builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
handler.cancel();
}
});
final AlertDialog dialog = builder.create();
dialog.show();
}
More explain about the email.
Specifically, the implementation ignores all SSL certificate validation
errors, making your app vulnerable to man-in-the-middle attacks.
The email says the default implement ignored an important SSL security problem. So we need to handle it in our own app which used WebView. Notify user with a alert dialog is a simple way.
The proposed solutions so far just bypass the security check, so they are not safe.
What I suggest is to embed the certificate(s) in the App, and when a SslError occurs, check that the server certificate matches one of the embedded certificates.
So here are the steps:
Retrieve the certificate from the website.
Open the site on Safari
Click on the padlock icon near the website name
Click on Show Certificate
Drag and drop the certificate in a folder
see https://www.markbrilman.nl/2012/03/howto-save-a-certificate-via-safari-on-mac/
Copy the certificate (.cer file) into the res/raw folder of your app
In your code, load the certificate(s) by calling loadSSLCertificates()
private static final int[] CERTIFICATES = {
R.raw.my_certificate, // you can put several certificates
};
private ArrayList<SslCertificate> certificates = new ArrayList<>();
private void loadSSLCertificates() {
try {
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
for (int rawId : CERTIFICATES) {
InputStream inputStream = getResources().openRawResource(rawId);
InputStream certificateInput = new BufferedInputStream(inputStream);
try {
Certificate certificate = certificateFactory.generateCertificate(certificateInput);
if (certificate instanceof X509Certificate) {
X509Certificate x509Certificate = (X509Certificate) certificate;
SslCertificate sslCertificate = new SslCertificate(x509Certificate);
certificates.add(sslCertificate);
} else {
Log.w(TAG, "Wrong Certificate format: " + rawId);
}
} catch (CertificateException exception) {
Log.w(TAG, "Cannot read certificate: " + rawId);
} finally {
try {
certificateInput.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (CertificateException e) {
e.printStackTrace();
}
}
When a SslError occurs, check that the server certificate matches one embedded certificate. Note that it is not possible to directly compare certificates, so I use SslCertificate.saveState to put the certificate data into a Bundle, and then I compare all the bundle entries.
webView.setWebViewClient(new WebViewClient() {
#Override
public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
// Checks Embedded certificates
SslCertificate serverCertificate = error.getCertificate();
Bundle serverBundle = SslCertificate.saveState(serverCertificate);
for (SslCertificate appCertificate : certificates) {
if (TextUtils.equals(serverCertificate.toString(), appCertificate.toString())) { // First fast check
Bundle appBundle = SslCertificate.saveState(appCertificate);
Set<String> keySet = appBundle.keySet();
boolean matches = true;
for (String key : keySet) {
Object serverObj = serverBundle.get(key);
Object appObj = appBundle.get(key);
if (serverObj instanceof byte[] && appObj instanceof byte[]) { // key "x509-certificate"
if (!Arrays.equals((byte[]) serverObj, (byte[]) appObj)) {
matches = false;
break;
}
} else if ((serverObj != null) && !serverObj.equals(appObj)) {
matches = false;
break;
}
}
if (matches) {
handler.proceed();
return;
}
}
}
handler.cancel();
String message = "SSL Error " + error.getPrimaryError();
Log.w(TAG, message);
}
});
I needed to check our truststore before show any message to the user so I did this:
public class MyWebViewClient extends WebViewClient {
private static final String TAG = MyWebViewClient.class.getCanonicalName();
Resources resources;
Context context;
public MyWebViewClient(Resources resources, Context context){
this.resources = resources;
this.context = context;
}
#Override
public void onReceivedSslError(WebView v, final SslErrorHandler handler, SslError er){
// first check certificate with our truststore
// if not trusted, show dialog to user
// if trusted, proceed
try {
TrustManagerFactory tmf = TrustManagerUtil.getTrustManagerFactory(resources);
for(TrustManager t: tmf.getTrustManagers()){
if (t instanceof X509TrustManager) {
X509TrustManager trustManager = (X509TrustManager) t;
Bundle bundle = SslCertificate.saveState(er.getCertificate());
X509Certificate x509Certificate;
byte[] bytes = bundle.getByteArray("x509-certificate");
if (bytes == null) {
x509Certificate = null;
} else {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
Certificate cert = certFactory.generateCertificate(new ByteArrayInputStream(bytes));
x509Certificate = (X509Certificate) cert;
}
X509Certificate[] x509Certificates = new X509Certificate[1];
x509Certificates[0] = x509Certificate;
trustManager.checkServerTrusted(x509Certificates, "ECDH_RSA");
}
}
Log.d(TAG, "Certificate from " + er.getUrl() + " is trusted.");
handler.proceed();
}catch(Exception e){
Log.d(TAG, "Failed to access " + er.getUrl() + ". Error: " + er.getPrimaryError());
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
String message = "SSL Certificate error.";
switch (er.getPrimaryError()) {
case SslError.SSL_UNTRUSTED:
message = "O certificado não é confiável.";
break;
case SslError.SSL_EXPIRED:
message = "O certificado expirou.";
break;
case SslError.SSL_IDMISMATCH:
message = "Hostname inválido para o certificado.";
break;
case SslError.SSL_NOTYETVALID:
message = "O certificado é inválido.";
break;
}
message += " Deseja continuar mesmo assim?";
builder.setTitle("Erro");
builder.setMessage(message);
builder.setPositiveButton("Sim", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
handler.proceed();
}
});
builder.setNegativeButton("Não", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
handler.cancel();
}
});
final AlertDialog dialog = builder.create();
dialog.show();
}
}
}
Fix which works for me is just disable onReceivedSslError function defined in AuthorizationWebViewClient. In this case handler.cancel will be called in case of SSL error. However it works good with One Drive SSL certificates. Tested on Android 2.3.7, Android 5.1.
According to Google Security Alert: Unsafe implementation of the interface X509TrustManager, Google Play won't support X509TrustManager from 11th July 2016:
Hello Google Play Developer,
Your app(s) listed at the end of this email use an unsafe
implementation of the interface X509TrustManager. Specifically, the
implementation ignores all SSL certificate validation errors when
establishing an HTTPS connection to a remote host, thereby making your
app vulnerable to man-in-the-middle attacks. An attacker could read
transmitted data (such as login credentials) and even change the data
transmitted on the HTTPS connection. If you have more than 20 affected
apps in your account, please check the Developer Console for a full
list.
To properly handle SSL certificate validation, change your code in the
checkServerTrusted method of your custom X509TrustManager interface to
raise either CertificateException or IllegalArgumentException whenever
the certificate presented by the server does not meet your
expectations. For technical questions, you can post to Stack Overflow
and use the tags “android-security” and “TrustManager.”
Please address this issue as soon as possible and increment the
version number of the upgraded APK. Beginning May 17, 2016, Google
Play will block publishing of any new apps or updates containing the
unsafe implementation of the interface X509TrustManager.
To confirm you’ve made the correct changes, submit the updated version
of your app to the Developer Console and check back after five hours.
If the app hasn’t been correctly upgraded, we will display a warning.
While these specific issues may not affect every app with the
TrustManager implementation, it’s best not to ignore SSL certificate
validation errors. Apps with vulnerabilities that expose users to risk
of compromise may be considered dangerous products in violation of the
Content Policy and section 4.4 of the Developer Distribution
Agreement.
...
I had the same issue and tried all the above-mentioned suggestions as below.
Implement onReceivedSslError() by giving the chance to the user to
decide handler.proceed(); or handler.cancel(); when a SSL error
occurred
Implement onReceivedSslError() to call handler.cancel(); whenever a
SSL issue occurred without considering user's decision.
Implement onReceivedSslError() to verify SSL certificate locally
addition to checking error.getPrimaryError() and providing the user
to decide handler.proceed(); or handler.cancel(); only if the SSL
certificate is valid. If not just call handler.cancel();
Removing the implementation of onReceivedSslError() and just let to
happen Android default behavior.
Even after trying all the above attempts, Google Play was keeping sending the same notification mail mentioning the same error and the old APK version (Even though in the all above attempts we changed both version code and version name in the Gradle)
We were in huge trouble and contacted Google Support via mail and asked
"We are uploading the higher versions of the APK but the review result
says the same error mentioning the old buggy APK version. What's the
reason for that ?"
After a few days, google support replied to our request as follows.
Please note that you must completely replace version 12 in your
Production track. It means that you'll have to full rollout a higher
version in order to deactivate version 12.
The highlighted point was never found or mentioned in the play console or any forum.
According to that guideline in the classic Google play view, we checked the production track and there were both buggy versions and the latest bug fixed version but the bug fix version's rollout percentage is 20%. So, turned it to full rollout then the buggy version disappeared from the production track. After more than 24 hour review time version has come back.
NOTE: When we had this issue Google has just moved to a new UI version of their play console and it had missed some views in the previous UI version or classic view. Since we were using the latest view we couldn't notice what was happening. Simply what happened was Google reviewed the same previous buggy version of the APK since the new one was not full roll-out.
You can use SslError for show, some information about the error of this certificated, and you can write in your dialog the string of the type error.
#Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
final SslErrorHandler handlerFinal;
handlerFinal = handler;
int mensaje ;
switch(error.getPrimaryError()) {
case SslError.SSL_DATE_INVALID:
mensaje = R.string.notification_error_ssl_date_invalid;
break;
case SslError.SSL_EXPIRED:
mensaje = R.string.notification_error_ssl_expired;
break;
case SslError.SSL_IDMISMATCH:
mensaje = R.string.notification_error_ssl_idmismatch;
break;
case SslError.SSL_INVALID:
mensaje = R.string.notification_error_ssl_invalid;
break;
case SslError.SSL_NOTYETVALID:
mensaje = R.string.notification_error_ssl_not_yet_valid;
break;
case SslError.SSL_UNTRUSTED:
mensaje = R.string.notification_error_ssl_untrusted;
break;
default:
mensaje = R.string.notification_error_ssl_cert_invalid;
}
AppLogger.e("OnReceivedSslError handel.proceed()");
View.OnClickListener acept = new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
handlerFinal.proceed();
}
};
View.OnClickListener cancel = new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
handlerFinal.cancel();
}
};
View.OnClickListener listeners[] = {cancel, acept};
dialog = UiUtils.showDialog2Buttons(activity, R.string.info, mensaje, R.string.popup_custom_cancelar, R.string.popup_custom_cancelar, listeners); }
In my situation:This error occured when we try to updated apk uploaded
into the Google Play store,and getting SSL Error:
Then i have used following code
private class MyWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
#Override
public void onPageFinished(WebView view, String url) {
try {
progressDialog.dismiss();
} catch (WindowManager.BadTokenException e) {
e.printStackTrace();
}
super.onPageFinished(view, url);
}
#Override
public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
final AlertDialog.Builder builder = new AlertDialog.Builder(PayNPayWebActivity.this);
builder.setMessage(R.string.notification_error_ssl_cert_invalid);
builder.setPositiveButton("continue", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
handler.proceed();
}
});
builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
handler.cancel();
}
});
final AlertDialog dialog = builder.create();
dialog.show();
}
}
This question already has answers here:
Servlet returns "HTTP Status 404 The requested resource (/servlet) is not available"
(19 answers)
Closed 6 years ago.
I've been struggling with a servlet in the maven web application for hours. I'm not able to run it. It always returns The requested resource is not available. I'm using Tomcat 8. This is my servlet code. I'm using this address http://localhost:8080/my-app/MyServlet to run it but I'm not successful.
#WebServlet(name = "MyServlet", urlPatterns = {"/MyServlet"})
public class MyServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
/* TODO output your page here. You may use following sample code. */
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet MyServlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Servlet MyServlet at " + request.getContextPath() + "</h1>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}
}
Check if your tomcat works fine by using http://localhost:8080 (Tomcat welcome page is shown )
Check if your context path is "/my-app", "/" or something else. e.g. if you context path is just /, http://localhost:8080/MyServlet should work.