fix: authenticate weblate requests (#6790)
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
This commit is contained in:
4
app.json
4
app.json
@@ -31,6 +31,10 @@
|
||||
"TWITCH_CLIENT_SECRET": {
|
||||
"description": "Configure the client secret to be used for the Twitch service.",
|
||||
"required": false
|
||||
},
|
||||
"WEBLATE_API_KEY": {
|
||||
"description": "Configure the API key to be used for the Weblate service.",
|
||||
"required": false
|
||||
}
|
||||
},
|
||||
"formation": {
|
||||
|
||||
@@ -52,6 +52,8 @@ public:
|
||||
authorizedOrigins: 'SONAR_ORIGINS'
|
||||
teamcity:
|
||||
authorizedOrigins: 'TEAMCITY_ORIGINS'
|
||||
weblate:
|
||||
authorizedOrigins: 'WEBLATE_ORIGINS'
|
||||
trace: 'TRACE_SERVICES'
|
||||
|
||||
cacheHeaders:
|
||||
@@ -95,4 +97,5 @@ private:
|
||||
wheelmap_token: 'WHEELMAP_TOKEN'
|
||||
influx_username: 'INFLUX_USERNAME'
|
||||
influx_password: 'INFLUX_PASSWORD'
|
||||
weblate_api_key: 'WEBLATE_API_KEY'
|
||||
youtube_api_key: 'YOUTUBE_API_KEY'
|
||||
|
||||
@@ -22,6 +22,8 @@ public:
|
||||
debug:
|
||||
enabled: false
|
||||
intervalSeconds: 200
|
||||
weblate:
|
||||
authorizedOrigins: 'https://hosted.weblate.org'
|
||||
trace: false
|
||||
|
||||
cacheHeaders:
|
||||
|
||||
@@ -10,5 +10,6 @@ private:
|
||||
sl_insight_apiToken: ...
|
||||
twitch_client_id: ...
|
||||
twitch_client_secret: ...
|
||||
weblate_api_key: ...
|
||||
wheelmap_token: ...
|
||||
youtube_api_key: ...
|
||||
|
||||
@@ -7,5 +7,6 @@ private:
|
||||
gh_token: '...'
|
||||
twitch_client_id: '...'
|
||||
twitch_client_secret: '...'
|
||||
weblate_api_key: '...'
|
||||
wheelmap_token: '...'
|
||||
youtube_api_key: '...'
|
||||
|
||||
@@ -135,6 +135,7 @@ const publicConfigSchema = Joi.object({
|
||||
npm: defaultService,
|
||||
sonar: defaultService,
|
||||
teamcity: defaultService,
|
||||
weblate: defaultService,
|
||||
trace: Joi.boolean().required(),
|
||||
}).required(),
|
||||
cacheHeaders: { defaultCacheLengthSeconds: nonNegativeInteger },
|
||||
@@ -182,6 +183,7 @@ const privateConfigSchema = Joi.object({
|
||||
wheelmap_token: Joi.string(),
|
||||
influx_username: Joi.string(),
|
||||
influx_password: Joi.string(),
|
||||
weblate_api_key: Joi.string(),
|
||||
youtube_api_key: Joi.string(),
|
||||
}).required()
|
||||
const privateMetricsInfluxConfigSchema = privateConfigSchema.append({
|
||||
|
||||
@@ -219,6 +219,21 @@ access to your private nexus repositories.
|
||||
Register an application in the [Twitch developer console](https://dev.twitch.tv/console)
|
||||
in order to obtain a client id and a client secret for making Twitch API calls.
|
||||
|
||||
### Weblate
|
||||
|
||||
- `WEBLATE_ORIGINS` (yml: `public.services.weblate.authorizedOrigins`)
|
||||
- `WEBLATE_API_KEY` (yml: `private.weblate_api_key`)
|
||||
|
||||
By default Weblate throttles [unauthenticated request][weblate authentication]
|
||||
to only 100 requests per day, after this you will need an API key or else
|
||||
badges will stop working.
|
||||
|
||||
You can find your Weblate API key in your profile under
|
||||
["API access"][weblate api key location].
|
||||
|
||||
[weblate authentication]: https://docs.weblate.org/en/latest/api.html#authentication-and-generic-parameters
|
||||
[weblate api key location]: https://hosted.weblate.org/accounts/profile/#api
|
||||
|
||||
### Wheelmap
|
||||
|
||||
- `WHEELMAP_TOKEN` (yml: `private.wheelmap_token`)
|
||||
|
||||
21
services/weblate/weblate-base.js
Normal file
21
services/weblate/weblate-base.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import Joi from 'joi'
|
||||
import { BaseJsonService } from '../index.js'
|
||||
import { optionalUrl } from '../validators.js'
|
||||
|
||||
export default class WeblateBase extends BaseJsonService {
|
||||
static queryParamSchema = Joi.object({
|
||||
server: optionalUrl,
|
||||
}).required()
|
||||
|
||||
static auth = {
|
||||
passKey: 'weblate_api_key',
|
||||
isRequired: false,
|
||||
serviceKey: 'weblate',
|
||||
}
|
||||
|
||||
async fetch(requestParams) {
|
||||
return this._requestJson(
|
||||
this.authHelper.withBearerAuthHeader(requestParams, 'Token')
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,20 @@
|
||||
import Joi from 'joi'
|
||||
import { BaseJsonService } from '../index.js'
|
||||
import { optionalUrl } from '../validators.js'
|
||||
import WeblateBase from './weblate-base.js'
|
||||
|
||||
const schema = Joi.object({
|
||||
license: Joi.string().required(),
|
||||
}).required()
|
||||
|
||||
const queryParamSchema = Joi.object({
|
||||
server: optionalUrl,
|
||||
}).required()
|
||||
|
||||
/**
|
||||
* This badge displays the license of a component on a Weblate instance.
|
||||
*/
|
||||
export default class WeblateComponentLicense extends BaseJsonService {
|
||||
export default class WeblateComponentLicense extends WeblateBase {
|
||||
static category = 'license'
|
||||
|
||||
static route = {
|
||||
base: 'weblate/l',
|
||||
pattern: ':project/:component',
|
||||
queryParamSchema,
|
||||
queryParamSchema: this.queryParamSchema,
|
||||
}
|
||||
|
||||
static examples = [
|
||||
@@ -38,7 +34,7 @@ export default class WeblateComponentLicense extends BaseJsonService {
|
||||
}
|
||||
|
||||
async fetch({ project, component, server = 'https://hosted.weblate.org' }) {
|
||||
return this._requestJson({
|
||||
return super.fetch({
|
||||
schema,
|
||||
url: `${server}/api/components/${project}/${component}/`,
|
||||
errorMessages: {
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
import Joi from 'joi'
|
||||
import { BaseJsonService } from '../index.js'
|
||||
import { nonNegativeInteger, optionalUrl } from '../validators.js'
|
||||
import { nonNegativeInteger } from '../validators.js'
|
||||
import { metric } from '../text-formatters.js'
|
||||
import WeblateBase from './weblate-base.js'
|
||||
|
||||
const schema = Joi.object({
|
||||
count: nonNegativeInteger,
|
||||
}).required()
|
||||
|
||||
const queryParamSchema = Joi.object({
|
||||
server: optionalUrl,
|
||||
}).required()
|
||||
|
||||
export default class WeblateEntities extends BaseJsonService {
|
||||
export default class WeblateEntities extends WeblateBase {
|
||||
static category = 'other'
|
||||
|
||||
static route = {
|
||||
base: 'weblate',
|
||||
pattern: ':type(components|projects|users|languages)',
|
||||
queryParamSchema,
|
||||
queryParamSchema: this.queryParamSchema,
|
||||
}
|
||||
|
||||
static examples = [
|
||||
@@ -36,7 +33,7 @@ export default class WeblateEntities extends BaseJsonService {
|
||||
}
|
||||
|
||||
async fetch({ type, server = 'https://hosted.weblate.org' }) {
|
||||
return this._requestJson({
|
||||
return super.fetch({
|
||||
schema,
|
||||
url: `${server}/api/${type}/`,
|
||||
errorMessages: {
|
||||
|
||||
@@ -1,26 +1,22 @@
|
||||
import Joi from 'joi'
|
||||
import { BaseJsonService } from '../index.js'
|
||||
import { optionalUrl } from '../validators.js'
|
||||
import { colorScale } from '../color-formatters.js'
|
||||
import WeblateBase from './weblate-base.js'
|
||||
|
||||
const schema = Joi.object({
|
||||
translated_percent: Joi.number().required(),
|
||||
}).required()
|
||||
|
||||
const queryParamSchema = Joi.object({
|
||||
server: optionalUrl,
|
||||
}).required()
|
||||
|
||||
/**
|
||||
* This badge displays the percentage of strings translated on a project on a
|
||||
* Weblate instance.
|
||||
*/
|
||||
export default class WeblateProjectTranslatedPercentage extends BaseJsonService {
|
||||
export default class WeblateProjectTranslatedPercentage extends WeblateBase {
|
||||
static category = 'other'
|
||||
|
||||
static route = {
|
||||
base: 'weblate/progress',
|
||||
pattern: ':project',
|
||||
queryParamSchema,
|
||||
queryParamSchema: this.queryParamSchema,
|
||||
}
|
||||
|
||||
static examples = [
|
||||
@@ -50,7 +46,7 @@ export default class WeblateProjectTranslatedPercentage extends BaseJsonService
|
||||
}
|
||||
|
||||
async fetch({ project, server = 'https://hosted.weblate.org' }) {
|
||||
return this._requestJson({
|
||||
return super.fetch({
|
||||
schema,
|
||||
url: `${server}/api/projects/${project}/statistics/`,
|
||||
errorMessages: {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Joi from 'joi'
|
||||
import { BaseJsonService } from '../index.js'
|
||||
import { nonNegativeInteger, optionalUrl } from '../validators.js'
|
||||
import { nonNegativeInteger } from '../validators.js'
|
||||
import { metric } from '../text-formatters.js'
|
||||
import WeblateBase from './weblate-base.js'
|
||||
|
||||
const schema = Joi.object({
|
||||
translated: nonNegativeInteger,
|
||||
@@ -11,10 +11,6 @@ const schema = Joi.object({
|
||||
languages: nonNegativeInteger,
|
||||
}).required()
|
||||
|
||||
const queryParamSchema = Joi.object({
|
||||
server: optionalUrl,
|
||||
}).required()
|
||||
|
||||
const statisticKeyNames = {
|
||||
translations: 'translated',
|
||||
suggestions: 'suggested',
|
||||
@@ -23,13 +19,14 @@ const statisticKeyNames = {
|
||||
languages: 'languages',
|
||||
}
|
||||
|
||||
export default class WeblateUserStatistic extends BaseJsonService {
|
||||
export default class WeblateUserStatistic extends WeblateBase {
|
||||
static category = 'other'
|
||||
|
||||
static route = {
|
||||
base: 'weblate',
|
||||
pattern:
|
||||
':statistic(translations|suggestions|languages|uploads|comments)/:user',
|
||||
queryParamSchema,
|
||||
queryParamSchema: this.queryParamSchema,
|
||||
}
|
||||
|
||||
static examples = [
|
||||
@@ -49,7 +46,7 @@ export default class WeblateUserStatistic extends BaseJsonService {
|
||||
}
|
||||
|
||||
async fetch({ user, server = 'https://hosted.weblate.org' }) {
|
||||
return this._requestJson({
|
||||
return super.fetch({
|
||||
schema,
|
||||
url: `${server}/api/users/${user}/statistics/`,
|
||||
errorMessages: {
|
||||
|
||||
Reference in New Issue
Block a user