Unauthorised request in Mailjet - scala

i'm using MailJet Java Api to send email, i write this code en scala:
object Main {
var client: MailjetClient = null
var request: MailjetRequest = _
var response: MailjetResponse = _
def main(args: Array[String]) {
client = new MailjetClient(System.getenv("MJ_APIKEY_PUBLIC"), System.getenv("MJ_APIKEY_PRIVATE"))
request = new MailjetRequest(Email.resource)
.property(Email.FROMEMAIL, "pilot#mailjet.com")
.property(Email.FROMNAME, "Pilot")
.property(Email.SUBJECT, "Your mail !!!!")
.property(Email.TO, "passenger#mailjet.com")
response = client.post(request)
println(response.getStatus)
println(response.getData)
}
but i get 401 Unauthorized, although my public API key and private are corrects.do you have any idea

Related

Retrofit2 post request is successful but I'm not able to retrieve token from response body

So I'm trying to making a login(post) request to an API (https://reqres.in/api/login) with retrofit 2. The connection was successful as the response code is 200, when I did the same on Postman I received a response which contains a token string which I want but in android studio when I log the response body it gives different output. I am new to kotlin so I think I must be doing something wrong while retrieving response.
Output I'm receiving:
Response{protocol=h2, code=200, message=, url=https://reqres.in/api/login}
Output I want (token field)
{
"token": "QpwL5tke4Pnpja7X4"
}
Retrofit Builder
val retrofit = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(apiUrl)
.build()
val api : reqresAPI = retrofit.create(reqresAPI::class.java)
API Interface
interface reqresAPI {
// FOR REFERENCE
// https://reqres.in/api/login
// ANNOTATE WITH POST TO SEND DATA
#POST(value = "login")
fun sendData(
#Body user: User
): Call<ResponseModel> // CALL IS USED TO MAKE AN API CALL
}
Response Model
class ResponseModel{
val token : String = ""
get() = field
}
User model with 2 parameters email and password
class User (
val email :String,
val password :String
)
Calling API
val call = api.sendData(user)
call.enqueue(object : Callback<ResponseModel>{
override fun onResponse(call: Call<ResponseModel>, response: Response<ResponseModel>) {
Log.d("LOGGER", response.toString())
}
override fun onFailure(call: Call<ResponseModel>, t: Throwable) {
Log.d("LOGGER", "ERROR "+t.message.toString())
}
})
Please change this
class ResponseModel{
val token : String = ""
get() = field
}
to this
class ResponseModel{
#SerializedName("token")
val token : String
}

Retrofit2 + SimpleXML + SOAP request in Kotlin

I'm trying to create a service in the Android App that consumes a SOAP API. Sent values and returned values are XML.
Previously i used FormUrlEncoded + JSON in another API and worked, but with XML i'm struggling as the API seems that is not being called (HttpLoggingInterceptor don't show and also the Mockup service don't show any petition).
If i change to FormUrlEncoded my service i can see that the request is done (i checked it with HttpLoggingInterceptor, but if i remove the FormUrlEncoded seems like service is not called never.
My NetModule where is create the retrofir, parser, etc:
#Module
class NetModule {
#Provides
#Singleton
fun provideRetrofit(): Retrofit {
val client =
OkHttpClient.Builder()
.addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
})
.build()
val strategy = AnnotationStrategy()
val serializer = Persister(strategy)
return Retrofit.Builder()
.baseUrl(BuildConfig.API_URL)
.client(client)
.addConverterFactory(SimpleXmlConverterFactory.create(serializer))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
}
#Provides
#Singleton
fun provideFilesService(retrofit: Retrofit): FilesService =
retrofit.create(FilesService::class.java)
}
My FilesService.kt where the interface is defined is:
import com.liderasoluciones.enviotest.data.model.FileSendResponse
import com.liderasoluciones.enviotest.data.model.FileSendEnvelope
import io.reactivex.Flowable
import retrofit2.http.*
interface FilesService {
#Headers(
"Content-Type: application/soap+xml",
"Accept-Charset: utf-8"
)
#POST("mockWSSMTSoap")
fun sendFile(#Body body: FileSendEnvelope): Flowable<FileSendResponse>
}
My model for the Body, Request and data is FileSendEnvelope.kt and is:
import org.simpleframework.xml.Element
import org.simpleframework.xml.Root
import org.simpleframework.xml.Namespace;
import org.simpleframework.xml.NamespaceList;
#Root(name = "GetInfoByState", strict = false)
#Namespace(reference = "http://www.webservicetest.net")
class FileSendData {
#Element(name = "FileName", required = false)
var name: String? = null
}
#Root(name = "soap12:Body", strict = false)
class FileSendBody {
#Element(name = "GetInfoByFile", required = false)
var fileSendData: FileSendData? = null
}
#Root(name = "soap12:Envelope")
#NamespaceList(
Namespace(prefix = "xsi", reference = "http://www.w3.org/2001/XMLSchema-instance"),
Namespace(prefix = "xsd", reference = "http://www.w3.org/2001/XMLSchema"),
Namespace(prefix = "soap12", reference = "http://www.w3.org/2003/05/soap-envelope")
)
class FileSendEnvelope {
#Element(name = "soap12:Body", required = false)
var body: FileSendBody? = null
}
From the RemoteDataSource class is where i call the api:
class RemoteFilesDataSource(private val filesService: FilesService,
private val genericResponseEntityMapper: GenericResponseEntityMapper):
FilesDataSource {
override fun sendFile(userToken: String): Flowable<GenericResponseEntity> {
var petitionEnvelope = FileSendEnvelope()
var petitionBody = FileSendBody()
var petitionData = FileSendData()
petitionData.name = "test.png"
petitionBody.fileSendData = petitionData
petitionEnvelope.body =
return filesService.sendFile(petitionEnvelope)
.map { it.result }
.map { genericResponseEntityMapper.transform(it) }
}
}
At this moment i'm not taking so much care about the XML sent or parse the response, i just "want to check" that the API is called.
I tried to follow this info:
https://github.com/asanchezyu/RetrofitSoapSample
http://geekcalledk.blogspot.com/2014/08/use-simple-xml-with-retrofit-for-making.html
Even are java examples and i'm using Kotlin but no luck.
Any help is appreciated.
Thanks in advance.
Have you tried to use text/xml for your Content-type in your header? (and try it without the Accept-Charset header as well)
#Headers(
"Content-type: text/xml"
)

