Could not find appSecret for push notification services on IBM bluemix cloud - ibm-mobilefirst

I would like to use a PushNotinfication service via Java application so that I need appGuid and appSecret of the service. (The figure attached to this message shows the window that appSecret is supposed to be shown but it didn't.) enter image description hereSome documents say that appSecret is automatically generated when an application is bound to the service but I cannot understand about the binding process.
So I would like to know the process to issue appSecret of the PushNotification Service as detail as possible. I would appreciate if someone could explain with the screen shot of the window of each process.

#ken We support both AppSecret and Tokens in the swagger(http://imfpush.ng.bluemix.net/imfpush/). For new instances created there would not be any AppSecret as these are IAM based instances. And there is no way other than the Token way of authentication.
Those instances created before June 2018 will work with Appsecret. But the new instances will work only with IAM token. This is introduced for better security. Please refer to our release notes for the same https://console.bluemix.net/docs/services/mobilepush/release-notes.html#release-notes.
To know more on the IAM implementation on the Push Notification service please refer to https://console.bluemix.net/docs/services/mobilepush/push_iam.html#service-access-management
Refer to the question 21 in our FAQ section https://console.bluemix.net/docs/services/mobilepush/push_faq.html#faq to know how to retrieve the token and use.
Regarding the Swagger a new Authorization field is introduced to submit the IAM token. Either the Authorization field or the appSecret is mandatory.
Please refer to the server sdk (https://github.com/ibm-bluemix-mobile-services/bms-pushnotifications-serversdk-java) readme file where customer has to Initialize Push with ApiKey for the new push instance that IAM token is automatically generated by initialization method..
PushNotifications.initWithApiKey("YOUR_APPLICATION_ID", "YOUR-BLUEMIX-PUSH-APIKEY", PushNotifications.US_SOUTH_REGION);
Sample
public static void main(String[] args) {
PushNotifications.initWithApiKey("appId", "APIKey", PushNotifications.US_SOUTH_REGION);
Message message = new Message.Builder().alert("20% Off Offer for you").url("www.ibm.com").build();
String [] deviceIds = {"deviceIds"};
Target target = new Target.Builder().deviceIds(deviceIds).build();
Notification notification = new Notification.Builder().message(message).target(target).build();
PushNotifications.send(notification, new PushNotificationsResponseListener(){
public void onSuccess(int statusCode, String responseBody) {
System.out.println(responseBody);
System.out.println("Successfully sent push notification! Status code: " + statusCode + " Response body: " + responseBody);
}
public void onFailure(Integer statusCode, String responseBody, Throwable t) {
System.out.println("Failed sent push notification. Status code: " + statusCode + " Response body: " + responseBody);
if(t != null){
t.printStackTrace();
}
}
});
}
Hope this helps.

Related

How to use YouTube Data API

I tried using YouTube Data API.
I really took a good look at everything I found on the internet. The code itself isn't the problem, but I did not find out, where to use this code. Do I simply create a python file (in Visual Studio Code for example) and run it there? Because it didn't work when I tried this...
I also saw many people using the API with the commander only, others used something in chrome (localhost:8888...). So I don`t really know what's the way to go or what I should do.
Thanks for any help :)
Best regards!
I'm not a python developer but as a guess you could start here:
https://developers.google.com/youtube/v3/quickstart/python
using pip to install the dependencies you need.
You should be able to create a simple python file that authenticates with the API and then calls a method on the on the google api client and then output it. There are some examples here:
https://github.com/youtube/api-samples/blob/master/python/
using System;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Upload;
using Google.Apis.Util.Store;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;
namespace Google.Apis.YouTube.Samples
{
/// <summary>
/// YouTube Data API v3 sample: upload a video.
/// Relies on the Google APIs Client Library for .NET, v1.7.0 or higher.
/// See https://code.google.com/p/google-api-dotnet-client/wiki/GettingStarted
/// </summary>
internal class UploadVideo
{
[STAThread]
static void Main(string[] args)
{
Console.WriteLine("YouTube Data API: Upload Video");
Console.WriteLine("==============================");
try
{
new UploadVideo().Run().Wait();
}
catch (AggregateException ex)
{
foreach (var e in ex.InnerExceptions)
{
Console.WriteLine("Error: " + e.Message);
}
}
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
private async Task Run()
{
UserCredential credential;
using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
// This OAuth 2.0 access scope allows an application to upload files to the
// authenticated user's YouTube channel, but doesn't allow other types of access.
new[] { YouTubeService.Scope.YoutubeUpload },
"user",
CancellationToken.None
);
}
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = Assembly.GetExecutingAssembly().GetName().Name
});
var video = new Video();
video.Snippet = new VideoSnippet();
video.Snippet.Title = "Default Video Title";
video.Snippet.Description = "Default Video Description";
video.Snippet.Tags = new string[] { "tag1", "tag2" };
video.Snippet.CategoryId = "22"; // See https://developers.google.com/youtube/v3/docs/videoCategories/list
video.Status = new VideoStatus();
video.Status.PrivacyStatus = "unlisted"; // or "private" or "public"
var filePath = #"REPLACE_ME.mp4"; // Replace with path to actual movie file.
using (var fileStream = new FileStream(filePath, FileMode.Open))
{
var videosInsertRequest = youtubeService.Videos.Insert(video, "snippet,status", fileStream, "video/*");
videosInsertRequest.ProgressChanged += videosInsertRequest_ProgressChanged;
videosInsertRequest.ResponseReceived += videosInsertRequest_ResponseReceived;
await videosInsertRequest.UploadAsync();
}
}
void videosInsertRequest_ProgressChanged(Google.Apis.Upload.IUploadProgress progress)
{
switch (progress.Status)
{
case UploadStatus.Uploading:
Console.WriteLine("{0} bytes sent.", progress.BytesSent);
break;
case UploadStatus.Failed:
Console.WriteLine("An error prevented the upload from completing.\n{0}", progress.Exception);
break;
}
}
void videosInsertRequest_ResponseReceived(Video video)
{
Console.WriteLine("Video id '{0}' was successfully uploaded.", video.Id);
}
}
}
Make sure you have python installed on your PC
Create a project: Google’s APIs and Services dashboard
Enable the Youtube v3 API: API Library
Create credentials: Credentials wizard
Now you need to get an access token and a refresh token using the credentials you created
Find an authentication example in one of the following libraries:
https://github.com/googleapis/google-api-python-client
https://github.com/omarryhan/aiogoogle (for the async version)
Copy and paste the client ID and client secret you got from step 4 and paste them in the authentication example you found in step 6 (Should search for an OAuth2 example), this step should provide with an access token and a refresh token
Copy and paste a Youtube example from either:
https://github.com/googleapis/google-api-python-client
https://github.com/omarryhan/aiogoogle (for the async version)
Replace the access token and refresh token fields with the ones you got.
Now you should be able to run the file from any terminal by typing:
python3 yourfile.py
[EDIT]
The API key is not the same as the access token. There are 2 main ways to authenticate with Google APIs:
Access and refresh token
API_KEY.
API key won't work with personal info. You need to get an access and refresh token for that (method 1).
Once you get an access token, it acts in a similar fashion to the API_KEY you got. Getting an access token is a bit more complicated than only working with an API_KEY.
A refresh token is a token you get with the access token upon authentication. Access tokens expire after 3600 seconds. When they expire, your authentication library asks Google's servers for a new access token with the refresh token. The refresh token has a very long lifetime (often indefinite), so make sure you store it securely.
To get an access token and a refresh token (user credentials), you must first create client credentials. Which should consists of 1. a client ID and 2. a client secret. These are just normal strings.
You should also, set a redirect URL in your Google app console in order to properly perform the OAuth2 flow. The OAuth2 flow is the authentication protocol that many APIs rely on to allow them to act on a user's account with the consent of the user. (e.g. when an app asks you to post on your behalf or control your account on your behalf, it typically will use this protocol.)
Aiogoogle's docs does a decent job in explaining the authentication flow(s) available by Google.
https://aiogoogle.readthedocs.io/en/latest/
But this is an async Python library. If you're not familiar with the async syntax, you can read the docs just to get a general idea of how the authentication system works and then apply it to Google's sync Python library.
About point no.6. The links I posted with Aiogoogle being one of them, are just client libraries that help you access Google's API quicker and with less boilerplate. Both libraries have documentation, where they have links to examples on how to use them. So, open the documentation, read it, search for the examples posted, try to understand how the code in the example(s) work. Then maybe download it and run it on your own machine.
I recommend that your read the docs. Hope that helps.

Android Google Sign-In

I need to enable server-side access to Google Drive. In this case a person is using his Android device. As far as I understood the steps are as follows:
1. Create GoogleSignInOptions
2. Using the GoogleSignInOptions create GoogleSignInAccount
3. Getting authCode from GoogleSignInAccount
4. Exchange the authCode for access/refresh/ID tokens
I am stuck on step 3. I followed the well-described tutorials without any success - https://developers.google.com/identity/sign-in/android/offline-access, https://developers.google.com/identity/sign-in/android/sign-in#configure_google_sign-in_and_the_googleapiclient_object
Here is the code that initialize sign-in process:
final GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestScopes(new Scope(Scopes.DRIVE_APPFOLDER))
.requestServerAuthCode(backend_server_web_client_id)
.build();
GoogleSignInClient google_api_client = GoogleSignIn.getClient(context, gso);
activity.startActivityForResult(google_api_client.getSignInIntent(), RC_SIGN_IN);
Here is the code that handles the sign-in result:
// data is the intent from onActivityResult callback
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
if (task.isComplete())
handle(task);
else {
task.addOnCompleteListener(new OnCompleteListener<GoogleSignInAccount>() {
#Override
public void onComplete(#NonNull Task<GoogleSignInAccount> task) {
handle(task);
}}
});
}
And finally here is the handle function where is the problem:
public void handle(Task<GoogleSignInAccount> task) {
try {
GoogleSignInAccount account = task.getResult(ApiException.class);
} catch (ApiException e) {
//I'm always getting this exception with status code 10, which means DEVELOPER ERROR. Keys in Google API console are checked multiple times.
}
}
In handle function I'm always getting an exception with status code 10, which means DEVELOPER_ERROR. Keys in Google API console are checked multiple times. Code was rewritten few times.... I really have no idea what could be wrong.
Thank you :)
You might have forgotten to configure Google API Console. Follow the instructions:
https://developers.google.com/identity/sign-in/android/start-integrating
You see to create OAuth client ID for Android with corresponding package name and signing certificate's SHA1. You do NOT have to enter this key anywhere in the code. It just have to exist in Google API Console.

Implement Authentication for servlet on publish instance CQ5/AEM

I have a scenario and any suggestions in implementing that will be of great help. I have a servlet created on publish that will have POST requests coming from a lot of other third party applications. This servlet just stores the incoming posted data in JCR. I have successfully created this servlet but now the requirement is to make this servlet secured so that only applications hitting this servlet with particular username and password should be entertained.
What can I do to achieve this?
The way I would go for it:
Ask those 3rd party applications to send you the username and password so you can validate them on your servlet, then decide if you will allow or reject the request.
from the servlet calling (the 3rd party application)
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// ...
request.setAttribute("username", "a_valid_user");
request.setAttribute("password", "a_valid_password");
request.getRequestDispatcher("yourApp/YourServlet").forward(req, resp);
}
On your servlet:
String username = request.getParameter("username");
String password = request.getParameter("password");
if("a_valid_user".equals(username) && "a_valid_password".equals(password) {
// validate and go further
} else {
// do not process the request
}
The above example is valid just in case you can validate them on your side.
If this sample doesn't answer to your question, please provide more information about those 3rd party applications and the way you want to validate them.
You might consider using Google Client Library. I used it for authentication of users in an AEM publish instance. After the third party server is authenticated, you could use a separate AEM service account to handle POST processing.
Here' a SO post I made about integrating those libraries into AEM.
Google Client API in OSGI
With this you should be able set up authentication of the third party service account... as discussed here
https://developers.google.com/identity/protocols/OAuth2ServiceAccount
I haven't actually done server to server auth in AEM, but it should be possible. But in a separate project (non AEM) I've used the Google Client Library for authenticating Service Accounts.
I recommend to use a two step process:
Step 1: Authentication and generate a token, you can use 3rd party service also to generate token.
Step 2: Call your servlet with this token, the servlet will validate token first and then use post data.
Thanks everyone for your replies. In the end I implemented the below code for authentication in cq :
final String authorization = request.getHeader("Authorization");
if (authorization != null && authorization.startsWith("Basic")) {
StringTokenizer st = new StringTokenizer(authorization);
if (st.hasMoreTokens()) {
String basic = st.nextToken();
if (basic.equalsIgnoreCase("Basic")) {
String decodedStr = Base64.decode(st.nextToken());
LOGGER.info("Credentials: " + decodedStr);
int p = decodedStr.indexOf(":");
if (p != -1) {
String login = decodedStr.substring(0, p).trim();
String password = decodedStr.substring(p + 1).trim();
Credentials credentials = new SimpleCredentials(login, password.toCharArray());
adminSession = repository.login(credentials);
if (null != adminSession) {
// means authenticated and do your stuff here
}
}
}
}
}
Also in the webservice code which is calling the servlet of publish, below is the code on how I am supplying the credentials in auth headers :
String authStr = usrname+":"+password;
// encode data on your side using BASE64
byte[] bytesEncoded = Base64.encodeBase64(authStr.getBytes());
String authEncoded = new String(bytesEncoded);
connection.setRequestProperty("Authorization", "Basic "+authEncoded);
connection.setDoOutput(true);
connection.setRequestMethod("POST");
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
writer.write("jsondata={sample:jsoncontent}");
writer.close();

Integrating STS with AWSS3TransferManagerUploadRequest and AWSS3TransferManagerDownloadRequest

We are trying to implement AWS Security Token Service in our android and iOS app. At backend we are using below code to generate token:
public class CloudManagementImpl implements CloudManagement{
private static final Logger Log = LoggerFactory.getLogger(CloudManagementImpl.class);
#Override
public CloudConfiguration getCloudProperties() {
CloudConfiguration CloudConfiguration = new CloudConfiguration();
AssumeRoleRequest assumeRoleRequest = new AssumeRoleRequest();
assumeRoleRequest.setRoleArn(JiveGlobals.getProperty(XYZConstant.AWS_ARN_EC2_ROLE_MAP));
assumeRoleRequest.setRoleSessionName(XYZConstant.AWS_ROLE_SESSIONNAME);
assumeRoleRequest.setDurationSeconds(JiveGlobals.getIntProperty(XYZConstant.AWS_CREDENTIALS_LIFETIME, 1800));
AWSSecurityTokenServiceClient stsClient = new AWSSecurityTokenServiceClient();
AssumeRoleResult assumeRoleResult = stsClient.assumeRole(assumeRoleRequest);
if (assumeRoleResult != null) {
Credentials sessionCredentials = assumeRoleResult.getCredentials();
CloudConfiguration.setAwsAccessId(sessionCredentials.getAccessKeyId());
CloudConfiguration.setAwsAccessKey(sessionCredentials.getSecretAccessKey());
CloudConfiguration.setToken(sessionCredentials.getSessionToken());
CloudConfiguration.setAwsMainBucket(JiveGlobals.getProperty(XYZConstant.AWS_MAIN_BUCKET));
} else {
Log.error("Cloud Management :: Propery values not configured ");
}
return CloudConfiguration;
}
}
Generated token is then obtained in iOS and android app through a separate web-service call.
In android we are using below code to consume retrieved token:
public S3Client(String accessKey, String secretKey, String token, String bucketName) {
super();
this.accessKey = accessKey;
this.secretKey = secretKey;
this.bucketName = bucketName;
BasicSessionCredentials basicSessionCredentials = new BasicSessionCredentials(accessKey, secretKey, token);
amazonS3Client = new AmazonS3Client(basicSessionCredentials);
}
Problem is -
We do not have android like API in AWS mobile SDK version 2 for iOS,
using which we can consume the retrieved token, perhaps the best way
to achieve this thing in iOS is through AWSCognitoCredentialsProvider,
but we are not sure.
Please suggest - what is the best way to integrate AWS Security Token Service in iOS.
You need to implement your own credentials provider by conforming to AWSCredentialsProvider. Sounds like you already have a code snippet that retrieves the temporary credentials from your server. That logic should go into your custom credentials provider. You can take a look at the implementation of AWSWebIdentityCredentialsProvider and AWSCognitoCredentialsProvider for how to implement your own credentials provider.

ArgumentException: Precondition failed.: !string.IsNullOrEmpty(authorization.RefreshToken) with Service Account for Google Admin SDK Directory access

I'm trying to access the Google Directory using a Service Account. I've fiddled with the DriveService example to get this code:
public static void Main(string[] args)
{
var service = BuildDirectoryService();
var results = service.Orgunits.List(customerID).Execute();
Console.WriteLine("OrgUnits");
foreach (var orgUnit in results.OrganizationUnits)
{
Console.WriteLine(orgUnit.Name);
}
Console.ReadKey();
}
static DirectoryService BuildDirectoryService()
{
X509Certificate2 certificate = new X509Certificate2(SERVICE_ACCOUNT_PKCS12_FILE_PATH, "notasecret",
X509KeyStorageFlags.Exportable);
var provider = new AssertionFlowClient(GoogleAuthenticationServer.Description, certificate)
{
ServiceAccountId = SERVICE_ACCOUNT_EMAIL,
Scope = DirectoryService.Scopes.AdminDirectoryOrgunit.GetStringValue()
};
var auth = new OAuth2Authenticator<AssertionFlowClient>(provider, AssertionFlowClient.GetState);
return new DirectoryService(new BaseClientService.Initializer()
{
Authenticator = auth,
ApplicationName = "TestProject1",
});
}
When I run it, I get
ArgumentException: Precondition failed.: !string.IsNullOrEmpty(authorization.RefreshToken)
I'm going round in circles in the Google documentation. The only stuff I can find about RefreshTokens seems to be for when an individual is authorizing the app and the app may need to work offline. Can anyone help out or point me in the direction of the documentation that will, please.
Service Account authorization actually do not return Refresh Token - so this error makes sense. Do you know where this is coming from?
I am not too familiar with the .NET client library but having the full error trace would help.
As a longshot - The error might be a bad error -
Can you confirm that you've enabled the Admin SDK in the APIs console for this project
Can you confirm that you whitelisted that Client ID for the service account in the domain you are testing with (along with the Admin SDK scopes)
The above code will work if you replace the provider block with:
var provider = new AssertionFlowClient(GoogleAuthenticationServer.Description, certificate)
{
ServiceAccountId = SERVICE_ACCOUNT_EMAIL,
Scope = DirectoryService.Scopes.AdminDirectoryOrgunit.GetStringValue(),
ServiceAccountUser = SERVICE_ACCOUNT_USER //"my.admin.account#my.domain.com"
};
I had seen this in another post and tried it with my standard user account and it didn't work. Then I read something that suggested everything had to be done with an admin account. So, I created a whole new project, using my admin account, including creating a new service account, and authorising it. When I tried it, it worked. So, then I put the old service account details back in but left the admin account in. That worked, too.