Keycloak SAML Client is not showing the login screen - single-sign-on

I have created a realm in Keycloak named SAML-Demo-Py
In the realm I have created a SAML client with these configuration
{
"clientId": "http://localhost:8081/python-app",
"name": "test-client-saml",
"description": "",
"rootUrl": "",
"adminUrl": "http://localhost:8081/cgi-bin/saml-consumer.py",
"baseUrl": "",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [
"http://localhost:8081/cgi-bin/saml-consumer.py"
],
"webOrigins": [],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": true,
"serviceAccountsEnabled": false,
"publicClient": true,
"frontchannelLogout": true,
"protocol": "saml",
"attributes": {
"saml_assertion_consumer_url_redirect": "http://localhost:8081/cgi-bin/saml-consumer.py",
"saml.force.post.binding": "true",
"saml.server.signature.keyinfo.ext": "false",
"saml.signing.certificate": "MIICzzCCAbcCBgGDSplRlDANBgkqhkiG9w0BAQsFADArMSkwJwYDVQQDDCBodHRwOi8vbG9jYWxob3N0OjgwODEvcHl0aG9uLWFwcDAeFw0yMjA5MTcwODM2NDVaFw0zMjA5MTcwODM4MjVaMCsxKTAnBgNVBAMMIGh0dHA6Ly9sb2NhbGhvc3Q6ODA4MS9weXRob24tYXBwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAve0sgrdPWvcKiRJ5UPcpa301aiIO7F7KDKnMDtxgY2EE47z8XS5TUvvySa75L0phxZQv+iqYSV1HlUkgJQiax3fg7JgxJ+BY3ss9Dz/m9x7stErFoMXeH+Bhdk9H7hUojlRqxn8qU7ZwInENvw8hlzTgouc5hqqBaQybXqtlmJi6HWAH/3Ck6jCd+P6pjIaGrQpYxpmpmPKbhRnovZWgL6KqdnoEl1thEcPAEbXE7HiB6h4z9HdF2EWx/8U7HE/qCq2m2lPsKn2OnJk2ejDqa5SyTBXRqeqS8sG70VXrotEtJVVuPJCFvGy8r7mq0bVX/83y+PyEpppsJMMtockdgwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBEDptd2Goi1XFKur3dpRHyOW9zxs96gGGllrcnQZCtZjVEb31Jibr0HFDftHR22hQV1mbQLokNk8k0on7tJvsOIdXv3459gkZyouYSmYpDTvfCi3YUgdxVrDiHzwaN6uIjqXeDeI08LmH2xDZwac46vqJyqx3QI/r84qmWR2Nil/7DnJegVWyr961GWm0HH6BpweZZ5QbEw0UHihqWDthgX4BAmVnRPm9fHebIa3/7AUqodh8hoRDJcaDiyLB+V8nUPD6vLwgFgiLSqLSPaJ0OSzBvz3cpNLL1PVkFVaoQZ7W3FX6Ruvz0Bj/piQ+h2fnX4NMkj33f6CyhJTGSfbnk",
"saml$server$signature$keyinfo$ext": "false",
"saml.signature.algorithm": "RSA_SHA256",
"saml.client.signature": "false",
"saml.force.name.id.format": "false",
"saml.signing.private.key": "MIIEowIBAAKCAQEAve0sgrdPWvcKiRJ5UPcpa301aiIO7F7KDKnMDtxgY2EE47z8XS5TUvvySa75L0phxZQv+iqYSV1HlUkgJQiax3fg7JgxJ+BY3ss9Dz/m9x7stErFoMXeH+Bhdk9H7hUojlRqxn8qU7ZwInENvw8hlzTgouc5hqqBaQybXqtlmJi6HWAH/3Ck6jCd+P6pjIaGrQpYxpmpmPKbhRnovZWgL6KqdnoEl1thEcPAEbXE7HiB6h4z9HdF2EWx/8U7HE/qCq2m2lPsKn2OnJk2ejDqa5SyTBXRqeqS8sG70VXrotEtJVVuPJCFvGy8r7mq0bVX/83y+PyEpppsJMMtockdgwIDAQABAoIBABjRKm1ELarZt/c0QkTpnvBsMnQVUjThp+4iq8bPVgr2TPDDK4izenDP+hdVtTrQMdli5Sf/s9l2RlnD7d7Y8nyY9fuEYXvv7Tzjeq2I8JGe6VgfoxZAdKdepu2SK3h5LEz4y+D3Ed1Ra/KcKisqe32qC6ZNp28ozXMgEhc7NzHKnOxKA0IXFzuT6cDJgJ8TQfa2K9dGgjEE9GTCCxnZEvdf17sEc4zVMJDDcE4Rorv0mZeN1QRXVSpnW1q0vFh1CvH1H9oBCUey8cElQybARTDbMJJWgHCdd29EbilmlyB4TFI34tcaKZUlvL3sT8fvRyV6yLL0M0mqVWYxhu24naUCgYEA/WKH8G6SsM+LhC2oVJWUSDicpDNNEi2Av2FZOSg7Vbqj53/t69kSPWv0Rp0o7Bz55xwxH+n6PjUEvHyiS3UBIW6kS81av1H8Gle/1XpopHEY4aX47KCdF1Wc0yq8l5ii+oFZt3GcS1egDFPiQgyo2lhlrrQ4mckcSZF3pdd8UTUCgYEAv+L6qdXxPZvyzRgsRfhmVl8FKdKPYFqBWQgh2Lx21J16T8jRhjFfJP6NNi2JupWrQB2JdA5sivx81GMxExo5j8P1VQm/g/c3I2bxb1kYDE77x6KJzmr0i7hK0SEGCcP51EdVpjtPzcdG3st3GT5UClvZ+rTfO87e6n4pdlMUgtcCgYBUre8cTPe9Gz9XByMwUWTi1fiTb4mcP5S9YL0+utFJjzxji39pyHuuBzv1tWQNtIlX0TYhokI9M97HVyet7AZas+04YAKp2a5U52p235fFDP7xulP8UJjvSW9Fqwyn5RzidwQSqGdBTqFwPUBqLmznu48P2a7oxisr8u93fxJO2QKBgG0fkdl/139n7n6AXr0z9E7uHquYGP18us5893KgSxvCqsowtCcScL9DG99Rql+3ufnuUjrz8PpheEP4XPI2GcIOeLhxoL5Vmr/BTVA7ZJerWzg+0QvYe1Xx6mpf02U+VBdKsgSk+k9WIpGVOBfdAEIb1izjK4iBrve/46hsut9lAoGBAKeKxXlH45BTuRg/Rcp60TTV4i+Aed0ApTmvYU22XasXRfrFsauLaxUkCP0x0hvdVx+cR37Jo9Nfw9DmplzHLVMI6STzracLuhjf0HKVS6XSJa5l4VpsmkJaWxyqdrm91OXnOOizTf6pOoRFoFI21u7ZKqMoEcaqrCOIwqv21qpa",
"saml.allow.ecp.flow": "false",
"saml.server.signature.keyinfo.xmlSigKeyInfoKeyNameTransformer": "NONE",
"saml.assertion.signature": "true",
"saml.encrypt": "false",
"login_theme": "keycloak",
"saml_assertion_consumer_url_post": "http://localhost:8081/cgi-bin/saml-consumer.py",
"saml$server$signature": "true",
"saml.server.signature": "true",
"saml.artifact.binding.identifier": "90y02x5M6keohgaOI7l3D0ZpdfU=",
"saml$server$signature$keyinfo$xmlSigKeyInfoKeyNameTransformer": "NONE",
"saml.artifact.binding": "false",
"saml_force_name_id_format": "false",
"saml.authnstatement": "true",
"display.on.consent.screen": "false",
"saml_name_id_format": "username",
"saml.onetimeuse.condition": "false",
"saml_signature_canonicalization_method": "http://www.w3.org/2001/10/xml-exc-c14n#"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"defaultClientScopes": [
"role_list"
],
"optionalClientScopes": [],
"access": {
"view": true,
"configure": true,
"manage": true
}
}
I have a running python dummy app which will act as ACS.
This is the SAML Request which will be send from the browser in the form of
<IDP-sso-url>?SAMLRequest=<encoded-same-request>
which results in
http://localhost:8080/realms/SAML-Demp-Py?SAMLRequest=lVLLTsMwEPyVyHfXSZpCayWVSiNEJEBRKRy4INdZqIVjB6%2FD4%2B9xUpDKBcHNK8%2FMzow2R9Hqjq96vzcbeOkBffTeaoN8%2FChI7wy3AhVyI1pA7iW%2FWV1d8nQS885Zb6XV5ED5HSwQwXllDTla8GfK6vu5tgb7FtwNuFcl4XZzWZC99x1nTFsp9N6i5%2FN4HjMHQrfIBjVaQtvR%2BoPtnH0Gx4bVVDUd9SEvA9N0VhlPojKMyohhzz9USXRunYSxw4I8Co1AoqosSFU%2BxMluOltAQuOTpKEZwIyKTIYxyzKxkDJtxGkAI%2FZQGfTC%2BIKkcZrSeEGT022S8GnM05PJdDG%2FJ1H9VfiZMo0yT7%2B3tzuAkF9stzXdQKMcyBDyDhyOAQOILPOhCz4acMs%2FR87ZMS0%2FHNF1sFCVtdVKfkQrre3bOlA9FMS7HsaWWhHy1YMB9BAaZ8uD0s8LXH4C&RelayState=9UITFKRCV-uUX7vdyNF6xIEybOVX2uDNZVohLi5OenU.q8U2Lp-_Lg8.http%3A%2F%2Flocalhost%3A8081%2Fpython-app
This is the request before encoding
<?xml version="1.0" encoding="UTF-8"?>
<saml2p:AuthnRequest
xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
AssertionConsumerServiceURL="http://localhost:8081/cgi-bin/saml-consumer.py"
Destination="http://localhost:8080/realms/SAML-Demp-Py/protocol/saml"
ID="1234"
IssueInstant="2021-09-17T18:41:20.295Z"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Version="2.0">
<saml2:Issuer
xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://localhost:8081/python-app
</saml2:Issuer>
</saml2p:AuthnRequest>
Now once past this in the url I don't see the keycloak login screen. Instead the url in the browser is still the same as above and I see this json in the body of the page
{"realm":"SAML-Demp-Py","public_key":"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvvoRDqFxcnJAmISv4qequAJ4w1dubE47Z2RStqVQ7oUZaUPO2magxvfa8CyaEwHuySkn42NjrafVMhZp/0gBVtsVW4uwNJCMXjvv8Tfbd4qUtVo50mEgGIpJRsm5RPXUJX2q1Yz/jX+U2vTfutEIDpRZGF6PtHt/tavuGt+qohpRycTWFvcEU7LuVu7Sj7AaOBNpgGSITUEYc09+JwrWcbenhrBZq9mJ5hgCw/0TU+HcwCIi1XgUVrzZ6OG0DwE702ezuDP2Nbs78U0w6tHUj+B1+p/TAntIg39CiwHHL3kIcwwJpHiJmeLNTlwlQm+Ny3w9LmP09dPAjMm2lw1qywIDAQAB","token-service":"http://localhost:8080/realms/SAML-Demp-Py/protocol/openid-connect","account-service":"http://localhost:8080/realms/SAML-Demp-Py/account","tokens-not-before":0}

You are using wrong endpoint. It is:
http://localhost:8080/realms/SAML-Demp-Py/protocol/saml?SAMLRequest=<encoded-saml-request>
instead of:
http://localhost:8080/realms/SAML-Demp-Py?SAMLRequest=<encoded-saml-request>

Related

Cannot set `bearerOnly: true` in Keycloak 19.0

I am trying to secure my backend service but due to the updates with Keycloak 19.0 I can't follow any tutorial online. I am trying to set bearerOnly: true but there are no options to set the access type in new version of Keycloak
I tested v19.0.1, I can't find to option for bearerOnly option UI either but client JSON import after export and change bearerOnly true works.
I tested to import v18.0.2's JSON makes error.(attached image at the bottom)
So if you migrate from old version to 19.0.1 should be update manually base on v19's export JSON file.
Steps
Export Client JSON from v19
Delete #1 client
Switch "bearerOnly": true
Import #3 JSON in v19
This is bearerOnly true and false difference screen in UI
bearerOnly True option
bearerOnly False option
Using this JSON for True option
{
"clientId": "my-client-bearer-true",
"name": "My Client Bearer Only True",
"description": "",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [],
"webOrigins": [],
"notBefore": 0,
"bearerOnly": true,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": true,
"serviceAccountsEnabled": false,
"publicClient": true,
"frontchannelLogout": true,
"protocol": "openid-connect",
"attributes": {
"oidc.ciba.grant.enabled": "false",
"oauth2.device.authorization.grant.enabled": "false",
"backchannel.logout.session.required": "true",
"backchannel.logout.revoke.offline.tokens": "false"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"defaultClientScopes": [
"web-origins",
"acr",
"roles",
"profile",
"email"
],
"optionalClientScopes": [
"address",
"phone",
"offline_access",
"microprofile-jwt"
],
"access": {
"view": true,
"configure": true,
"manage": true
}
}
If import v18.0.2 JSON file with bearerOnly true into v19.0.1,
It makes error
I using this V18 JSON file but It makes error as upper image.
So you can't import directly v18 JSON into V19.
{
"realm": "test",
"bearer-only": true,
"auth-server-url": "http://localhost:8180/auth/",
"ssl-required": "external",
"resource": "my-client",
"confidential-port": 0
}

Configuring keycloak as IDP in another keycloak

I am trying to configure a keycloak as an IDP in another keycloak. In my test setup there are 2 keycloak containers - keycloak-1 and keycloak-2.
In keycloak-1, I have created an openid client called idp-client. The configuration exported as JSON is shown below,
{
"clientId": "idp-client",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [
"http://localhost:8081/auth/realms/master/broker/oidc/endpoint"
],
"webOrigins": [],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": true,
"serviceAccountsEnabled": false,
"publicClient": false,
"frontchannelLogout": false,
"protocol": "openid-connect",
"attributes": {
"saml.assertion.signature": "false",
"saml.force.post.binding": "false",
"saml.multivalued.roles": "false",
"saml.encrypt": "false",
"saml.server.signature": "false",
"saml.server.signature.keyinfo.ext": "false",
"exclude.session.state.from.auth.response": "false",
"saml_force_name_id_format": "false",
"saml.client.signature": "false",
"tls.client.certificate.bound.access.tokens": "false",
"saml.authnstatement": "false",
"display.on.consent.screen": "false",
"saml.onetimeuse.condition": "false"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"defaultClientScopes": [
"web-origins",
"role_list",
"profile",
"roles",
"email"
],
"optionalClientScopes": [
"address",
"phone",
"offline_access",
"microprofile-jwt"
],
"access": {
"view": true,
"configure": true,
"manage": true
}
}
In keycloak-2, I have added keycloak-1 as an identity provider. I have attached the images of the configuration for reference.
Now when I try to login to keycloak-2 using keycloak-1's user, after successful login, I am redirected to keycloak-2's but to an error page, its showing "Unexpected error when authenticating with identity provider"
Stacktrace in the keycloak-2's terminal is as below,
keycloak2_1 | 08:21:17,079 TRACE [org.keycloak.events] (default task-10) type=CODE_TO_TOKEN_ERROR, realmId=master, clientId=idp-client, userId=null, ipAddress=127.0.0.1, error=invalid_client_credentials, grant_type=authorization_code, requestUri=http://localhost:8080/auth/realms/master/protocol/openid-connect/token, cookies=[]
...
...
keycloak2_1 | 08:21:17,081 TRACE [org.keycloak.events] (default task-12) type=LOGIN_ERROR, realmId=master, clientId=null, userId=null, ipAddress=172.21.0.1, error=identity_provider_login_failure, requestUri=http://localhost:8081/auth/realms/master/broker/oidc/endpoint?state=MOz5_i2-SpoSLRtS4IWkXtUBsSzGciBysUrdYq8gGy0.k0e5WlQElRw.security-admin-console&session_state=1cc90330-cf3c-45c3-a44e-53fc71b17bb1&code=be12828b-3408-4822-b275-31afeb1c0405.1cc90330-cf3c-45c3-a44e-53fc71b17bb1.eb068c43-9f4e-45b7-b2e8-ac346f139141, cookies=[KEYCLOAK_SESSION_LEGACY=master/ce30941f-407f-4344-9019-58d2f26ea832/1cc90330-cf3c-45c3-a44e-53fc71b17bb1, PrivacyPolicy=accepted, KEYCLOAK_IDENTITY_LEGACY=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIxNjgzNzMzNi1mMTA3LTRiMTktODk1Yi0wNWJmZDliZGIzYTUifQ.eyJleHAiOjE2MDk3ODQ0NzcsImlhdCI6MTYwOTc0ODQ3NywianRpIjoiNTQ3YmRlZGQtOGQyYy00MTJkLWJhMzYtZjkyNzAwNjlhYzQxIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL21hc3RlciIsInN1YiI6ImNlMzA5NDFmLTQwN2YtNDM0NC05MDE5LTU4ZDJmMjZlYTgzMiIsInR5cCI6IlNlcmlhbGl6ZWQtSUQiLCJzZXNzaW9uX3N0YXRlIjoiMWNjOTAzMzAtY2YzYy00NWMzLWE0NGUtNTNmYzcxYjE3YmIxIiwic3RhdGVfY2hlY2tlciI6IkZFT3psWkRScXhqREVVOGV6MFd6MU5menZGYU1jNHRzV1J4TnlrNUc5NDQifQ.YeBB6vJYZ9Z4IUXY2-og17EMRodUdeqTBTQ31pY3P1s, AUTH_SESSION_ID_LEGACY=1cc90330-cf3c-45c3-a44e-53fc71b17bb1.4c93e8da0ca1]
In keycloak-1, the user is logged in i.e. a session is shown for idp-client.
The mentioned issue was rectified once the SSL was enabled.

Azure devops - minimal code coverage pull reqeust

I have an Angular 9 project and I am trying to get the minimal code coverage working on an pull request in Azure devops conform the documentation. However the minimal code coverage isn't working, probably missing some step....
Steps to reproduce:
Create an new Angular 9 project: "ng new DefaultWebsite"
Create build pipeline and edit the karma and protractor config conform Microsoft "Build, test, and deploy JavaScript and Node.js apps" documentation
Add and "azurepipelines-coverage.yml" in the root of my project to enable the code coverage check in an pull request conform the Microsoft "Code coverage for pull requests" documentation
Disable some test in de app.spec.ts file, so the code coverage isn't 100% any more, it now is 77%. Changed the minimal code coverag in the yml file to 95% so the pull request cannot be complited conform the theory and it should give an "Coverage status check failed" error conform the Microsoft documentation.
However when the pull request is started there is an code coverage check below the 'Status' part. When the build (with unit and e2e tests) is done, there is no code coverage error which I espect te see below the 'Status' part.
Pull reqeust with code coverage check Pull reqeust build completed
When I look at the build there are test results and code coverage results.
Build test result Build code coverage result
When I look at the code coverage result I see an Line coverage of 75% which should be an minimal of 90% conform the yml-file.
Karma config file
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
const process = require('process');
process.env.CHROME_BIN = require('puppeteer').executablePath();
config.set({
basePath: '',
frameworks: ['jasmine', '#angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('#angular-devkit/build-angular/plugins/karma'),
require('karma-junit-reporter')
],
client: {
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, './coverage'),
reports: ['html', 'lcovonly', 'text-summary', 'cobertura'],
fixWebpackSourcePaths: true
},
coverageReporter: {
type : 'html',
dir : 'coverage/'
},
junitReporter: {
outputDir: './coverage', // results will be saved as $outputDir/$browserName.xml
outputFile: 'junit.xml', // if included, results will be saved as $outputDir/$browserName/$outputFile
suite: '', // suite will become the package name attribute in xml testsuite element
useBrowserName: true, // add browser name to report and classes names
nameFormatter: undefined, // function (browser, result) to customize the name attribute in xml testcase element
classNameFormatter: undefined, // function (browser, result) to customize the classname attribute in xml testcase element
properties: {}, // key value pair of properties to add to the <properties> section of the report
xmlVersion: null // use '1' if reporting to be per SonarQube 6.2 XML format
},
reporters: ['progress', 'kjhtml','junit'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['ChromeHeadless'],
singleRun: false,
restartOnFileChange: true
});
};
Protractor config file:
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
const { SpecReporter } = require('jasmine-spec-reporter');
const { JUnitXmlReporter } = require('jasmine-reporters');
process.env.CHROME_BIN = process.env.CHROME_BIN || require("puppeteer").executablePath();
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./src/**/*.e2e-spec.ts'
],
capabilities: {
'browserName': 'chrome',
chromeOptions: {
args: ["--headless", "--disable-gpu", "--window-size=1200,900"],
binary: process.env.CHROME_BIN
}
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function () { }
},
onPrepare() {
require('ts-node').register({
project: require('path').join(__dirname, './tsconfig.json')
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
var junitReporter = new JUnitXmlReporter({
savePath: require('path').join(__dirname, './junit'),
consolidateAll: true
});
jasmine.getEnv().addReporter(junitReporter);
}
};
azurepipelines-coverage.yml
coverage:
status: #Code coverage status will be posted to pull requests based on targets defined below.
diff: #diff coverage is code coverage only for the lines changed in a pull request.
target: 95% #set this to a desired %. Default is 70%.
Azure Build pipeline steps:
"steps": [
{
"environment": {},
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "npm install",
"timeoutInMinutes": 0,
"condition": "succeeded()",
"task": {
"id": "fe47e961-9fa8-4106-8639-368c022d43ad",
"versionSpec": "1.*",
"definitionType": "task"
},
"inputs": {
"command": "install",
"workingDir": "Project\\Frontend\\DefaultWebsite",
"verbose": "false",
"customCommand": "",
"customRegistry": "useNpmrc",
"customFeed": "",
"customEndpoint": "",
"publishRegistry": "useExternalRegistry",
"publishFeed": "",
"publishPackageMetadata": "true",
"publishEndpoint": ""
}
},
{
"environment": {},
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "npm custom - test ",
"timeoutInMinutes": 0,
"condition": "succeeded()",
"task": {
"id": "fe47e961-9fa8-4106-8639-368c022d43ad",
"versionSpec": "1.*",
"definitionType": "task"
},
"inputs": {
"command": "custom",
"workingDir": "Project\\Frontend\\DefaultWebsite",
"verbose": "false",
"customCommand": "run test",
"customRegistry": "useNpmrc",
"customFeed": "",
"customEndpoint": "",
"publishRegistry": "useExternalRegistry",
"publishFeed": "",
"publishPackageMetadata": "true",
"publishEndpoint": ""
}
},
{
"environment": {},
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "Publish code coverage from Project\\Frontend\\DefaultWebsite\\coverage\\cobertura-coverage.xml",
"timeoutInMinutes": 0,
"condition": "succeeded()",
"task": {
"id": "2a7ebc54-c13e-490e-81a5-d7561ab7cd97",
"versionSpec": "1.*",
"definitionType": "task"
},
"inputs": {
"codeCoverageTool": "Cobertura",
"summaryFileLocation": "Project\\Frontend\\DefaultWebsite\\coverage\\cobertura-coverage.xml",
"pathToSources": "",
"reportDirectory": "",
"additionalCodeCoverageFiles": "",
"failIfCoverageEmpty": "false"
}
},
{
"environment": {},
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "Publish Test Results Project\\Frontend\\DefaultWebsite\\**\\junit.xml copy",
"timeoutInMinutes": 0,
"condition": "succeeded()",
"task": {
"id": "0b0f01ed-7dde-43ff-9cbb-e48954daf9b1",
"versionSpec": "2.*",
"definitionType": "task"
},
"inputs": {
"testRunner": "JUnit",
"testResultsFiles": "Project\\Frontend\\DefaultWebsite\\**\\junit.xml",
"searchFolder": "$(System.DefaultWorkingDirectory)",
"mergeTestResults": "false",
"failTaskOnFailedTests": "false",
"testRunTitle": "",
"platform": "",
"configuration": "",
"publishRunAttachments": "true"
}
},
{
"environment": {},
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "npm custom - e2e",
"timeoutInMinutes": 0,
"condition": "succeeded()",
"task": {
"id": "fe47e961-9fa8-4106-8639-368c022d43ad",
"versionSpec": "1.*",
"definitionType": "task"
},
"inputs": {
"command": "custom",
"workingDir": "Project\\Frontend\\DefaultWebsite",
"verbose": "false",
"customCommand": "run e2e",
"customRegistry": "useNpmrc",
"customFeed": "",
"customEndpoint": "",
"publishRegistry": "useExternalRegistry",
"publishFeed": "",
"publishPackageMetadata": "true",
"publishEndpoint": ""
}
},
{
"environment": {},
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "Publish Test Results Project\\Frontend\\DefaultWebsite\\e2e\\**\\junitresults.xml",
"timeoutInMinutes": 0,
"condition": "succeeded()",
"task": {
"id": "0b0f01ed-7dde-43ff-9cbb-e48954daf9b1",
"versionSpec": "2.*",
"definitionType": "task"
},
"inputs": {
"testRunner": "JUnit",
"testResultsFiles": "Project\\Frontend\\DefaultWebsite\\e2e\\**\\junitresults.xml",
"searchFolder": "$(System.DefaultWorkingDirectory)",
"mergeTestResults": "false",
"failTaskOnFailedTests": "false",
"testRunTitle": "",
"platform": "",
"configuration": "",
"publishRunAttachments": "true"
}
},
{
"environment": {},
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "npm custom - prodBuild",
"timeoutInMinutes": 0,
"condition": "succeeded()",
"task": {
"id": "fe47e961-9fa8-4106-8639-368c022d43ad",
"versionSpec": "1.*",
"definitionType": "task"
},
"inputs": {
"command": "custom",
"workingDir": "Project\\Frontend\\DefaultWebsite",
"verbose": "false",
"customCommand": "run prodBuild",
"customRegistry": "useNpmrc",
"customFeed": "",
"customEndpoint": "",
"publishRegistry": "useExternalRegistry",
"publishFeed": "",
"publishPackageMetadata": "true",
"publishEndpoint": ""
}
},
{
"environment": {},
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "Publish Artifact: app",
"timeoutInMinutes": 0,
"condition": "succeeded()",
"task": {
"id": "2ff763a7-ce83-4e1f-bc89-0ae63477cebe",
"versionSpec": "1.*",
"definitionType": "task"
},
"inputs": {
"PathtoPublish": "Project\\Frontend\\DefaultWebsite\\dist",
"ArtifactName": "app",
"ArtifactType": "Container",
"TargetPath": "",
"Parallel": "false",
"ParallelCount": "8",
"FileCopyOptions": ""
}
}
],

MongoDB query double nested array

Below is my mongo db document named business
{
"_id": ObjectId("5be8e24a6600321ead321466"),
"business_id": "r89Re4FNgVWHgBfjCVZyVw",
"name": "Harlow",
"neighborhood": "Ville-Marie",
"address": "438 Place Jacques Cartier",
"city": "Montréal",
"state": "QC",
"postal_code": "H2Y 3B3",
"stars": 3.5,
"attributes": {
"Alcohol": "full_bar",
"BikeParking": "True",
"BusinessAcceptsCreditCards": "True",
"BusinessParking": "{'garage': False, 'street': False, 'validated': False, 'lot': False, 'valet': False}",
"Caters": "False",
"GoodForMeal": "{'dessert': False, 'latenight': False, 'lunch': False, 'dinner': False, 'breakfast': False, 'brunch': False}",
"RestaurantsDelivery": "False",
"RestaurantsGoodForGroups": "True",
},
"categories": "Nightlife, Bars, American (Traditional), Tapas/Small Plates, Poutineries, Supper Clubs, Restaurants, Tapas Bars",
}
Question:In the above collection named business i need to Find all restaurants which provides meal for lunch. (need to Check attributes-GoodForMeal-lunch)
it is nested array. please suggest me how can this be done with mongo db

TFS 2015 Rest API - Create Build Definition

I'm trying to create a build definition in TFS using his api rest for it.
This is the microsoft docs for TFS Api Rest
I get status code 200 but...
This is what i get when I look into Tfs build definition
Anyone knows why this is happening?
Your second link provided a screenshot that a build definition with no tasks. It seems you had created a build definition successfully, but you didn't add tasks in the build definition.
Check your rest api to see whether you have "build": [] parameter with "task" in it as the following example shows:
"build": [
{
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "Build solution **\\*.sln",
"task": {
"id": "71a9a2d3-a98a-4caa-96ab-affca411ecda",
"versionSpec": "*"
},
"inputs": {
"solution": "**\\*.sln",
"msbuildArgs": "",
"platform": "$(platform)",
"configuration": "$(config)",
"clean": "false",
"restoreNugetPackages": "true",
"vsLocationMethod": "version",
"vsVersion": "latest",
"vsLocation": "",
"msbuildLocationMethod": "version",
"msbuildVersion": "latest",
"msbuildArchitecture": "x86",
"msbuildLocation": "",
"logProjectEvents": "true"
}
},
{
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "Test Assemblies **\\*test*.dll;-:**\\obj\\**",
"task": {
"id": "ef087383-ee5e-42c7-9a53-ab56c98420f9",
"versionSpec": "*"
},
"inputs": {
"testAssembly": "**\\*test*.dll;-:**\\obj\\**",
"testFiltercriteria": "",
"runSettingsFile": "",
"codeCoverageEnabled": "true",
"otherConsoleOptions": "",
"vsTestVersion": "14.0",
"pathtoCustomTestAdapters": ""
}
}
],