When I called Braintree::Transaction.sale, got error "CVV must be 4 digits for American Express and 3 digits for other card types" - braintree

When I called Braintree::Transaction.sale with the "payment_method_nonce" which created by Drop-in UI, everything is alright.
However, after I added some custom fields in the Drop-in UI and call the same API, I got an error "CVV must be 4 digits for American Express and 3 digits for other card types".
I'm quite sure the CVV should be correct...
Does anyone have idea on this error?
iOS client side implementation:
internal func tokenizeCreditCard(creditCard: CreditCard, completion: #escaping NerfireAPICompletionBlock) {
// For client authorization,
// get your tokenization key from the control panel
// or fetch a client token
let braintreeClient = BTAPIClient(authorization: <sandbox_token>)!
let cardClient = BTCardClient(apiClient: braintreeClient)
let card = BTCard(number: creditCard.number!, expirationMonth: creditCard.month!, expirationYear: creditCard.year!, cvv: creditCard.verificationValue!)
cardClient.tokenizeCard(card) { (tokenizedCard, error) in
if error != nil {
completion(nil, error as NSError?)
}else {
completion(tokenizedCard, nil)
}
}
}
Ruby server side:
result = Braintree::Transaction.sale(
:amount => "15.00",
:payment_method_nonce => nonce_from_the_client,
:options => {
:submit_for_settlement => true
}
)

Related

GO Gin Keeps returning empty status if Any part of my code returns false

I am relatively new to Golang and Gin(framework)
I am writing some really simple API endpoints . But I notice something really weird about Gin, if there is any codition or function within my code that returns false the rest of my code or conditions does not get executed and Gin just returns a JSON with empty status :
{"status":""}
Here is a very simple code to explain what I mean
In a functions.go file I have :
func VerifyUserLogin(username,password,userAgent string) (string, string) {
userData := Users{}
userQueryColumn := "username=?"
// if they are trying to login with email
if nEmailHelpers.EmailIsValid(username) == true{
userQueryColumn = "email=?"
}
if getUserData := db.Select("password").Where(userQueryColumn, strings.ToLower(username)).First(&userData); getUserData.Error != nil {
// Meaning there was an error, most likely no data found , so we just return false todo improve this error handling later to handle more specific errors
return "", feedback["InvalidLogin"]
} else {
if getUserData.RowsAffected == 1 {
if nSecurityHelpers.CheckPasswordHash(password, userData.Password)==true {
token, tokenError := CreateToken(username, userAgent, false, 60)
if tokenError == nil {
return token, feedback["ValidLogin"]
} else {
return "", feedback["TokenNotGenerated"]
}
} else {
return "", feedback["InvalidLogin"]
}
}
return "", feedback["InvalidLogin"]
}
}
In another go file that references the functions.go file I have :
func main(){
router := gin.Default()
router.POST ("login",loginUser)
router.Run()
}
var feedback = userFeedback.Users()
// loginUser function to login a user
func loginUser(c *gin.Context){
requestBody := neielRequestsHelpers.RequestBody(c)
username := requestBody["username"]
password := requestBody["password"]
userAgent := c.Request.Header.Get("User-Agent")
token, loginMessage := userFunctions.VerifyUserLogin(username,password,userAgent)
// todo come back and fix proper error message when user does not exist
fmt.Println(loginMessage)
if loginMessage==feedback["ValidLogin"]{
c.JSON(http.StatusOK, gin.H{"status":loginMessage,"token":token})
}else{
c.JSON(http.StatusUnauthorized, gin.H{"status":feedback["InvalidLogin"]})
}
}
If all my inputs are correct , all goes well (Username exists and password is correct). But I have to handle scenario where username or password is invalid .If for any reason getUserData or nSecurityHelpers.CheckPasswordHash() is false , or any function for that matter returns a boolean of false . The entire function just terminates and doesn't allow me handle the error the way I want and output custom JSON response. I just get this {"status":""}
I am 100% sure this issue is from Gin , but I don't know what to activate or deactivate to allow me handle errors on my own. I have read the docs, but its obvious I am missing something .
Kindly help me please .
I have resolved this, thanks to everyone that tried to help
It was a typo error causing the issue "InValidLogin" instead of "InvalidLogin" in another file.
It was really subtle

Why does OIDC login breaks in Edge but not in FireFox?

