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

[tests-only][full-ci]Store federated ocis user and token for e2e tests #11796

Merged
merged 1 commit into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 6 additions & 6 deletions tests/e2e/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@ export const config = {
keycloakRealm: process.env.KEYCLOAK_REALM ?? 'oCIS',
keycloakAdminUser: process.env.KEYCLOAK_ADMIN_USER ?? 'admin',
keycloakAdminPassword: process.env.KEYCLOAK_ADMIN_PASSWORD ?? 'admin',
get backendUrl() {
return withHttp(process.env.BACKEND_HOST || this.baseUrlOcis)
},
get frontendUrl() {
return withHttp(process.env.SERVER_HOST || this.baseUrlOcis)
},
get keycloakUrl() {
return withHttp(this.keycloakHost)
},
get keycloakLoginUrl() {
return withHttp(this.keycloakHost + '/admin/master/console')
},
// ocm config
federatedBaseUrlOcis: process.env.FEDERATED_BASE_URL_OCIS ?? 'federation-ocis:10200',
federatedServer: false,
get baseUrl() {
return withHttp(this.federatedServer ? this.federatedBaseUrlOcis : this.baseUrlOcis)
},
debug: process.env.DEBUG === 'true',
logLevel: process.env.LOG_LEVEL || 'silent',
// cucumber
Expand Down
42 changes: 35 additions & 7 deletions tests/e2e/cucumber/environment/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,15 @@ import {
createdLinkStore,
createdGroupStore,
createdUserStore,
keycloakCreatedUser
keycloakCreatedUser,
federatedUserStore
} from '../../support/store'
import { Group, User } from '../../support/types'
import { createdTokenStore, keycloakTokenStore } from '../../support/store/token'
import {
createdTokenStore,
federatedTokenStore,
keycloakTokenStore
} from '../../support/store/token'
import { removeTempUploadDirectory } from '../../support/utils/runtimeFs'
import {
setAccessTokenForKeycloakUser,
Expand Down Expand Up @@ -78,13 +83,20 @@ Before(async function (this: World, { pickle }: ITestCaseHookParameter) {
break
}
})

if (!config.basicAuth) {
const user = this.usersEnvironment.getUser({ key: 'admin' })
if (config.keycloak) {
await setAccessTokenForKeycloakOcisUser(user)
await setAccessTokenForKeycloakUser(user)
} else {
await setAccessAndRefreshToken(user)
if (isOcm(pickle)) {
config.federatedServer = true
amrita-shrestha marked this conversation as resolved.
Show resolved Hide resolved
// need to set tokens for federated oCIS admin
await setAccessAndRefreshToken(user)
config.federatedServer = false
}
}
}
})
Expand Down Expand Up @@ -122,7 +134,8 @@ const defaults = {
reportTracing: config.reportTracing
}

