Skip to content

[PROD] Post Release Patch 1.5.3 #167

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

Merged
merged 11 commits into from
Mar 9, 2021
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
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,21 @@
- first it would be waiting for `kafka-client` to create all the required topics and exit, you would see:

```
tc-taas-es-procesor | Waiting for kafka-client to exit....
tc-taas-es-processor | Waiting for kafka-client to exit....
```

- after that, `taas-es-processor` would be started itself. Make sure it successfully connected to Kafka, you should see 9 lines with text `Subscribed to taas.`:

```
tc-taas-es-procesor | 2021-01-22T14:27:48.971Z DEBUG no-kafka-client Subscribed to taas.jobcandidate.create:0 offset 0 leader kafka:9093
tc-taas-es-procesor | 2021-01-22T14:27:48.972Z DEBUG no-kafka-client Subscribed to taas.job.create:0 offset 0 leader kafka:9093
tc-taas-es-procesor | 2021-01-22T14:27:48.972Z DEBUG no-kafka-client Subscribed to taas.resourcebooking.delete:0 offset 0 leader kafka:9093
tc-taas-es-procesor | 2021-01-22T14:27:48.973Z DEBUG no-kafka-client Subscribed to taas.jobcandidate.delete:0 offset 0 leader kafka:9093
tc-taas-es-procesor | 2021-01-22T14:27:48.974Z DEBUG no-kafka-client Subscribed to taas.jobcandidate.update:0 offset 0 leader kafka:9093
tc-taas-es-procesor | 2021-01-22T14:27:48.975Z DEBUG no-kafka-client Subscribed to taas.resourcebooking.create:0 offset 0 leader kafka:9093
tc-taas-es-procesor | 2021-01-22T14:27:48.976Z DEBUG no-kafka-client Subscribed to taas.job.delete:0 offset 0 leader kafka:9093
tc-taas-es-procesor | 2021-01-22T14:27:48.977Z DEBUG no-kafka-client Subscribed to taas.job.update:0 offset 0 leader kafka:9093
tc-taas-es-procesor | 2021-01-22T14:27:48.978Z DEBUG no-kafka-client Subscribed to taas.resourcebooking.update:0 offset 0 leader kafka:9093
tc-taas-es-processor | 2021-01-22T14:27:48.971Z DEBUG no-kafka-client Subscribed to taas.jobcandidate.create:0 offset 0 leader kafka:9093
tc-taas-es-processor | 2021-01-22T14:27:48.972Z DEBUG no-kafka-client Subscribed to taas.job.create:0 offset 0 leader kafka:9093
tc-taas-es-processor | 2021-01-22T14:27:48.972Z DEBUG no-kafka-client Subscribed to taas.resourcebooking.delete:0 offset 0 leader kafka:9093
tc-taas-es-processor | 2021-01-22T14:27:48.973Z DEBUG no-kafka-client Subscribed to taas.jobcandidate.delete:0 offset 0 leader kafka:9093
tc-taas-es-processor | 2021-01-22T14:27:48.974Z DEBUG no-kafka-client Subscribed to taas.jobcandidate.update:0 offset 0 leader kafka:9093
tc-taas-es-processor | 2021-01-22T14:27:48.975Z DEBUG no-kafka-client Subscribed to taas.resourcebooking.create:0 offset 0 leader kafka:9093
tc-taas-es-processor | 2021-01-22T14:27:48.976Z DEBUG no-kafka-client Subscribed to taas.job.delete:0 offset 0 leader kafka:9093
tc-taas-es-processor | 2021-01-22T14:27:48.977Z DEBUG no-kafka-client Subscribed to taas.job.update:0 offset 0 leader kafka:9093
tc-taas-es-processor | 2021-01-22T14:27:48.978Z DEBUG no-kafka-client Subscribed to taas.resourcebooking.update:0 offset 0 leader kafka:9093
```

</details>
Expand Down
5 changes: 5 additions & 0 deletions config/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,13 @@ module.exports = {
// the emails address for receiving the issue report
// REPORT_ISSUE_EMAILS may contain comma-separated list of email which is converted to array
REPORT_ISSUE_EMAILS: (process.env.REPORT_ISSUE_EMAILS || '').split(','),
// the emails address for receiving the issue report
// REPORT_ISSUE_EMAILS may contain comma-separated list of email which is converted to array
REQUEST_EXTENSION_EMAILS: (process.env.REQUEST_EXTENSION_EMAILS || '').split(','),
// SendGrid email template ID for reporting issue
REPORT_ISSUE_SENDGRID_TEMPLATE_ID: process.env.REPORT_ISSUE_SENDGRID_TEMPLATE_ID,
// SendGrid email template ID for requesting extension
REQUEST_EXTENSION_SENDGRID_TEMPLATE_ID: process.env.REQUEST_EXTENSION_SENDGRID_TEMPLATE_ID,
// the URL where TaaS App is hosted
TAAS_APP_URL: process.env.TAAS_APP_URL || 'https://platform.topcoder-dev.com/taas/myteams'
}
20 changes: 20 additions & 0 deletions config/email_template.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ module.exports = {
recipients: config.REPORT_ISSUE_EMAILS,
sendgridTemplateId: config.REPORT_ISSUE_SENDGRID_TEMPLATE_ID
},