Akka-http & scribe for linkedin API: set/get cookie without session (scala)

I am using akka-http for bulding a REST API. (I am new to build REST web services).
I don't know how I can get and set cookie without using a session. This cookie must contain encrypt token access. I don't use Play or spray.
My code for the moment is:
lazy val signin = path("signin") {
get {
/* create the OAuthService object with a callback URL*/
val service = buildService()
/* get the request token*/
val requestToken = service.getRequestToken
/* create the cookie */
val jwtCookieEncrypted = tokenUtil.createLinkedinTokenSecret(requestToken)
val cookie = HttpCookie("jwtTokenCookie", jwtCookieEncrypted)
/* making the user validate our requestToken by redirecting him to the following URL*/
val authURL = service.getAuthorizationUrl(requestToken)
redirect(authURL, StatusCodes.TemporaryRedirect)
}
}
lazy val callback = path("callback") {
// extract cookie with the jwtTokenCookie name
cookie("jwtTokenCookie") { cookiePair =>
complete(s"The logged in user is '${cookiePair.name}'")
}
get {
parameters('code, 'state) { (code, state) => // must come from cookie and not request parameters
/* create the OAuthService object with a callback URL*/
val service = buildService()
/* get the request token*/
val requestToken = new Token(code, state)
if(state == tokenUtil.decryptLinkedinToken(requestToken.getSecret).getOrElse("")) "continue" else "throw error"
val verifier = new Verifier(state)
/* get the access token
(need to exchange requestToken and verifier for an accessToken which is the one used to sign requests)*/
val accessToken = service.getAccessToken(requestToken, verifier)
logger.debug(accessToken.getRawResponse)
/* sign request*/
val ResourceUrl = Settings.LinkedIn.ResourceUrl
val request = new OAuthRequest(Verb.GET, ResourceUrl)
service.signRequest(accessToken, request)
val response = request.send
if (response.getCode == StatusCodes.OK.intValue) complete(response.getBody)
else complete(int2StatusCode(response.getCode))
}
}
}
signin ~ callback
Check the akka doc. In your response you can include the header. In your case, maybe with redirect it´s not so simple. But you could complete the signing request returning a 308 Http code with the Location Header pointing to your oauth2 Auth server.
Is it better ?
path("signin") {
get {
val service = buildService()
val requestToken = service.getRequestToken
val authURL = service.getAuthorizationUrl(requestToken)
val requestTokenCrypted = tokenUtil.createLinkedinToken(requestToken)
val cookie = HttpCookie("abcde", requestTokenCrypted.getSecret)
setCookie(cookie) {
complete(HttpResponse(
status = StatusCodes.TemporaryRedirect,
headers = List(Location(authURL))
))
}
}
}