After(async function (this: World, { result, willBeRetried }: ITestCaseHookParameter) {
After(async function (this: World, { result, willBeRetried, pickle }: ITestCaseHookParameter) {
config.federatedServer = false
if (!result) {
return
}
Expand All @@ -136,12 +149,19 @@ After(async function (this: World, { result, willBeRetried }: ITestCaseHookParam
await refreshAccessTokenForKeycloakOcisUser(user)
}

await cleanUpUser(this.usersEnvironment.getUser({ key: 'admin' }))
if (isOcm(pickle)) {
// need to set federatedServer config to true to delete federated oCIS users
config.federatedServer = true
await cleanUpUser(federatedUserStore, this.usersEnvironment.getUser({ key: 'admin' }))
config.federatedServer = false
}
await cleanUpUser(createdUserStore, this.usersEnvironment.getUser({ key: 'admin' }))
await cleanUpSpaces(this.usersEnvironment.getUser({ key: 'admin' }))
await cleanUpGroup(this.usersEnvironment.getUser({ key: 'admin' }))

createdLinkStore.clear()
createdTokenStore.clear()
federatedTokenStore.clear()
keycloakTokenStore.clear()
removeTempUploadDirectory()
closeSSEConnections()
Expand Down Expand Up @@ -188,13 +208,13 @@ function filterTracingReports(status: string) {
}
}

const cleanUpUser = async (adminUser: User) => {
const cleanUpUser = async (store, adminUser: User) => {
const requests: Promise<User>[] = []
createdUserStore.forEach((user) => {
store.forEach((user) => {
requests.push(api.provision.deleteUser({ user, admin: adminUser }))
})
await Promise.all(requests)
createdUserStore.clear()
store.clear()
keycloakCreatedUser.clear()
}

Expand Down Expand Up @@ -230,3 +250,11 @@ const cleanUpGroup = async (adminUser: User) => {
await Promise.all(requests)
createdGroupStore.clear()
}

const isOcm = (pickle): boolean => {
const tags = pickle.tags.map((tag) => tag.name)
if (tags.includes('@ocm')) {
return true
}
return false
}
22 changes: 22 additions & 0 deletions tests/e2e/cucumber/features/ocm/ocm.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@ocm
Feature: federation management
As a user
I want to establish connection between multiple oCIS instance
So that I share resource

Scenario: user creates a federated share
Given using "LOCAL" server
And "Admin" creates following user using API
| id |
| Alice |
And "Alice" creates the following files into personal space using API
| pathToFile | content |
| example1.txt | example text |
And "Alice" logs in
And "Alice" logs out
Given using "FEDERATED" server
And "Admin" creates following user using API
| id |
| Brian |
And "Brian" logs in
And "Brian" logs out
19 changes: 16 additions & 3 deletions tests/e2e/cucumber/steps/ui/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ async function LogInUser(this: World, stepUser: string): Promise<void> {
? this.usersEnvironment.getUser({ key: stepUser })
: this.usersEnvironment.getCreatedUser({ key: stepUser })

await page.goto(config.frontendUrl)
await page.goto(config.baseUrl)
await sessionObject.login(user)

if (this.feature.tags.length > 0) {
Expand All @@ -33,7 +33,7 @@ async function LogInUser(this: World, stepUser: string): Promise<void> {

// listen to SSE events when running scenarios with '@sse' tag
if (tags.includes('@sse')) {
void listenSSE(config.frontendUrl, user)
void listenSSE(config.baseUrl, user)
}
}

Expand Down Expand Up @@ -62,7 +62,7 @@ Then('{string} fails to log in', async function (this: World, stepUser: string):
const { page } = this.actorsEnvironment.getActor({ key: stepUser })
const user = this.usersEnvironment.getUser({ key: stepUser })

await page.goto(config.frontendUrl)
await page.goto(config.baseUrl)
await page.locator('#oc-login-username').fill(user.id)
await page.locator('#oc-login-password').fill(user.password)
await page.locator('button[type="submit"]').click()
Expand Down Expand Up @@ -118,3 +118,16 @@ When(
await actor.closeCurrentTab()
}
)

Given('using {string} server', async function (this: World, server: string): Promise<void> {
switch (server) {
case 'LOCAL':
config.federatedServer = false
break
case 'FEDERATED':
config.federatedServer = true
break
default:
throw new Error(`Invalid server type: ${server}\nUse one of these: [LOCAL, FEDERATED]`)
}
})
2 changes: 1 addition & 1 deletion tests/e2e/support/api/graph/userManagement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export const addUserToGroup = async ({
const userId = usersEnvironment.getCreatedUser({ key: user.id }).uuid
const groupId = usersEnvironment.getCreatedGroup({ key: group.id }).uuid
const body = JSON.stringify({
'@odata.id': join(config.backendUrl, 'graph', 'v1.0', 'users', userId)
'@odata.id': join(config.baseUrl, 'graph', 'v1.0', 'users', userId)
})

const response = await request({
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/support/api/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const request = async ({
...header
}

const baseUrl = isKeycloakRequest ? config.keycloakUrl : config.backendUrl
const baseUrl = isKeycloakRequest ? config.keycloakUrl : config.baseUrl

return await fetch(join(baseUrl, path), {
method,
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/support/api/keycloak/ocisUserToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ interface ocisTokenForKeycloak {

const authorizationEndpoint = config.keycloakUrl + '/realms/oCIS/protocol/openid-connect/auth'
const tokenEndpoint = config.keycloakUrl + '/realms/oCIS/protocol/openid-connect/token'
const redirectUrl = config.backendUrl + '/oidc-callback.html'
const redirectUrl = config.baseUrl + '/oidc-callback.html'

async function getAuthorizationEndPoint() {
const loginParams = {
Expand Down
18 changes: 9 additions & 9 deletions tests/e2e/support/api/token/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,29 @@ import { config } from '../../../config'
import fetch, { Response } from 'node-fetch'
import { User } from '../../types'

const logonUrl = config.backendUrl + '/signin/v1/identifier/_/logon'
const redirectUrl = config.backendUrl + '/oidc-callback.html'
const tokenUrl = config.backendUrl + '/konnect/v1/token'
const logonUrl = '/signin/v1/identifier/_/logon'
const redirectUrl = '/oidc-callback.html'
const tokenUrl = '/konnect/v1/token'

interface Token {
access_token: string
refresh_token: string
}

const getAuthorizedEndPoint = async (user: User): Promise<Array<string>> => {
const logonResponse = await fetch(logonUrl, {
const logonResponse = await fetch(config.baseUrl + logonUrl, {
method: 'POST',
headers: {
'Kopano-Konnect-XSRF': '1',
Referer: config.backendUrl,
Referer: config.baseUrl,
'Content-Type': 'application/json'
},
body: JSON.stringify({
params: [user.id, user.password, '1'],
hello: {
scope: 'openid profile email',
client_id: 'web',
redirect_uri: redirectUrl,
redirect_uri: config.baseUrl + redirectUrl,
flow: 'oidc'
}
})
Expand All @@ -52,7 +52,7 @@ const getCode = async ({
const params = new URLSearchParams({
client_id: 'web',
prompt: 'none',
redirect_uri: redirectUrl,
redirect_uri: config.baseUrl + redirectUrl,
response_mode: 'query',
response_type: 'code',
scope: 'openid profile offline_access email'
Expand Down Expand Up @@ -81,12 +81,12 @@ const getCode = async ({
}

const getToken = async (code: string): Promise<Response> => {
const response = await fetch(tokenUrl, {
const response = await fetch(config.baseUrl + tokenUrl, {
method: 'POST',
body: new URLSearchParams({
client_id: 'web',
code: code,
redirect_uri: redirectUrl,
redirect_uri: config.baseUrl + redirectUrl,
grant_type: 'authorization_code'
})
})
Expand Down
9 changes: 6 additions & 3 deletions tests/e2e/support/environment/token.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createdTokenStore, keycloakTokenStore } from '../store/token'
import { createdTokenStore, federatedTokenStore, keycloakTokenStore } from '../store/token'
import { Token, User } from '../types'
import { config } from '../../config'

export type TokenProviderType = 'keycloak' | null | undefined
export type TokenEnvironmentType = KeycloakTokenEnvironment | IdpTokenEnvironment
Expand All @@ -15,11 +16,13 @@ export function TokenEnvironmentFactory(type?: TokenProviderType) {

class IdpTokenEnvironment {
getToken({ user }: { user: User }): Token {
return createdTokenStore.get(user.id)
const store = config.federatedServer ? federatedTokenStore : createdTokenStore
return store.get(user.id)
}

setToken({ user, token }: { user: User; token: Token }): Token {
createdTokenStore.set(user.id, token)
const store = config.federatedServer ? federatedTokenStore : createdTokenStore
store.set(user.id, token)
return token
}

Expand Down
20 changes: 12 additions & 8 deletions tests/e2e/support/environment/userManagement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import {
dummyGroupStore,
createdUserStore,
createdGroupStore,
keycloakCreatedUser
keycloakCreatedUser,
federatedUserStore
} from '../store'
import { config } from '../../config'

export class UsersEnvironment {
getUser({ key }: { key: string }): User {
Expand All @@ -31,21 +33,22 @@ export class UsersEnvironment {
}

storeCreatedUser({ user }: { user: User }): User {
if (createdUserStore.has(user.id)) {
const store = config.federatedServer ? federatedUserStore : createdUserStore
if (store.has(user.id)) {
throw new Error(`user '${user.id}' already exists`)
}
createdUserStore.set(user.id, user)

store.set(user.id, user)
return user
}

getCreatedUser({ key }: { key: string }): User {
const store = config.federatedServer ? federatedUserStore : createdUserStore
const userKey = key.toLowerCase()
if (!createdUserStore.has(userKey)) {
if (!store.has(userKey)) {
throw new Error(`user with key '${userKey}' not found`)
}

return createdUserStore.get(userKey)
return store.get(userKey)
}

updateCreatedUser({ key, user }: { key: string; user: User }): User {
Expand All @@ -60,13 +63,14 @@ export class UsersEnvironment {
}

removeCreatedUser({ key }: { key: string }): boolean {
const store = config.federatedServer ? federatedUserStore : createdUserStore
const userKey = key.toLowerCase()

if (!createdUserStore.has(userKey)) {
if (!store.has(userKey)) {
throw new Error(`user '${userKey}' not found`)
}

return createdUserStore.delete(userKey)
return store.delete(userKey)
}

getGroup({ key }: { key: string }): Group {
Expand Down
Loading