I am wokring on a website (.NET Framework 4.6.1) and we implemented OIDC authentication (IdentityServer4). The implementation is very basic, nothing fancy just some code challange and token validation. We tested it and it worked real nice on both Edge and FireFox.
Then we were asked to implement "acr_values" parameter for MFA. In the authentication configuration, specifically inside RedirectToIdentityProvider (which is part of Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationNotifications), we add the specified "acr_values" parameter the following way (the value itself is set in a config file, and its similar to "xyz:asd:wtf:qwe"):
n.ProtocolMessage.AcrValues = authCfg.AcrValues
In a very similar setup (by similar i mean almost identical) it is working without any issues. For my setup it only works in Firefox. When trying in Edge we get AuthenticationFailed (which is also a Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationNotifications) with the following error:
2021-05-26 13:00:08.0633 ERROR MT.Translate.Startup
OIDC-Notification: AuthenticationFailed:
2021-05-26 13:00:08.0633 ERROR MT.Translate.Startup Value cannot
be null. Parameter name: s
2021-05-26 13:00:08.0633 ERROR MT.Translate.Startup
-TargetSite-------------------------------
2021-05-26 13:00:08.0633 ERROR MT.Translate.Startup Byte[]
FromBase64String(System.String)
2021-05-26 13:00:08.0633 ERROR MT.Translate.Startup
-Source-----------------------------------
2021-05-26 13:00:08.0633 ERROR MT.Translate.Startup mscorlib
In development enviroment the behaviour is a bit different. We do not get AuthenticationFailed, because after verifying the login information IdentityServer's redirection does nothing, but return us to the same login screen.
To summerize, without "acr:values" MFA was not working, but otherwise it was working in both Edge and Firefox. After implementig "acr_values" Firefox was working with MFA but not in Edge. So we rolled back to the previous version, where we have no "acr_values" and now MFA works with Edge and Firefox too.
The error does not make any sense to me. There is no parameter called "s", at least I have never heard of it in the context of authentication. The fact that without the necessary code it works does not make any sense to me. Also how can it work on Firefox and not on Edge?
Bonus Objective: Only in Edge a png is not appearing. It was not touched and in every other browser it shows up. How and why is my question.
Thank you for reading my post and I am looking forward to any insight what is happening.
Some code snippets:
oicdAuthOpt.Notifications = new OpenIdConnectAuthenticationNotifications
{
RedirectToIdentityProvider = n =>
{
if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication && AppSettingsKey.AuthCodeChallangeEnabled.Enabled)
{
// generate code verifier and code challenge
var codeVerifier = CryptoRandom.CreateUniqueId(32);
string codeChallenge;
using (var sha256 = SHA256.Create())
{
var challengeBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier));
codeChallenge = Base64UrlEncoder.Encode(challengeBytes);
}
// set code_challenge parameter on authorization request
n.ProtocolMessage.Parameters.Add("code_challenge", codeChallenge);
n.ProtocolMessage.Parameters.Add("code_challenge_method", "S256");
if (AppSettingsKey.MultiFactorAuthEnabled.Enabled)
n.ProtocolMessage.AcrValues = authCfg.AcrValues ?? n.ProtocolMessage.AcrValues;
// remember code verifier in cookie (adapted from OWIN nonce cookie)
// see: https://github.com/scottbrady91/Blog-Example-Classes/blob/master/AspNetFrameworkPkce/ScottBrady91.BlogExampleCode.AspNetPkce/Startup.cs#L85
RememberCodeVerifier(n, codeVerifier);
}
logger.Debug("OIDC-Notification: RedirectToIdentityProvider Called");
//if signing out, add the id_token_hint
if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout)
{
logger.Debug(" RequestType=" + OpenIdConnectRequestType.Logout);
var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");
if (idTokenHint != null)
{
logger.Debug(" IdTokenHint got from n.OwinContext.Authentication.User");
n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
}
logger.Debug(" IdTokenHint=" + n?.ProtocolMessage?.IdTokenHint);
}
return Task.CompletedTask;
},
Code for the IndentityServer is on their github (Quickstart).
For authorization middleware we made a custom System.Web.Mvc.AuthorizeAttribute.
public override void OnAuthorization(AuthorizationContext filterContext)
{
try
{
if (AppSettingsKey.LoginEnabled.Enabled && AppSettingsKey.OpenIdConnectSSOEnabled.Enabled)
{
var cookie = HttpContext.Current.Request.Cookies["oidc.default"];
if (cookie == null)
{
logger.Debug("oidc.default is null -> HandleUnauthorizedRequest");
base.HandleUnauthorizedRequest(filterContext);
}
else
{
if (CookieKeyStore.Instance.CheckIfContains(cookie.Value))
{
if (!CookieKeyStore.Instance.isExpired(cookie.Value))
{
logger.Debug("oidc.default is not expired:" + cookie.Value + " -> OnAuthorization");
//requires oidc.default and ASP.NET_SessionID cookies
base.OnAuthorization(filterContext);
}
else
{
logger.Debug("oidc.default is expired:" + cookie.Value + " -> HandleUnauthorizedRequest");
base.HandleUnauthorizedRequest(filterContext);
}
}
else
{
logger.Debug("insert oidc.default into the KeyStore:" + cookie.Value + " -> OnAuthorization");
CookieKeyStore.Instance.HandleCookies(cookie);
base.OnAuthorization(filterContext);
}
}
}
else
base.OnAuthorization(filterContext);
}
catch (Exception e)
{
logger.Error(e, "Exception while overriding the OnAuthorization method.");
}
}
"oidc.default" is our custom cookie configured into OIDC.
app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
CookieName = "oidc.default",
CookieManager = new Microsoft.Owin.Host.SystemWeb.SystemWebChunkingCookieManager(),
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
OnResponseSignOut = context =>
{
CookieKeyStore.Instance.Clear(context.Request.Cookies["oidc.default"]);
}
}
});