How to PUT XmlSlurper back to REST with HttpBuilder

I'm trying to make GET and then PUT call on XML REST web service.
I do it this way:
#Grab('org.codehaus.groovy.modules.http-builder:http-builder:0.7')
import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.ContentType.*
import static groovyx.net.http.Method.*
import groovy.xml.XmlUtil
def url = "http://localhost:81"
def pathPrefix = "/api/v1"
def http = new HTTPBuilder(url)
def profile = http.request(GET, XML) { req ->
uri.path = "$pathPrefix/profiles/55"
response.success = {resp, xml ->
xml
}
}
println XmlUtil.serialize(profile) // this is fine!
Now i'm going to change and save
profile.name = "New Name"
// this is not fine (i have 400 Bad Request)
// because it sends body not in XML
def savedProfile = http.request(PUT, XML) { req ->
uri.path = "$pathPrefix/profiles/55"
body = profile
response.success = {resp, xml ->
xml
}
}
println XmlUtil.serialize(savedProfile)
When i make PUT request HTTPBuilder do not send XML. It sends string, made of profile.toString().
It it not what i'm expecting.
How to send XmlSlurper object (that i obtained earlier) in PUT request?
Thank you.
I think i found the solution.
When i define body configuration value, i have to write
body = {
mkp.yield profile
}

Controller action returns "Invalid Json" when using a Fakerequest from a spec2 test

I am using playframework 2.6 and play-slick 0.8.0.
Action code:
def addCompany = Authenticated {
DBAction(parse.json) {
implicit rs => {
val newCompany = rs.request.body
val result = CompanyTable.insert(newCompany.as[Company])(rs.dbSession)
if(result > 0)
Ok("{\"id\":"+result+"}")
else
Ok("New company was not created.")
}
}
}
The Action is a composition of an Action that just checks for a valid session and the DBAction, which requires the request body to have a valid JSON object.
Test code:
"should create a Company from a Json request" in new InMemoryDB {
val newCompany = Company(name = "New Company1")
val fr = FakeRequest(POST, "/company")
.withSession(("email", "bob#villa.com"))
.withHeaders(CONTENT_TYPE -> "application/json")
.withJsonBody(Json.toJson(newCompany))
val action = controllers.CompanyController.addCompany
val result = action(fr).run
status(result) should be_==(OK)
(contentAsJson(result) \ "id").as[Long] should be_>(1L)
}
The InMemoryDB class is just a FakeApplication with a pre-populated in memory database.
The issue that I am having is that when the test runs the result is always a 400 with body content containing a message saying [Invalid Json]. When I call the service using curl with the same JSON body content, it works and the id is returned.
I decided to build a separate test project, and I used the activator to create a seed for the new project. I noticed that in the generated test that a different method of calling the action was used, so I switched my project to use this method. It worked, but I don't know why.
New code:
"should create a Company from a Json request" in new InMemoryDB {
val newCompany = Company(name = "New Company1")
val action = route(
FakeRequest(POST, "/company")
.withSession(("email", "bob#villa.com"))
.withHeaders(CONTENT_TYPE -> "application/json")
.withJsonBody(Json.toJson(newCompany))
).get
status(action) should be_==(OK)
(contentAsJson(action) \ "id").as[Long] should be_>(1L)
}
As you can see it uses a call to route instead of calling the controller.