0

I am having problems implementing HttpBuilder-NG basic authentication for a Cucumber feature step definition using Gradle, Groovy and Junit. I have sucessfully implemented this step definition using Behat/PHP. I have also verified the test using Postman.

Here is the build.gradle file

apply plugin: 'groovy'
apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.codehaus.groovy:groovy-all:2.4.12'
    compile 'io.github.http-builder-ng:http-builder-ng-core:1.0.2'
    testCompile 'junit:junit:4.12'
    testCompile 'info.cukes:cucumber-groovy:1.2.5'
    testCompile 'info.cukes:cucumber-junit:1.2.5'
}

The github API /user/repos path requires authentication to retrieve the user's repository information but the Get is returning an unAuthorized exception. If I leave out the path I get success but the base URL does not require authentication. Here is the Groovy code:

import static cucumber.api.groovy.EN.*
import cucumber.api.PendingException
import static groovyx.net.http.HttpBuilder.configure
import static groovyx.net.http.util.SslUtils.ignoreSslIssues

Given(~/^I am an authenticated user$/) { ->
    def github = configure {
        ignoreSslIssues execution
        request.uri = 'https://api.github.com'
    request.auth.basic('githubUser', 'githubPassword', false)
    }.get {
        request.uri.path = '/user/repos'
    }
    assert github != null
    println github.dump()
}

And here is the exception I am getting (401):

groovyx.net.http.HttpException: Unauthorized
    at groovyx.net.http.NativeHandlers.failure(NativeHandlers.java:69)
    at groovyx.net.http.HttpConfigs$BaseHttpConfig$$Lambda$9/15235276.apply(Unknown Source)
    at groovyx.net.http.HttpBuilder$ResponseHandlerFunction.apply(HttpBuilder.java:2305)
    at groovyx.net.http.JavaHttpBuilder$Action.lambda$execute$2(JavaHttpBuilder.java:168)
    at groovyx.net.http.JavaHttpBuilder$Action$$Lambda$56/33475769.call(Unknown Source)
    at groovyx.net.http.JavaHttpBuilder$ThreadLocalAuth.with(JavaHttpBuilder.java:331)
    at groovyx.net.http.JavaHttpBuilder$Action.execute(JavaHttpBuilder.java:122)
    at groovyx.net.http.JavaHttpBuilder.createAndExecute(JavaHttpBuilder.java:374)
    at groovyx.net.http.JavaHttpBuilder.doGet(JavaHttpBuilder.java:381)
    at groovyx.net.http.HttpBuilder$$Lambda$25/32560218.apply(Unknown Source)
    at groovyx.net.http.HttpObjectConfigImpl.nullInterceptor(HttpObjectConfigImpl.java:47)
    at groovyx.net.http.HttpObjectConfigImpl$Exec$$Lambda$23/7279823.apply(Unknown Source)
    at groovyx.net.http.HttpBuilder.get(HttpBuilder.java:346)
Gradle Test Executor 191 finished executing tests.
    at groovyx.net.http.HttpBuilder.get(HttpBuilder.java:1297)
    at groovyx.net.http.HttpBuilder$get$0.call(Unknown Source)
    at repo-create_steps$_run_closure1.doCall(repo-create_steps.groovy:7)
    at ?.Given I am an authenticated user(repo-create.feature:3)
cjstehno
  • 13,468
  • 4
  • 44
  • 56
  • Please add the configuration you used to make this work in Postman, as an example of it working. – cjstehno Oct 17 '17 at 12:15
  • Also, you might consider trying the `apache` or `okhttp` client implementation rather than the `core`, just to see if it's an issue with only one of the clients. – cjstehno Oct 17 '17 at 12:16
  • Lastly, I am assuming the `githubUser` and `githubPassword` are replaced with the actual values in your code... just checking ;-) – cjstehno Oct 17 '17 at 13:07
  • Are you sure their API accepts BASIC authentication (https://developer.github.com/v3/guides/basics-of-authentication/) everything I see requires OAUTH. Please point to the documentation you are using? – cjstehno Oct 17 '17 at 13:13
  • 1. Here is a link to the collection the step definition is contained in. https://documenter.getpostman.com/view/2835930/github-repositories-collection/716cF5C#e4dc66a0-ee79-9fff-a1e7-15f3077aaa85 - see the second operation (the first Get). – Phil Norman Oct 17 '17 at 13:39
  • Here is a link to github documentation showing that API v3 supports basic authentication. https://developer.github.com/v3/#authentication . Here is documentation for the action I was trying to take, List your respositories: https://developer.github.com/v3/repos/#list-your-repositories – Phil Norman Oct 17 '17 at 13:50
  • Finding same problem with apache and okhttp client implementations. And I am replacing githubUser and githubPassword with actual values in the code. – Phil Norman Oct 17 '17 at 15:03
  • did you look at my answer below? – cjstehno Oct 17 '17 at 15:15

1 Answers1

0

It looks like GitHub does provide BASIC support (https://developer.github.com/v3/auth/) but it is non-standard and they suggest creating the Authorization header yourself, which would look something like this:

@Grab('io.github.http-builder-ng:http-builder-ng-core:1.0.2')

import static groovyx.net.http.HttpBuilder.configure
import static groovyx.net.http.util.SslUtils.ignoreSslIssues

def username = 'blah'
def password = 'blah'
def creds = "$username:$password".bytes.encodeBase64()

def github = configure {
    ignoreSslIssues execution
    request.uri = 'https://api.github.com'
    request.headers['Authorization'] = "Basic $creds"
}.get {
    request.uri.path = '/user/repos'
    response.failure { fs, obj->
        println "Status: ${fs.statusCode}"
        fs.headers.each { h->
            println h
        }
    }
}

println github.dump()

However, this presents a problem which you may not have on your end. I have 2-factor authentication enabled on my account so I get the X-GitHub-OTP: required; :2fa-type header back (per the documentation linked above). If you do not have 2-factor you should have what you need.

I added the failure handler to get some additional information about the failure cases - it's not required for the solution.

cjstehno
  • 13,468
  • 4
  • 44
  • 56
  • That worked for all three client implementations (core, apache and okhttp). I appreciate the additional code for failure case. – Phil Norman Oct 17 '17 at 16:02