/* Report issue for a particular member
*
* - userHandle: the user handle. Example: "bili_2021"
Expand All @@ -39,5 +40,24 @@ module.exports = {
'{{reportText}}',
recipients: config.REPORT_ISSUE_EMAILS,
sendgridTemplateId: config.REPORT_ISSUE_SENDGRID_TEMPLATE_ID
},

/* Request extension for a particular member
*
* - userHandle: the user handle. Example: "bili_2021"
* - projectId: the project ID. Example: 123412
* - projectName: the project name. Example: "TaaS API Misc Updates"
* - text: comment for the request. Example: "I would like to keep working with this member for 2 months..."
*/
'extension-request': {
subject: 'Extension Requested for member {{userHandle}} on TaaS Team {{projectName}} ({{projectId}}).',
body: 'User Handle: {{userHandle}}' + '\n' +
'Project Name: {{projectName}}' + '\n' +
'Project ID: {{projectId}}' + '\n' +
`Project URL: ${config.TAAS_APP_URL}/{{projectId}}` + '\n' +
'\n' +
'{{text}}',
recipients: config.REPORT_ISSUE_EMAILS,
sendgridTemplateId: config.REQUEST_EXTENSION_SENDGRID_TEMPLATE_ID
}
}
132 changes: 85 additions & 47 deletions docs/Topcoder-bookings-api.postman_collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -4407,7 +4407,7 @@
},
"response": []
},
{
{
"name": "POST /taas-teams/email - team-issue-report",
"request": {
"method": "POST",
Expand Down Expand Up @@ -4483,51 +4483,89 @@
},
"response": []
},
{
"name": "POST /taas-teams/:id/members",
"request": {
"method": "POST",
"header": [
{
"key": "Authorization",
"type": "text",
"value": "Bearer {{token_administrator}}"
},
{
"key": "Content-Type",
"type": "text",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"handles\": [\n \"tester1234\",\n \"non-existing\"\n ],\n \"emails\": [\n \"non-existing@domain.com\",\n \"email@domain.com\"\n ]\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{URL}}/taas-teams/:id/members",
"host": [
"{{URL}}"
],
"path": [
"taas-teams",
":id",
"members"
],
"variable": [
{
"key": "id",
"value": "16705"
}
]
}
},
"response": []
},
{
"name": "POST /taas-teams/email - extension-request",
"request": {
"method": "POST",
"header": [
{
"key": "Authorization",
"type": "text",
"value": "Bearer {{token_member}}"
},
{
"key": "Content-Type",
"type": "text",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"template\": \"extension-request\",\n \"data\": {\n \"projectName\": \"TaaS Project Name\",\n \"projectId\": 12345,\n \"userHandle\": \"pshah_manager\",\n \"reportText\": \"I would like to keep working with this member for 2 months...\"\n }\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{URL}}/taas-teams/email",
"host": [
"{{URL}}"
],
"path": [
"taas-teams",
"email"
]
}
},
"response": []
},
{
"name": "POST /taas-teams/:id/members",
"request": {
"method": "POST",
"header": [
{
"key": "Authorization",
"type": "text",
"value": "Bearer {{token_administrator}}"
},
{
"key": "Content-Type",
"type": "text",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"handles\": [\n \"tester1234\",\n \"non-existing\"\n ],\n \"emails\": [\n \"non-existing@domain.com\",\n \"email@domain.com\"\n ]\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{URL}}/taas-teams/:id/members",
"host": [
"{{URL}}"
],
"path": [
"taas-teams",
":id",
"members"
],
"variable": [
{
"key": "id",
"value": "16705"
}
]
}
},
"response": []
},
{
"name": "GET /taas-teams/:id/members",
"request": {
Expand Down Expand Up @@ -9772,4 +9810,4 @@
]
}
]
}
}
22 changes: 22 additions & 0 deletions docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ paths:
Create job.

**Authorization** All topcoder members are allowed

Permission rules on field `isApplicationPageActive`:
- M2M user is allowed to set the value of the field
- Other users are not allowed to set the value of the field

security:
- bearerAuth: []
requestBody:
Expand Down Expand Up @@ -352,6 +357,10 @@ paths:
Update the job.

**Authorization** Every topcoder member can update the job he/she created. bookingmanager and connectmember can update all jobs.

Permission rules on field `isApplicationPageActive`:
- M2M user is allowed to update the value of the field
- Other users are not allowed to update the value of the field
security:
- bearerAuth: []
parameters:
Expand Down Expand Up @@ -413,6 +422,10 @@ paths:
Update job.

**Authorization** Topcoder token with patch job scope is allowed

Permission rules on field `isApplicationPageActive`:
- M2M user is allowed to update the value of the field
- Other users are not allowed to update the value of the field
security:
- bearerAuth: []
parameters:
Expand Down Expand Up @@ -1980,6 +1993,9 @@ components:
description: "The job candidates."
items:
$ref: '#/components/schemas/JobCandidate'
isApplicationPageActive:
type: boolean
default: false
createdAt:
type: string
format: date-time
Expand Down Expand Up @@ -2057,6 +2073,9 @@ components:
type: string
format: uuid
description: "The skill id."
isApplicationPageActive:
type: boolean
default: false
JobCandidate:
required:
- id
Expand Down Expand Up @@ -2186,6 +2205,9 @@ components:
type: string
format: uuid
description: "The skill id."
isApplicationPageActive:
type: boolean
default: false
ResourceBooking:
required:
- id
Expand Down
2 changes: 1 addition & 1 deletion local/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ services:
- 9200:9200

taas-es-processor:
container_name: tc-taas-es-procesor
container_name: tc-taas-es-processor
build:
context: ./generic-tc-service
args:
Expand Down
19 changes: 19 additions & 0 deletions migrations/2021-02-27-job-add-is-application-page-active-field.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Add isApplicationPageActive field to the Job model.
*/

module.exports = {
up: queryInterface => {
return Promise.all([
queryInterface.sequelize.query('ALTER TABLE bookings.jobs ADD is_application_page_active BOOLEAN NOT NULL DEFAULT false'),
// this command looks like does nothing, because we already set default value to `null` and this column cannot be `NULL`
// but we keep it as it was tested this way, and it looks harmful
queryInterface.sequelize.query('UPDATE bookings.jobs SET is_application_page_active=false WHERE is_application_page_active is NULL'),
])
},
down: queryInterface => {
return Promise.all([
queryInterface.sequelize.query('ALTER TABLE bookings.jobs DROP is_application_page_active')
])
}
}
1 change: 1 addition & 0 deletions src/common/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ esIndexPropertyMapping[config.get('esConfig.ES_INDEX_JOB')] = {
workload: { type: 'keyword' },
skills: { type: 'keyword' },
status: { type: 'keyword' },
isApplicationPageActive: { type: 'boolean' },
createdAt: { type: 'date' },
createdBy: { type: 'keyword' },
updatedAt: { type: 'date' },
Expand Down
6 changes: 6 additions & 0 deletions src/models/Job.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ module.exports = (sequelize) => {
type: Sequelize.STRING(255),
allowNull: false
},
isApplicationPageActive: {
field: 'is_application_page_active',
type: Sequelize.BOOLEAN,
defaultValue: false,
allowNull: false
},
createdBy: {
field: 'created_by',
type: Sequelize.UUID,
Expand Down
20 changes: 17 additions & 3 deletions src/services/JobService.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,11 @@ async function createJob (currentUser, job) {
await helper.checkIsMemberOfProject(currentUser.userId, job.projectId)
}

// the "isApplicationPageActive" field can be set/updated only by M2M user
if (!_.isUndefined(job.isApplicationPageActive) && !currentUser.isMachine) {
throw new errors.ForbiddenError('You are not allowed to set/update the value of field "isApplicationPageActive".')
}

await _validateSkills(job.skills)
job.id = uuid()
job.createdBy = await helper.getUserId(currentUser.userId)
Expand All @@ -171,7 +176,8 @@ createJob.schema = Joi.object().keys({
resourceType: Joi.stringAllowEmpty().allow(null),
rateType: Joi.rateType().allow(null),
workload: Joi.workload().allow(null),
skills: Joi.array().items(Joi.string().uuid()).required()
skills: Joi.array().items(Joi.string().uuid()).required(),
isApplicationPageActive: Joi.boolean()
}).required()
}).required()

Expand All @@ -188,6 +194,12 @@ async function updateJob (currentUser, id, data) {
}
let job = await Job.findById(id)
const oldValue = job.toJSON()

// the "isApplicationPageActive" field can be set/updated only by M2M user
if (!_.isUndefined(data.isApplicationPageActive) && !currentUser.isMachine) {
throw new errors.ForbiddenError('You are not allowed to set/update the value of field "isApplicationPageActive".')
}

const ubahnUserId = await helper.getUserId(currentUser.userId)
if (!currentUser.hasManagePermission && !currentUser.isMachine) {
// Check whether user can update the job.
Expand Down Expand Up @@ -232,7 +244,8 @@ partiallyUpdateJob.schema = Joi.object().keys({
resourceType: Joi.stringAllowEmpty().allow(null),
rateType: Joi.rateType().allow(null),
workload: Joi.workload().allow(null),
skills: Joi.array().items(Joi.string().uuid())
skills: Joi.array().items(Joi.string().uuid()),
isApplicationPageActive: Joi.boolean()
}).required()
}).required()

Expand Down Expand Up @@ -262,7 +275,8 @@ fullyUpdateJob.schema = Joi.object().keys({
rateType: Joi.rateType().allow(null).default(null),
workload: Joi.workload().allow(null).default(null),
skills: Joi.array().items(Joi.string().uuid()).required(),
status: Joi.jobStatus().default('sourcing')
status: Joi.jobStatus().default('sourcing'),
isApplicationPageActive: Joi.boolean()
}).required()
}).required()

Expand Down