Using side effects in Akka Streams to implement commands received from a websocket

I want to be able to click a button on a website, have it represent a command, issue that command to my program via a websocket, have my program process that command (which will produce a side effect), and then return the results of that command to the website to be rendered.
The websocket would be responsible for updating state changes applied by different actors that are within the users view.
Example: Changing AI instructions via the website. This modifies some values, which would get reported back to the website. Other users might change other AI instructions, or the AI would react to current conditions changing position, requiring the client to update the screen.
I was thinking I could have an actor responsible for updating the client with changed information, and just have the receiving stream update the state with the changes?
Is this the right library to use? Is there a better method to achieve what I want?
You can use akka-streams and akka-http for this just fine. An example when using an actor as a handler:
package test
import akka.actor.{Actor, ActorRef, ActorSystem, Props, Stash, Status}
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.ws.{Message, TextMessage}
import akka.http.scaladsl.server.Directives._
import akka.stream.scaladsl.{Flow, Sink, Source, SourceQueueWithComplete}
import akka.stream.{ActorMaterializer, OverflowStrategy, QueueOfferResult}
import akka.pattern.pipe
import scala.concurrent.{ExecutionContext, Future}
import scala.io.StdIn
object Test extends App {
implicit val actorSystem = ActorSystem()
implicit val materializer = ActorMaterializer()
implicit def executionContext: ExecutionContext = actorSystem.dispatcher
val routes =
path("talk") {
get {
val handler = actorSystem.actorOf(Props[Handler])
val flow = Flow.fromSinkAndSource(
Flow[Message]
.filter(_.isText)
.mapAsync(4) {
case TextMessage.Strict(text) => Future.successful(text)
case TextMessage.Streamed(textStream) => textStream.runReduce(_ + _)
}
.to(Sink.actorRefWithAck[String](handler, Handler.Started, Handler.Ack, Handler.Completed)),
Source.queue[String](16, OverflowStrategy.backpressure)
.map(TextMessage.Strict)
.mapMaterializedValue { queue =>
handler ! Handler.OutputQueue(queue)
queue
}
)
handleWebSocketMessages(flow)
}
}
val bindingFuture = Http().bindAndHandle(routes, "localhost", 8080)
println("Started the server, press enter to shutdown")
StdIn.readLine()
bindingFuture
.flatMap(_.unbind())
.onComplete(_ => actorSystem.terminate())
}
object Handler {
case object Started
case object Completed
case object Ack
case class OutputQueue(queue: SourceQueueWithComplete[String])
}
class Handler extends Actor with Stash {
import context.dispatcher
override def receive: Receive = initialReceive
def initialReceive: Receive = {
case Handler.Started =>
println("Client has connected, waiting for queue")
context.become(waitQueue)
sender() ! Handler.Ack
case Handler.OutputQueue(queue) =>
println("Queue received, waiting for client")
context.become(waitClient(queue))
}
def waitQueue: Receive = {
case Handler.OutputQueue(queue) =>
println("Queue received, starting")
context.become(running(queue))
unstashAll()
case _ =>
stash()
}
def waitClient(queue: SourceQueueWithComplete[String]): Receive = {
case Handler.Started =>
println("Client has connected, starting")
context.become(running(queue))
sender() ! Handler.Ack
unstashAll()
case _ =>
stash()
}
case class ResultWithSender(originalSender: ActorRef, result: QueueOfferResult)
def running(queue: SourceQueueWithComplete[String]): Receive = {
case s: String =>
// do whatever you want here with the received message
println(s"Received text: $s")
val originalSender = sender()
queue
.offer("some response to the client")
.map(ResultWithSender(originalSender, _))
.pipeTo(self)
case ResultWithSender(originalSender, result) =>
result match {
case QueueOfferResult.Enqueued => // okay
originalSender ! Handler.Ack
case QueueOfferResult.Dropped => // due to the OverflowStrategy.backpressure this should not happen
println("Could not send the response to the client")
originalSender ! Handler.Ack
case QueueOfferResult.Failure(e) =>
println(s"Could not send the response to the client: $e")
context.stop(self)
case QueueOfferResult.QueueClosed =>
println("Outgoing connection to the client has closed")
context.stop(self)
}
case Handler.Completed =>
println("Client has disconnected")
queue.complete()
context.stop(self)
case Status.Failure(e) =>
println(s"Client connection has failed: $e")
e.printStackTrace()
queue.fail(new RuntimeException("Upstream has failed", e))
context.stop(self)
}
}
There are lots of places here which could be tweaked, but the basic idea remains the same. Alternatively, you could implement the Flow[Message, Message, _] required by the handleWebSocketMessages() method by using GraphStage. Everything used above is also described in detail in akka-streams documentation.

