Error finding UserKey with Google Directory Admin API - java

I have some code to retrieve, delete, and update, and create google users. I can create the user with no problem using:
public void createUser(String id, String firstName, String lastName, String email, String password){
User user = new User();
try{
UserName name = new UserName();
name.setFamilyName(lastName);
name.setGivenName(firstName);
user.setName(name);
user.setPassword(password);
user.setPrimaryEmail(email);
user.setId(id);
System.out.println(service.users().insert(user).execute());
}
catch(Exception e){
System.out.println("Error creating user: " + e);
}
I can also retrieve the userKey with:
System.out.println("UserKey: " + service.users().get(id).getUserKey());
But when I try to update or delete the user with the id, I get the following error:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 404 Not Found
{
"code" : 404,
"errors" : [ {
"domain" : "global",
"message" : "Resource Not Found: userKey",
"reason" : "notFound"
} ],
"message" : "Resource Not Found: userKey"
}
My delete method looks like:
public void deleteUser(String id){
try{
System.out.println(service.users().delete(id).execute());
}
catch(Exception e){
System.out.println("Error deleting user: " + e);
}
}
If I pass the delete or update methods the email address (id#domain.edu), it finds the account and works correctly, but I need to be able to pass just the id I created the account with in the insert method. Any ideas?

When calling Directory API, you must always specify the full email address of the user or else the Google unique id of the user. It's not sufficient to simply provide the local part of the username as this does not allow Google to determine which Google Apps domain the user is associated with.

Related

Trying to add password to Firebase RealTime Database, but it doesn't show up?

So I know Firebase Auth exists, but this is for a school project where I have to implement my own hash for the passwords.
I'm registering users to the Realtime Database, it gets added in the correct format, but "password" doesn't show up. Is there a way to make it show up?
Heres some example code
public void registerUser (String name, String email, String password)
{
Intent toWelcome = new Intent(this, Welcome.class);
String id = mDatabase.push().getKey();
if (type.equals("Admin")) {
Person user = new Admin(id, email, password, name);
mDatabase.child("Person").child("Admin").child(id).setValue(user);
Toast.makeText(Register.this, "Admin account already created.", Toast.LENGTH_LONG).show();
}
else if (type.equals("Patient"))
{
Person user = new Patient(id, email, password, name);
mDatabase.child("Person").child("Patient").child(id).setValue(user);
}
else if (type.equals("Employee"))
{
Person user = new Employee(id, email, password, name);
mDatabase.child("Person").child("Employee").child(id).setValue(user);
}
toWelcome.putExtra("name", name);
toWelcome.putExtra("role", type);
startActivity(toWelcome);
}
Here is what shows up in my database:
Any ideas?
Are you certain it is supposed to show you the passwords? Servers are normally very reluctant to display such things even to admins. It may be a security feature. As an admin, you can reset a password, but not necessarily be able to see a password. You did mention it was a RealTime Database.

Using RestFB along side a JavaFX WebView, how can I post to Facebook?

I've been trying a number of ways to achieve a way to post to Facebook from within my JavaFX application using a WebView to manage login.
I have read Facebook's documentation but continue to get lost with user_key, codes, access_code, tokens and what not.
What I have so far is this:
My WebView loads this URL.
public static String userLogin() {
String state = UUID.randomUUID().toString();
return String.format(AUTHORIZATION_URL, CLIENT_ID, REDIRECT_URI, state);
}
User logs in and authorises my Facebook application and I capture the response
System.out.println("Response: " + response);
if (response.contains("code=")) {
String[] finalCode = response.split("code=");
Facebook.CODE = finalCode[1];
System.out.println("Access Key:" + finalCode[1]);
}
}
My webview displays the following:
SECURITY WARNING: Please treat the URL above as you would your password and do not share it with anyone. See the Facebook Help Centre for more information.
I also see my code returned:
https://www.facebook.com/connect/login_success.html?code=AQA4w...
I then try to get my User Token, by directing my webView here:
public static String getUserToken() {
return String.format(ACCESS_TOKEN_URL, CLIENT_ID, REDIRECT_URI, CLIENT_SECRET, CODE);
}
At which point my webview displays the following:
{
"error": {
"message": "Missing authorization code",
"type": "OAuthException",
"code": 1,
"fbtrace_id": "D/0gXWRYkx4"
}
}
How can I solve this?

GCP - App Engine Endpoints - Performance ISSUE

Do you guys use the Google Cloud Platform, specifically the APP ENGINE ENDPOINTs for professional/production purposes? Asking because I am not comfortable with response time. It´s taking too long to perform simple http POST requests like registering an users with only e-mail and password (saving in a DATASTORE). In this URL you will find the register form, let me know what you guys thing about the response time, is it acceptable?
https://filiperebollo1986.appspot.com/register.html
My Java code is quite simple. Only instantiate an user object with email and password which does´t have any special encrypting algorithm. Naturally for the registering purpose I need to check if the user already exists and after that save the object in the DATASTORE. I can ensure that the problem is not in my front-end apps because takes too long in the iOS e Android apps too.
POST:
https://filiperebollo1986.appspot.com/_ah/api/igardenendpoints/v12/saveProfile.
{
"userEmail": "response_time",
"password": "123"
}
Response:
200
Show headers
{
"messageText": "User successfully created!",
"messageNumer": 0,
"kind": "igardenendpoints#resourcesItem",
"etag": "\"9e-bXvBAIkMzDxg9PvVcUBMIXB0/_RzWmXdehTtOTMg1Y7MhIvXy5-k\""
}
public Message saveProfile(ProfileForm profileForm) {
Message message;
String userEmail = profileForm.getUserEmail();
String password = profileForm.getPassword();
String displayName = profileForm.getDisplayName();
Profile profile = ofy().load().key(Key.create(Profile.class, profileForm.getUserEmail())).now();
if (profile == null) {
if (displayName == "") {
displayName = extractDefaultDisplayNameFromEmail(profileForm.getUserEmail());
}
profile = new Profile(userEmail, password, displayName);
message = new Message("User successfully created!", 0);
} else {
message = new Message("User already exists!", 1);
}
ofy().save().entity(profile).now();
return message;
}

JDOObjectNotFoundException when retrieving data from datastore in Android application

I am creating an android application with an app engine back end. I used the google app engine plugin to create an android connected app. Here is my entity.
#PersistenceCapable(identityType = IdentityType.APPLICATION)
public class User {
#PrimaryKey
#Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
Long id;
#Persistent
String email;
#Persistent
String password;
I used the plugin to generate my endpoint. To test it, I run the app engine as a web application and I can use every method successfully. I navigate to
http://localhost:8888/_ah/admin/datastore
and I can see the records that I entered. To be sure the generated getUser method works I go to the API explorer and retrieve user with id = 1 and I get
{
"id": "1",
"email": "this#that.com",
"password": "1234"
}
So I know it works. In my android app I connect to the endpoint like this:
User user = new User();
Userendpoint.Builder endpointBuilder = new Userendpoint.Builder(AndroidHttp.newCompatibleTransport(), new JacksonFactory(), new HttpRequestInitializer() {
public void initialize(HttpRequest httpRequest) {
}
});
Userendpoint endpoint = CloudEndpointUtils.updateBuilder(endpointBuilder).build();
try {
User result = endpoint.getUser(1L).execute();
} catch (IOException e) {
e.printStackTrace();
}
And I get the following error
com.google.api.client.googleapis.json.GoogleJsonResponseException: 503 Service Unavailable
{
"code" : 503,
"errors" : [ {
"domain" : "global",
"message" : "javax.jdo.JDOObjectNotFoundException: Could not retrieve entity of kind User with key User(1)\nNestedThrowables:\norg.datanucleus.exceptions.NucleusObjectNotFoundException: Could not retrieve entity of kind User with key User(1)",
"reason" : "backendError"
} ],
Any advice or ideas would be greatly appreciated!
The error was that I was connecting to the development server from my laptop, but I was connecting to the production server on my device.
Change
// For development server
protected static final String LOCAL_APP_ENGINE_SERVER_URL_FOR_ANDROID = "http://<Your IP>:<your port>/_ah/api";
// For production server
protected static final String LOCAL_APP_ENGINE_SERVER_URL_FOR_ANDROID = "https://<your version>-<your project ID>.appspot.com/_ah/api/";

How to correctly obtain user's Calendar events using service account?

I'm trying to retrive Calendar events for a user in a domain. I have service account access, but i get 404 error when I try to get specific user events.
Heres connection code:
NetHttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(googleApiServiceAccountId)
.setServiceAccountScopes(Collections.singleton(CalendarScopes.CALENDAR_READONLY))
.setServiceAccountPrivateKey(SecurityUtils.loadPrivateKeyFromKeyStore(
SecurityUtils.getPkcs12KeyStore(),
getClass().getClassLoader().getResourceAsStream(googleApiPrivateKeyPath),
NOTASECRET, PRIVATEKEY, NOTASECRET))
.build();
calendarApi = new Calendar.Builder(httpTransport,
JSON_FACTORY, credential).setApplicationName(getApplicactionName()).build();
Events listing method:
public List<Event> getCalendarEventsForUserAndDates(String userEmail, Long dateFrom, Long dateTo) {
try {
String pageToken = null;
List<Event> allEvents = Lists.newArrayList();
do {
ArrayMap<String, Object> parameters = new ArrayMap<String, Object>();
parameters.add("xoauth_requestor_id", userEmail);
Calendar.Events.List list = calendarApiBean.getCalendarApi()
.events().list("primary");
list.setTimeMax(new DateTime(dateFrom, 0))
.setTimeMin(new DateTime(dateTo, 0))
.setUnknownKeys(parameters);
Events events = list.setPageToken(pageToken)
.execute();
List<? extends Event> items = events.getItems();
if (items != null) {
allEvents.addAll(items);
}
pageToken = events.getNextPageToken();
} while (pageToken != null);
return allEvents;
} catch (IOException e) {
logger.error("error while retriving calendar events for {} and dates {} {} ", userEmail, dateFrom, dateTo);
logger.error("exception", e);
return Collections.emptyList();
}
}
When i try to set xoauth_requestor_id to user's email and list 'primary', i get Calendar events for my Service Accounts. When I change events().list() parameter to user's email I get an following Error:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 404 Not Found
{
"code" : 404,
"errors" : [ {
"domain" : "global",
"message" : "Not Found",
"reason" : "notFound"
} ],
"message" : "Not Found"
}
Thanks for any help.
To solved this problem I had to add this service account to authorized API clients on Domain Administration.
Client name is Service Account Client ID and scope was for Readonly Calendar
This consists of two different parts
Creating a service account
Giving it permissions to access the scopes you need
Create the service account:
Go to the cloud page to administer your Service Accounts:
Menu on the left side -> IAM & admin -> Service accounts. Or click on this link: https://console.cloud.google.com/iam-admin/serviceaccounts
Make sure you are logged in as the user you want to use, and check that the organization is correctly selected
Create a new service account with Project Viewer role (you can change this later), and download the .json file with the credentials when you click to create a key.
Edit the service account and enable G Suite Domain-wide Delegation
Take note of the Client ID. (NOT the Key ID)
Give it permissions:
Go to admin.google.com
Make sure you are logged in as the user with admin rights.
Then go to Security -> Settings -> Advanced settings -> Manage API client access
In client name fill in the Client ID you copied above (NOT the Key id)
Fill in the scopes you need and authorize the service account. ie:
https://www.googleapis.com/auth/calendar.readonly,https://www.googleapis.com/auth/gmail.readonly
I tested the Python samples I link in the sources, and can confirm this works as expected.
Sources:
https://developers.google.com/identity/protocols/OAuth2ServiceAccount
https://support.google.com/a/answer/162106?hl=en

Categories