Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SNOW-1881731] Add externalBrowser, oauth, okta, keypair automated authentication tests #1082

Merged
merged 44 commits into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
688a1a7
init work, before review, without cicd
sfc-gh-pcyrek Jan 23, 2025
029a16d
after initial review
sfc-gh-pcyrek Jan 27, 2025
63c289f
jenkinsfile edit
sfc-gh-pcyrek Jan 27, 2025
98f1238
move params into jenkins
sfc-gh-pcyrek Jan 27, 2025
7c3a967
changes in jenkinsfile
sfc-gh-pcyrek Jan 27, 2025
2886a8b
jenkinsfile with waiting
sfc-gh-pcyrek Jan 27, 2025
fb75015
image name change jenkins
sfc-gh-pcyrek Jan 27, 2025
d1a1cdf
diagnostic jenkins
sfc-gh-pcyrek Jan 27, 2025
0e403f6
with agent
sfc-gh-pcyrek Jan 27, 2025
d3b9dab
without browser
sfc-gh-pcyrek Jan 27, 2025
d512986
no mismatched user
sfc-gh-pcyrek Jan 27, 2025
a90deca
only one test
sfc-gh-pcyrek Jan 28, 2025
698a726
adding stamps
sfc-gh-pcyrek Jan 28, 2025
37dfd04
s_logger
sfc-gh-pcyrek Jan 28, 2025
120d396
more params, edited jenkinsfile
sfc-gh-pcyrek Jan 28, 2025
97d9336
fixjenkins
sfc-gh-pcyrek Jan 28, 2025
e2d194b
cleanup jenkins
sfc-gh-pcyrek Jan 28, 2025
3e3bc21
without basetest
sfc-gh-pcyrek Jan 28, 2025
e95071f
without fixtures
sfc-gh-pcyrek Jan 28, 2025
4eece68
creating parameters.json
sfc-gh-pcyrek Jan 28, 2025
913e2ec
different test set
sfc-gh-pcyrek Jan 28, 2025
f924d25
silent sfbasetest
sfc-gh-pcyrek Jan 28, 2025
554477f
changing name space
sfc-gh-pcyrek Jan 28, 2025
e1f0794
oauth test
sfc-gh-pcyrek Jan 28, 2025
1ba357d
add externalbrowser
sfc-gh-pcyrek Jan 28, 2025
5489a9b
externalbrowser on
sfc-gh-pcyrek Jan 29, 2025
6c2b04f
more tests added
sfc-gh-pcyrek Jan 29, 2025
772c236
Merge branch 'master' into pcyrek/authentication-tests
sfc-gh-pcyrek Jan 29, 2025
45367d1
specify only .net 9
sfc-gh-pcyrek Jan 29, 2025
69dee96
ignore on ci import
sfc-gh-pcyrek Jan 29, 2025
bee0b3f
without parameters.json in docker
sfc-gh-pcyrek Jan 29, 2025
343dc82
test with different namespace
sfc-gh-pcyrek Jan 29, 2025
21acb6e
cleanup
sfc-gh-pcyrek Jan 29, 2025
6eb6251
comment oauth test
sfc-gh-pcyrek Jan 29, 2025
715d134
ignoreOnCI
sfc-gh-pcyrek Jan 29, 2025
3b54397
Merge branch 'master' into pcyrek/authentication-tests
sfc-gh-pcyrek Jan 29, 2025
ad5dcac
convert to connection string
sfc-gh-pcyrek Jan 29, 2025
ccb5b97
after review
sfc-gh-pcyrek Jan 30, 2025
092a07c
Merge branch 'master' into pcyrek/authentication-tests
sfc-gh-pcyrek Jan 30, 2025
5d8b334
review2
sfc-gh-pcyrek Jan 30, 2025
1d01960
review3
sfc-gh-pcyrek Jan 30, 2025
1aacad4
review4
sfc-gh-pcyrek Jan 30, 2025
793cd94
review6
sfc-gh-pcyrek Jan 30, 2025
b75825e
review7
sfc-gh-pcyrek Jan 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
sfc-gh-knozderko marked this conversation as resolved.
Show resolved Hide resolved
Binary file not shown.
Binary file not shown.
Binary file not shown.
46 changes: 30 additions & 16 deletions Jenkinsfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import groovy.json.JsonOutput