Logging in with Facebook through Parse error after updating to Xcode 6.3

I used a tutorial to learn how to log in with Facebook through Parse and followed it step by step. The link to the tutorial is: http://blog.oskoui-oskoui.com/?p=8161
It worked great in Xcode 6.2 and I had no problems with my code, but now after updating to Xcode 6.3 I am getting an error that says: "missing argument for parameter 'selector' in call". This error appears right after "PFFacebookUtils.logInWithPermissions" in the code below. I have tried a few different things and all I get is a different error. How can I fix this?
let permissions = ["public_profile"]
#IBAction func facebookLogInButton(sender: AnyObject) {
PFFacebookUtils.logInWithPermissions(permissions: permissions, {
(user: PFUser!, error: NSError!) -> Void in
if user == nil {
NSLog("Uh oh. The user cancelled the Facebook login.")
} else if user.isNew {
NSLog("User signed up and logged in through Facebook! \(user)")
} else {
NSLog("User logged in through Facebook! \(user)")
}
})
}
This could be a case of Xcode misreading an error. At the beginning of the closure, the two variables should have "?" instead of "!". The code would be
(user:PFUser?, error:NSError?) in
This fixed the problem.
#IBAction func fbLoginClick(sender: AnyObject) {
PFFacebookUtils.logInWithPermissions(self.permissions, block: {
(user: PFUser?, error: NSError?) -> Void in
if user == nil {
NSLog("Uh oh. The user cancelled the Facebook login.")
} else if user!.isNew {
NSLog("User signed up and logged in through Facebook! \(user)")
} else {
NSLog("User logged in through Facebook! \(user)")
}
})
}

Keep a Play 2 application private on heroku

I'm using Heroku to host a Play 2 application for the purpose of testing and playing around. I'd like the application to be "private" at this point which means that every aspect of the application should only be visible to certain users.
Normally, I would just use an htaccess file with one single user/password, but that's a specific thing of Apache of course and doesn't help me in this case.
The protection doesn't have to be "strong". The main aim is to keep away bots and random visitors
It would be great if I didn't have to "pollute" the code of my play application. I'd prefer to have some external mechanism to achieve that. If there is no other way than to realize it using play itself, the solution should be loosely coupled from the rest of my play application.
How could I achieve that?
edit: to emphasize it: what I want to achieve won't be part of the final application in production mode. So it neither has to be super secure, nor super engineered.
Adreas example is correct but it is from play 2.1 and in play 2.2 the signature of Filter.apply has changed a little bit, this should work better with 2.2:
class BasicAuth extends Filter {
val username = "stig"
val password = "secretpassword"
override def apply(next: RequestHeader => Future[SimpleResult])(request: RequestHeader): Future[SimpleResult] = {
request.headers.get("Authorization").flatMap { authorization =>
authorization.split(" ").drop(1).headOption.filter { encoded =>
new String(org.apache.commons.codec.binary.Base64.decodeBase64(encoded.getBytes)).split(":").toList match {
case u :: p :: Nil if u == username && password == p => true
case _ => false
}
}.map(_ => next(request))
}.getOrElse {
Future.successful(Results.Unauthorized.withHeaders("WWW-Authenticate" -> """Basic realm="MyApp Staging""""))
}
}
}
I dont think Heroku offers a solution for this. I ended up implementing a Basic access authentication filter and used it in the Global object. It looks something like this
class HerokuHttpAuth extends Filter {
object Conf {
val isStaging = true // read a config instead of hard coding
val user = "theusername"
val password = "thepassword"
}
override def apply(next: RequestHeader => Result)(request: RequestHeader): Result = {
if (Conf.isStaging) {
request.headers.get("Authorization").flatMap { authorization =>
authorization.split(" ").drop(1).headOption.filter { encoded =>
new String(org.apache.commons.codec.binary.Base64.decodeBase64(encoded.getBytes)).split(":").toList match {
case u :: p :: Nil if u == Conf.user && Conf.password == p => true
case _ => false
}
}.map(_ => next(request))
}.getOrElse {
Results.Unauthorized.withHeaders("WWW-Authenticate" -> """Basic realm="MyApp Staging"""")
}
} else {
next(request)
}
}
}

Resources