so I'm trying to use this library library
to access my Spotify account but i can't figure out how i can get an acces token but i can't figure out how i can get the response from the authorization URL I have trayed creating a input stream that access the url and print out the response but i dos not give the right output i have also trayed creating a server with shut receive the response but I'm getting nothing i have never used java server / networking that much so i might have made an error....
public class privat {
public privat() throws IOException {
final String clientId = "clientId ";
final String clientSecret = "clientSecret code ";
final String redirectUri = "http://localhost:8888/callback";
final Api api = Api.builder()
.clientId(clientId)
.clientSecret(clientSecret)
.redirectURI(redirectUri)
.build();
/* Set the necessary scopes that the application will need from the user */
final List<String> scopes = Arrays.asList("user-read-private", "user-read-email");
/* Set a state. This is used to prevent cross site request forgeries. */
final String state = "someExpectedStateString";
String authorizeURL = api.createAuthorizeURL(scopes, state);
System.out.println(authorizeURL);
/* Continue by sending the user to the authorizeURL, which will look something like
https://accounts.spotify.com:443/authorize?client_id=5fe01282e44241328a84e7c5cc169165&response_type=code&redirect_uri=https://example.com/callback&scope=user-read-private%20user-read-email&state=some-state-of-my-choice
*/
/* Application details necessary to get an access token */
final String code = "" ;/* where to find this ?? */
/* Make a token request. Asynchronous requests are made with the .getAsync method and synchronous requests
* are made with the .get method. This holds for all type of requests. */
final SettableFuture<AuthorizationCodeCredentials> authorizationCodeCredentialsFuture = api.authorizationCodeGrant(code).build().getAsync();
/* Add callbacks to handle success and failure */
Futures.addCallback(authorizationCodeCredentialsFuture, new FutureCallback<AuthorizationCodeCredentials>() {
#Override
public void onSuccess(AuthorizationCodeCredentials authorizationCodeCredentials) {
/* The tokens were retrieved successfully! */
System.out.println("Successfully retrieved an access token! " + authorizationCodeCredentials.getAccessToken());
System.out.println("The access token expires in " + authorizationCodeCredentials.getExpiresIn() + " seconds");
System.out.println("Luckily, I can refresh it using this refresh token! " + authorizationCodeCredentials.getRefreshToken());
/* Set the access token and refresh token so that they are used whenever needed */
api.setAccessToken(authorizationCodeCredentials.getAccessToken());
api.setRefreshToken(authorizationCodeCredentials.getRefreshToken());
}
#Override
public void onFailure(Throwable throwable) {
/* Let's say that the client id is invalid, or the code has been used more than once,
* the request will fail. Why it fails is written in the throwable's message. */
System.out.println(throwable.getMessage());
System.out.println(throwable.getStackTrace());
}
});
}
}
The code comes as a query parameter to your callback URL once the user authorises your application. You'll need to find a way to grab it from there - you could spin up a web server on localhost:8888 to get the code from there - or you could instruct the user to copy the code from the query parameters of the redirect URI once they're redirected. You can find more information about the authorisation procedure (looks like either the authorization code or implicit grant flows will work for you) on the Spotify Developer site.
Related
I can create a ProjectApiRoot using the Java SDK and perform requests with that using the following code:
private static ProjectApiRoot createProjectClient() {
ProjectApiRoot apiRoot = ApiRootBuilder.of()
.defaultClient(ClientCredentials.of()
.withClientId(System.getenv("CTP_CLIENT_ID"))
.withClientSecret(System.getenv("CTP_CLIENT_SECRET"))
.build(),
ServiceRegion.GCP_EUROPE_WEST1)
.build(System.getenv("CTP_PROJECT_KEY"))
return apiRoot
}
However, I would like to authorize as a specific customer (email and password) and interact with the Commercetools API using the customer. The following code throws an error:
private static ProjectApiRoot createCustomerClient() {
def tokenUri = "https://auth.europe-west1.gcp.commercetools.com/oauth/*CTP_PROJECT_KEY*/customers/token"
def projectKey = System.getenv("CTP_PROJECT_KEY")
def scopes = System.getenv("CTP_SCOPES")
def credentials = ClientCredentials.of()
.withClientId("*email*")
.withClientSecret("*password*")
.withScopes(scopes)
.build()
def apiRootBuilder = ApiRootBuilder.of()
.withApiBaseUrl("https://api.europe-west1.gcp.commercetools.com")
.withClientCredentialsFlow(credentials, tokenUri)
return apiRootBuilder.build(projectKey)
}
Error:
io.vrap.rmf.base.client.oauth2.AuthException: detailMessage: Unauthorized
"message" : "Please provide valid client credentials using HTTP Basic Authentication.",
By using the withGlobalCustomerPasswordFlow instead of the withClientCredentialsFlow which authenticates the customer prior to doing the request.
But I would advise to do this only in a context where the customer is logging in everytime. Using it in any other context e.g. remembered log in of needs a more sophisticated approach as you need to store the bearer token and refresh token and can't easily use the middleware approach for authenticating the customer but instead do it not as part of an auth flow middleware.
Please see also https://github.com/commercetools/commercetools-sdk-java-v2/tree/main/commercetools/commercetools-sdk-java-api/src/integrationTest/java/commercetools/me
I am a newbie (6 months going or so) and creating an app on Android (Java) that utilizes FireBase Auth with Google Sign In. (with only a few days of NodeJS exposure now) In other words my end user signs in with the Google Account. That part (I think) works pretty well so far. I use the Firestore Database heavily for a lot of things in the app.
So now I've gotten to the point where I want to use (Callable) Cloud Functions with HTTP Triggers. (never having done any of this before) I'm trying to get a proof of concept working at this time. The actual function works and I can trigger it from my app.
It appears that I cannot figure out how to make the function "private" though; as in "adding proper Members" to the Cloud function who have the right to invoke the function.
I have tried a few different things by trial error, but first let me show what I have.
This is the Cloud Function and I'm passing in an arbitrary String as a test, works nicely: (as long as "allUsers" have the role/right to invoke the function; in other words when the function is public.
exports.createTest = functions.https.onCall((data, context) => {
const text = data.text;
const uid = context.auth.uid;
const name = context.auth.token.name || null;
const email = context.auth.token.email || null;
console.log('UID: ', uid);
console.log('Name: ', name);
console.log('Email: ', email);
console.log('Message: ', text);
});
The above function gets triggered in my Android/Java code like this: (I think this code came from Google Doc/Sample/Example
private FirebaseFunctions mFunctions;
...
private void testing() {
mFunctions = FirebaseFunctions.getInstance();
Log.e(LOG_TAG, "Testing executed!");
String testMessage = "Hello Hello Testing 123 Mic Check";
createTest(testMessage)
.addOnCompleteListener(new OnCompleteListener<String>() {
#Override
public void onComplete(#NonNull Task<String> task) {
if (!task.isSuccessful()) {
Exception e = task.getException();
if (e instanceof FirebaseFunctionsException) {
FirebaseFunctionsException ffe = (FirebaseFunctionsException) e;
FirebaseFunctionsException.Code code = ffe.getCode();
Object details = ffe.getDetails();
Log.e(LOG_TAG, "FFE: " + ffe.getMessage() );
Log.e(LOG_TAG, "Code: " + code);
Log.e(LOG_TAG, "Details:" + details);
}
// ...
}
// ...
}
});
}
private Task<String> createTest(String text) {
// Create the arguments to the callable function.
Map<String, Object> data = new HashMap<>();
data.put("text", text);
data.put("push", true);
return mFunctions
.getHttpsCallable("createTest") //this is the function name
.call(data)
.continueWith(new Continuation<HttpsCallableResult, String>() {
#Override
public String then(#NonNull Task<HttpsCallableResult> task) throws Exception {
// This continuation runs on either success or failure, but if the task
// has failed then getResult() will throw an Exception which will be
// propagated down.
String result = (String) task.getResult().getData();
if (result != null) {
Log.e(LOG_TAG, "Result: " + result);
}
return result;
}
});
}
Only when I have "allUsers" added with the role/right to "invoke Cloud Function" then I get this working. My understanding of HTTP Requests and such is pretty limited, which is not making things easier.
I tried using the "allAuthenticatedUsers" options, which I figured would do the trick, because I actually authenticate my Users in the app through Firebase/Google Sign In. This Cloud Function shall only be available to either a) authenticated users or b) users of a specific domain. (I have a domain, let's say #testorganization.com) Or if I can identify my particular app (api key?) then that would work, too.
The moment I add a member "allAuthenticatedUsers" with role to invoke the function (and remove "allUsers) nothing happens. I also tried adding the entire domain, but that wouldn't work. (duh) Also tried adding my service account (trial and error at this point) and didn't seem to work.
In my Node JS code I am actually receiving the UID of the authenticated user, so it appears that some kind of user authentication information is already being exchanged.
With that knowledge, I can (successfully tried this) get the UID and cross check that against my database and verify a user that way, but seems unnecessary and I should be able to make the permissions work. (lock the function down entirely) Plus this took a really long time just finish this cross check. Or is this pretty standard procedure to do?
Like this-->
const usersRef = admin.firestore().collection('users').doc(uid)
usersRef.get()
.then((docSnapshot) => {
if (docSnapshot.exists) {
usersRef.onSnapshot((doc) => {
console.log('User Type logged in: ', doc.data().userCategory)
console.log('User Title: ', doc.data().userTitle)
});
} else {
console.log('User does not exist')
}
});
Edit:
So while not having figured out how to shut down the function entirely, I did discover that instead of cross checking my users, I can simple check for auth like this:
if (context.auth){
//user is auth'd
} else {
//no auth
}
That's a little bit better, I guess. (but still doesn't technically prevent access to the function?!)
Thank you so much for any help. Much appreciated.
Edit2:
Here is a screensshot of the area in the cloud console (for cloud function roles/privileges) that I am referring to:
https://imgur.com/cBsjaaL
With a Callable Cloud Function, if you want to ensure that only authenticated users can trigger it's business logic, you actually don't need to configure any extra "cloud function roles/privileges" as shown at the bottom of your question.
By default, with a Callable Cloud Function you will get, when available, "Firebase Authentication and FCM tokens automatically included in requests" and it will "automatically deserializes the request body and validates auth tokens", as explained in the doc.
So you just have to follow the doc and use the context parameter. As you have mentioned in your question, you can check the user is authenticated by doing:
if (context.auth) {
//...
}
If you want to verify the user email, you would do:
exports.addMessage = functions.https.onCall((data, context) => {
const uid = context.auth.uid;
return admin.auth().getUser(uid)
.then(userRecord => {
const userEmail = userRecord.email;
//....
})
.catch(function(error) {
console.log('Error fetching user data:', error);
// Send back an error to the front end
// See https://firebase.google.com/docs/functions/callable#handle_errors
});
});
You will find more examples on how to "work with" users with the Admin SDK here in the doc.
I have a Task that is to retrieve some Information from a JIRA account through Java. I downloaded the Jira API which is working with Java, but I have no idea how to make it work. I have to pass somewhere my username and password for log in and after that to retrieve what Information I want from what project I want.
JiraRestClientFactory factory = new AsynchronousJiraRestClientFactory();
URI uri = new URI(JIRA_URL);
JiraRestClient client = factory.createWithBasicHttpAuthentication(uri, JIRA_ADMIN_USERNAME, JIRA_ADMIN_PASSWORD);
// Invoke the JRJC Client
Promise<User> promise = client.getUserClient().getUser("admin");
// Here I am getting the error!!
User user = promise.claim();
///////////////////////////////////////
// Print the result
System.out.println(String.format("Your admin user's email address is: %s\r\n", user.getEmailAddress()));
// Done
System.out.println("Example complete. Now exiting.");
System.exit(0);
That above code is not working, because either if I pass a wrong password and a wrong username is showing me the same result. I have to know how to connect properly to JIRA and retrive some Information in JSON from there! Thank you for your time!
Here is the error
Caused by: com.atlassian.jira.rest.client.api.RestClientException: org.codehaus.jettison.json.JSONException: A JSONObject text must begin with '{' at character 9 of
I think you don't have the necessary permission to acces Jira , you have to connect with jira with an account that have the correct permissions!
The only thing I can think of is that you are sending incorrect creds. Try using the email address instead of just "admin".
Here is some code that might help: https://github.com/somaiah/jrjc
I check for an issue, but getting user info would be similar.
You can use the below code the get the results.Remember I am using this in my gradle project where I am downloading all the dependencies of JRCJ
import com.atlassian.jira.rest.client.api.JiraRestClientFactory
import com.atlassian.jira.rest.client.api.domain.User
import com.atlassian.jira.rest.client.internal.async.AsynchronousJiraRestClientFactory
import com.atlassian.util.concurrent.Promise
/**
* TODO: Class description
*
* on 20 Jul 2017
*/
class Jira {
private static final String JIRA_URL = "https://JIRA.test.com"
private static final String JIRA_ADMIN_USERNAME = "ABCDE"
private static final String JIRA_ADMIN_PASSWORD = "******"
static void main(String[] args) throws Exception
{
// Construct the JRJC client
System.out.println(String.format("Logging in to %s with username '%s' and password '%s'", JIRA_URL, JIRA_ADMIN_USERNAME, JIRA_ADMIN_PASSWORD))
JiraRestClientFactory factory = new AsynchronousJiraRestClientFactory()
URI uri = new URI(JIRA_URL)
JiraRestClient client = factory.createWithBasicHttpAuthentication(uri, JIRA_ADMIN_USERNAME, JIRA_ADMIN_PASSWORD)
// Invoke the JRJC Client
Promise<User> promise = client.getUserClient().getUser(JIRA_ADMIN_USERNAME)
User user = promise.claim()
// Print the result
System.out.println(String.format("Your user's email address is: %s\r\n", user.getEmailAddress()))
// Done
//System.out.println("Example complete. Now exiting.")
//System.exit(0)
}
}
I have written the code in java that creates an instance of the wrapper and verifies the user's email and password for their account, however with discontinued support for the java SoundCloud API I can't seem to find a way to get a users' likes from this point and I've looked up all the documentation and examples but none seem to work when implemented.
PS. I changed the client id, client secret, and username and password for security so ignore that in the code.
import com.soundcloud.api.ApiWrapper;
import com.soundcloud.api.Token;
import java.io.File;
/**
* Creates an API wrapper instance, obtains an access token and serializes the
* wrapper to disk. The serialized wrapper can then be used for subsequent
* access to resources without re-authenticating
*
* #see GetResource
*/
public final class CreateWrapper {
public static final File WRAPPER_SER = new File("wrapper.ser");
public static void main(String[] args) throws Exception {
final ApiWrapper soundCloud = new ApiWrapper(
"client_id", /*client id*/
"client_secret" /* client_secret */,
null /* redirect URI */,
null /* token */);
Token token;
token = soundCloud.login("username#username.com" /* login */, "password" /* password */);
System.out.println("got token from server: " + token);
// in this example the whole wrapper is serialised to disk -
// in a real application you would just save the tokens and usually have the client_id/client_secret
// hardcoded in the application, as they rarely change
soundCloud.toFile(WRAPPER_SER);
System.out.println("wrapper serialised to " + WRAPPER_SER);
}
}
Look at the developers documentation for the me endpoint
All subresources that are documented in /users are also available via /me. For example /me/tracks will return the tracks owned by the user. Additionally you can access the users dashboard activities through /me/activities and his or her connected external accounts through /me/connections.
https://developers.soundcloud.com/docs/api/reference#me
GET /users/{id}/favorites list of tracks favorited by the user
I have the following Google Cloud Endpoints API, and I want it accesible only for authenticated users with certain role.
Few lines of code says much more than a thousand words:
import com.google.appengine.api.users.User;
#Api(
name = "heroesApi",
version = "v1",
clientIds = {...},
scopes = {...},
audiences = {...},
namespace = #ApiNamespace(
ownerDomain = "my.domain.com",
ownerName = "my.domain.com",
packagePath=""
)
)
public class HeroesApi {
// THIS IS THE FUNCTION THAT I DON´T KNOW WHERE TO PUT
/**
* Validates that the user is logged in with a specific role
* #param user
* #throws UnauthorizedException
* #throws ForbiddenException
*/
private void validateUser(User user) throws UnauthorizedException, ForbiddenException {
IUserController userController = ControllerFactory.get.userController();
if (user == null) {
throw new ForbiddenException("You must be logged in, my friend.");
} else if (!userController.isLoggedAsSuperHero(user)) {
throw new UnauthorizedException("You must be logged in as a Superhero.");
}
}
// API METHODS
#ApiMethod(path = "something", httpMethod = ApiMethod.HttpMethod.PUT)
public DoneTask doSomething(Some thing, User superhero) throws UnauthorizedException, ForbiddenException {
// this is what I want to avoid on each function
this.validateUser(superhero);
// Now I'll do something special
IUserController userController = ControllerFactory.get.userController();
return userController.doSome(thing);
}
// MORE GORGEOUS METHODS JUST FOR SUPERHEROES, SO I HAVE TO PERFORM THE VALIDATION...
}
I have though about adding a filter through the web.xml file for all request to /api/heroesApi/*, but the problem there is how to catch the Google Appengine Api User.
Isn´t there something provided by Google to do this?
Any suggestion to avoid the repeated call to validateUser(User) is welcome
Google Cloud Endpoints doesn't supper roles by default , so your application have to build role concept, and you have to write filter and get current user and check against the roles maintained in your end
To get current user in the filter, try this
https://cloud.google.com/appengine/docs/java/oauth/
I haven't tested this , but am sure you can get the current user using the UserService Api in appengine as long as your system uses google account as authentication.