timestamps {
node('regular-memory-node') {
stage('checkout') {
Expand All @@ -13,8 +12,8 @@ timestamps {
stage('Build') {
withCredentials([
usernamePassword(credentialsId: '063fc85b-62a6-4181-9d72-873b43488411', usernameVariable: 'AWS_ACCESS_KEY_ID', passwordVariable: 'AWS_SECRET_ACCESS_KEY'),
string(credentialsId: 'a791118f-a1ea-46cd-b876-56da1b9bc71c',variable: 'NEXUS_PASSWORD')
]) {
string(credentialsId: 'a791118f-a1ea-46cd-b876-56da1b9bc71c', variable: 'NEXUS_PASSWORD')
]) {
sh '''\
|#!/bin/bash -e
|export GIT_BRANCH=${GIT_BRANCH}
Expand All @@ -23,7 +22,8 @@ timestamps {
'''.stripMargin()
}
}
params = [

def params = [
string(name: 'svn_revision', value: 'bptp-built'),
string(name: 'branch', value: 'main'),
string(name: 'client_git_commit', value: scmInfo.GIT_COMMIT),
Expand All @@ -32,23 +32,37 @@ timestamps {
string(name: 'parent_job', value: env.JOB_NAME),
string(name: 'parent_build_number', value: env.BUILD_NUMBER)
]

stage('Test') {
build job: 'RT-LanguageDotnet-PC',parameters: params
parallel(
'Test': {
stage('Test') {
build job: 'RT-LanguageDotnet-PC', parameters: params
}
},
'Test Authentication': {
stage('Test Authentication') {
withCredentials([
string(credentialsId: 'a791118f-a1ea-46cd-b876-56da1b9bc71c', variable: 'NEXUS_PASSWORD'),
string(credentialsId: 'sfctest0-parameters-secret', variable: 'PARAMETERS_SECRET')
]) {
sh '''\
|#!/bin/bash -e
|$WORKSPACE/ci/test_authentication.sh
'''.stripMargin()
}
}
}
)
}
}
}


pipeline {
agent { label 'regular-memory-node' }
options { timestamps() }
environment {
COMMIT_SHA_LONG = sh(returnStdout: true, script: "echo \$(git rev-parse " + "HEAD)").trim()

// environment variables for semgrep_agent (for findings / analytics page)
// remove .git at the end
// remove SCM URL + .git at the end

COMMIT_SHA_LONG = sh(returnStdout: true, script: "echo \$(git rev-parse HEAD)").trim()
BASELINE_BRANCH = "${env.CHANGE_TARGET}"
}
stages {
Expand All @@ -61,7 +75,7 @@ pipeline {
}

def wgetUpdateGithub(String state, String folder, String targetUrl, String seconds) {
def ghURL = "https://api.github.com/repos/snowflakedb/snowflake-connector-net/statuses/$COMMIT_SHA_LONG"
def data = JsonOutput.toJson([state: "${state}", context: "jenkins/${folder}",target_url: "${targetUrl}"])
sh "wget ${ghURL} --spider -q --header='Authorization: token $GIT_PASSWORD' --post-data='${data}'"
}
def ghURL = "https://api.github.com/repos/snowflakedb/snowflake-connector-net/statuses/$COMMIT_SHA_LONG"
def data = JsonOutput.toJson([state: "${state}", context: "jenkins/${folder}", target_url: "${targetUrl}"])
sh "wget ${ghURL} --spider -q --header='Authorization: token $GIT_PASSWORD' --post-data='${data}'"
}
162 changes: 162 additions & 0 deletions Snowflake.Data.Tests/AuthenticationTests/AuthConnectionString.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
using System;
sfc-gh-knozderko marked this conversation as resolved.
Show resolved Hide resolved
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json.Linq;
using NUnit.Framework;
using System.IO;
using Snowflake.Data.Core;
using System.Net.Http;

namespace Snowflake.Data.AuthenticationTests

{
static class AuthConnectionString
{
public static readonly string SsoUser = Environment.GetEnvironmentVariable("SNOWFLAKE_AUTH_TEST_BROWSER_USER");
public static readonly string Host = Environment.GetEnvironmentVariable("SNOWFLAKE_AUTH_TEST_HOST");
public static readonly string SsoPassword = Environment.GetEnvironmentVariable("SNOWFLAKE_TEST_OKTA_PASS");

public static SFSessionProperties GetBaseConnectionString()
{
var properties = new SFSessionProperties()
{
{SFSessionProperty.HOST, Host },
{SFSessionProperty.PORT, Environment.GetEnvironmentVariable("SNOWFLAKE_AUTH_TEST_PORT") },
{SFSessionProperty.ROLE, Environment.GetEnvironmentVariable("SNOWFLAKE_AUTH_TEST_ROLE") },
{SFSessionProperty.ACCOUNT, Environment.GetEnvironmentVariable("SNOWFLAKE_AUTH_TEST_ACCOUNT") },
{SFSessionProperty.DB, Environment.GetEnvironmentVariable("SNOWFLAKE_AUTH_TEST_DATABASE") },
{SFSessionProperty.SCHEMA, Environment.GetEnvironmentVariable("SNOWFLAKE_AUTH_TEST_SCHEMA") },
{SFSessionProperty.WAREHOUSE, Environment.GetEnvironmentVariable("SNOWFLAKE_AUTH_TEST_WAREHOUSE") },
};
return properties;
}

public static string SetBaseConnectionString(SFSessionProperties parameters) =>
$"host={parameters[SFSessionProperty.HOST]};port={parameters[SFSessionProperty.PORT]};account={parameters[SFSessionProperty.ACCOUNT]};role={parameters[SFSessionProperty.ROLE]};db={parameters[SFSessionProperty.DB]};schema={parameters[SFSessionProperty.SCHEMA]};warehouse={parameters[SFSessionProperty.WAREHOUSE]};";


public static SFSessionProperties GetExternalBrowserConnectionString()
{
var properties = GetBaseConnectionString();
properties.Add(SFSessionProperty.AUTHENTICATOR, "externalbrowser");
properties.Add(SFSessionProperty.USER, Environment.GetEnvironmentVariable("SNOWFLAKE_AUTH_TEST_BROWSER_USER"));
return properties;
}

public static string SetExternalBrowserConnectionString(SFSessionProperties parameters) =>
$"{SetBaseConnectionString(parameters)}authenticator={parameters[SFSessionProperty.AUTHENTICATOR]};user={parameters[SFSessionProperty.USER]};";


public static SFSessionProperties GetOauthConnectionString(string token)
{
var properties = GetBaseConnectionString();
properties.Add(SFSessionProperty.AUTHENTICATOR, "OAUTH");
properties.Add(SFSessionProperty.USER, SsoUser);
properties.Add(SFSessionProperty.TOKEN, token);
return properties;
}

public static string SetOauthConnectionString(SFSessionProperties parameters) =>
$"{SetBaseConnectionString(parameters)}authenticator={parameters[SFSessionProperty.AUTHENTICATOR]};user={parameters[SFSessionProperty.USER]};token={parameters[SFSessionProperty.TOKEN]};";

public static SFSessionProperties GetOktaConnectionString()
{
var properties = GetBaseConnectionString();
properties.Add(SFSessionProperty.AUTHENTICATOR, Environment.GetEnvironmentVariable("SNOWFLAKE_AUTH_TEST_OAUTH_URL"));
properties.Add(SFSessionProperty.USER, SsoUser);
properties.Add(SFSessionProperty.PASSWORD, SsoPassword);

return properties;
}

public static SFSessionProperties GetKeyPairFromFileContentParameters(string privateKey)
{

var properties = GetBaseConnectionString();
properties.Add(SFSessionProperty.AUTHENTICATOR, "snowflake_jwt");
properties.Add(SFSessionProperty.USER, SsoUser);
properties.Add(SFSessionProperty.PRIVATE_KEY, privateKey);

return properties;
}


public static SFSessionProperties GetKeyPairFromFilePathConnectionString(string privateKeyPath)
{

var properties = GetBaseConnectionString();
properties.Add(SFSessionProperty.AUTHENTICATOR, "snowflake_jwt");
properties.Add(SFSessionProperty.USER, AuthConnectionString.SsoUser);
properties.Add(SFSessionProperty.PRIVATE_KEY_FILE, privateKeyPath);
return properties;
}
public static string SetPrivateKeyFromFileContentConnectionString(SFSessionProperties parameters) =>
$"{SetBaseConnectionString(parameters)}authenticator={parameters[SFSessionProperty.AUTHENTICATOR]};private_key={parameters[SFSessionProperty.PRIVATE_KEY]};user={SsoUser}";


public static string SetPrivateKeyFromFilePathConnectionString(SFSessionProperties parameters) =>
$"{SetBaseConnectionString(parameters)}authenticator={parameters[SFSessionProperty.AUTHENTICATOR]};private_key_file={parameters[SFSessionProperty.PRIVATE_KEY_FILE]};user={SsoUser}";


public static string SetOktaConnectionString(SFSessionProperties parameters) =>
$"{SetBaseConnectionString(parameters)}authenticator={parameters[SFSessionProperty.AUTHENTICATOR]};user={parameters[SFSessionProperty.USER]};password={parameters[SFSessionProperty.PASSWORD]};";


public static string GetPrivateKeyContentForKeypairAuth(string fileLocation)
{
string filePath = Environment.GetEnvironmentVariable(fileLocation);
Assert.IsNotNull(filePath);
string pemKey = File.ReadAllText(Path.Combine("..", "..", "..", "..", filePath));
Assert.IsNotNull(pemKey, $"Failed to read file: {filePath}");
return pemKey;

}

public static string GetPrivateKeyPathForKeypairAuth(string fileLocation)
{
string filePath = Environment.GetEnvironmentVariable(fileLocation);
Assert.IsNotNull(filePath);
return Path.Combine("..", "..", "..", "..", filePath);
}

public static string GetOauthToken()
{
try
{

using (var client = new HttpClient())
{
var authUrl = Environment.GetEnvironmentVariable("SNOWFLAKE_AUTH_TEST_OAUTH_URL");
var clientId = Environment.GetEnvironmentVariable("SNOWFLAKE_AUTH_TEST_OAUTH_CLIENT_ID");
var clientSecret = Environment.GetEnvironmentVariable("SNOWFLAKE_AUTH_TEST_OAUTH_CLIENT_SECRET");
var credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{clientId}:{clientSecret}"));
sfc-gh-knozderko marked this conversation as resolved.
Show resolved Hide resolved

client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", credentials);

var values = new Dictionary<string, string>
{
{ "username", Environment.GetEnvironmentVariable("SNOWFLAKE_AUTH_TEST_OKTA_USER") },
{ "password", Environment.GetEnvironmentVariable("SNOWFLAKE_AUTH_TEST_OKTA_PASS") },
{ "grant_type", "password" },
{ "scope", "session:role:" + Environment.GetEnvironmentVariable("SNOWFLAKE_AUTH_TEST_ROLE") }
};

var content = new FormUrlEncodedContent(values);
var response = client.PostAsync(authUrl, content).Result;
response.EnsureSuccessStatusCode();

var fullResponse = response.Content.ReadAsStringAsync().Result;
var responseObject = JObject.Parse(fullResponse);
Assert.IsNotNull(responseObject["access_token"]);
return responseObject["access_token"].ToString();
}
}
catch (Exception e)
{
Assert.Fail($"Failed to get OAuth token: {e.Message}");
return null;
sfc-gh-knozderko marked this conversation as resolved.
Show resolved Hide resolved
}

sfc-gh-knozderko marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
Loading
Loading