mirror of
https://github.com/HangarMC/Hangar.git
synced 2025-02-17 15:01:42 +08:00
started work on bbcode converter
This commit is contained in:
parent
f9bfafc0e2
commit
202c2e11b1
@ -86,10 +86,10 @@ There is a bunch of stuff to do, some of that is noted in the [**Roadmap Project
|
||||
Your best bet is joining #hangar-dev on the [Paper Discord](https://discord.gg/papermc) and just discussing with us.
|
||||
All contributions are very welcome, we will not be able to finish this alone!
|
||||
|
||||
## Licence
|
||||
## License
|
||||
|
||||
Most of the frontend is a fork of Ore, licensed under MIT [here](https://github.com/SpongePowered/Ore/blob/staging/LICENSE.txt).
|
||||
The rest is new code (but created in reference of Ore) and is licenced under the MIT licence too.
|
||||
The rest is new code (but created in reference of Ore) and is licensed under the MIT license too.
|
||||
|
||||
[Yarn]: https://yarnpkg.com/
|
||||
[HangarAuth]: https://github.com/PaperMC/HangarAuth
|
||||
|
@ -17,7 +17,7 @@ hangar:
|
||||
base-url: "https://hangar.benndorf.dev"
|
||||
plugin-upload-dir: "/hangar/uploads"
|
||||
|
||||
licences:
|
||||
licenses:
|
||||
- "MIT"
|
||||
- "Apache 2.0"
|
||||
- "GPL"
|
||||
|
@ -44,7 +44,7 @@ hangar:
|
||||
plugin-upload-dir: "/uploads"
|
||||
ga-code: "UA-38006759-9"
|
||||
|
||||
licences:
|
||||
licenses:
|
||||
- "MIT"
|
||||
- "Apache 2.0"
|
||||
- "GPL"
|
||||
|
@ -152,10 +152,10 @@ const msgs: LocaleMessageObject = {
|
||||
title: 'Basic Settings',
|
||||
continue: 'Continue',
|
||||
back: 'Back',
|
||||
userselect: 'Create as...',
|
||||
projectname: 'Project name',
|
||||
projectsummary: 'Project Summary',
|
||||
projectcategory: 'Project Category',
|
||||
userSelect: 'Create as...',
|
||||
projectName: 'Project name',
|
||||
projectSummary: 'Project Summary',
|
||||
projectCategory: 'Project Category',
|
||||
},
|
||||
step3: {
|
||||
title: 'Additional Settings',
|
||||
@ -167,7 +167,7 @@ const msgs: LocaleMessageObject = {
|
||||
issues: 'Issue Tracker',
|
||||
source: 'Source Code',
|
||||
support: 'External Support',
|
||||
licence: 'Licence',
|
||||
license: 'License',
|
||||
type: 'Type',
|
||||
customName: 'Name',
|
||||
url: 'URL',
|
||||
@ -180,8 +180,18 @@ const msgs: LocaleMessageObject = {
|
||||
back: 'Back',
|
||||
optional: 'Optional',
|
||||
convert: 'Convert',
|
||||
convertLabels: {
|
||||
bbCode: 'Paste your BBCode here',
|
||||
output: 'Markdown Output',
|
||||
},
|
||||
preview: 'Preview',
|
||||
tutorial: 'How to get the BBCode',
|
||||
tutorialInstructions: {
|
||||
line1: 'To get the BBCode of your Spigot project, do the following:',
|
||||
line2: '1. Go to your project and click on "Edit Resource".',
|
||||
line3: '2. Click on the wrench symbol in the description editor.',
|
||||
line4: '3. Copy paste the new contents into the upper converter textbox, do changes to the output if you like, and hit save!',
|
||||
},
|
||||
},
|
||||
step5: {
|
||||
title: 'Finishing',
|
||||
@ -232,7 +242,7 @@ const msgs: LocaleMessageObject = {
|
||||
support: 'External support',
|
||||
supportSub: 'An external place where you can offer support to your users. Could be a forum, a Discord server, or somewhere else.',
|
||||
license: 'License',
|
||||
licenceSub: 'What can people do (and not do) with your project?',
|
||||
licenseSub: 'What can people do (and not do) with your project?',
|
||||
forum: 'Create posts on the forums',
|
||||
forumSub: 'Sets if events like a new release should automatically create a post on the forums',
|
||||
description: 'Description',
|
||||
@ -252,9 +262,9 @@ const msgs: LocaleMessageObject = {
|
||||
hardDeleteSub: 'Once you delete a project, it cannot be recovered. For real this time...',
|
||||
save: 'Save changes',
|
||||
optional: '(optional)',
|
||||
licenceCustom: 'Custom Name',
|
||||
licenceType: 'Type',
|
||||
licenceUrl: 'URL',
|
||||
licenseCustom: 'Custom Name',
|
||||
licenseType: 'Type',
|
||||
licenseUrl: 'URL',
|
||||
donation: {
|
||||
enable: 'Enable',
|
||||
enableSub: 'Enable the donation form for this project',
|
||||
|
@ -201,7 +201,7 @@
|
||||
<h2>
|
||||
{{ $t('project.settings.license') }} <small>{{ $t('project.settings.optional') }}</small>
|
||||
</h2>
|
||||
<p>{{ $t('project.settings.licenceSub') }}</p>
|
||||
<p>{{ $t('project.settings.licenseSub') }}</p>
|
||||
<v-row>
|
||||
<v-col cols="12" :md="isCustomLicense ? 4 : 6">
|
||||
<v-select
|
||||
@ -209,8 +209,8 @@
|
||||
dense
|
||||
hide-details
|
||||
filled
|
||||
:items="licences"
|
||||
:label="$t('project.settings.licenceType')"
|
||||
:items="licenses"
|
||||
:label="$t('project.settings.licenseType')"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col v-if="isCustomLicense" cols="12" md="8">
|
||||
@ -219,7 +219,7 @@
|
||||
dense
|
||||
hide-details
|
||||
filled
|
||||
:label="$t('project.settings.licenceCustom')"
|
||||
:label="$t('project.settings.licenseCustom')"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" :md="isCustomLicense ? 12 : 6">
|
||||
@ -229,7 +229,7 @@
|
||||
clearable
|
||||
filled
|
||||
:rules="[$util.$vc.url]"
|
||||
:label="$t('project.settings.licenceUrl')"
|
||||
:label="$t('project.settings.licenseUrl')"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
@ -398,7 +398,7 @@ import TextareaModal from '~/components/modals/TextareaModal.vue';
|
||||
@ProjectPermission(NamedPermission.EDIT_SUBJECT_SETTINGS)
|
||||
export default class ProjectManagePage extends HangarProjectMixin {
|
||||
roles!: Role[];
|
||||
licences!: string[];
|
||||
licenses!: string[];
|
||||
apiKey = '';
|
||||
newName = '';
|
||||
nameErrors: TranslateResult[] = [];
|
||||
@ -582,11 +582,11 @@ export default class ProjectManagePage extends HangarProjectMixin {
|
||||
generateApiKey() {}
|
||||
|
||||
async asyncData({ $api, $util }: Context) {
|
||||
const data = await Promise.all([$api.requestInternal('data/projectRoles', false), $api.requestInternal('data/licences', false)]).catch(
|
||||
const data = await Promise.all([$api.requestInternal('data/projectRoles', false), $api.requestInternal('data/licenses', false)]).catch(
|
||||
$util.handlePageRequestError
|
||||
);
|
||||
if (typeof data === 'undefined') return;
|
||||
return { roles: data[0], licences: data[1] };
|
||||
return { roles: data[0], licenses: data[1] };
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -43,8 +43,8 @@
|
||||
filled
|
||||
item-text="name"
|
||||
item-value="userId"
|
||||
:label="$t('project.new.step2.userselect')"
|
||||
:rules="[$util.$vc.require($t('project.new.step2.userselect'))]"
|
||||
:label="$t('project.new.step2.userSelect')"
|
||||
:rules="[$util.$vc.require($t('project.new.step2.userSelect'))]"
|
||||
:append-icon="createAsIcon"
|
||||
/>
|
||||
</v-col>
|
||||
@ -55,8 +55,8 @@
|
||||
dense
|
||||
filled
|
||||
:error-messages="nameErrors"
|
||||
:label="$t('project.new.step2.projectname')"
|
||||
:rules="[$util.$vc.require($t('project.new.step2.projectname'))]"
|
||||
:label="$t('project.new.step2.projectName')"
|
||||
:rules="[$util.$vc.require($t('project.new.step2.projectName'))]"
|
||||
append-icon="mdi-form-textbox"
|
||||
/>
|
||||
</v-col>
|
||||
@ -66,8 +66,8 @@
|
||||
dense
|
||||
filled
|
||||
clearable
|
||||
:label="$t('project.new.step2.projectsummary')"
|
||||
:rules="[$util.$vc.require($t('project.new.step2.projectsummary')), $util.$vc.maxLength(validations.project.desc.max)]"
|
||||
:label="$t('project.new.step2.projectSummary')"
|
||||
:rules="[$util.$vc.require($t('project.new.step2.projectSummary')), $util.$vc.maxLength(validations.project.desc.max)]"
|
||||
append-icon="mdi-card-text"
|
||||
/>
|
||||
</v-col>
|
||||
@ -78,10 +78,10 @@
|
||||
:items="$store.getters.visibleCategories"
|
||||
dense
|
||||
filled
|
||||
:label="$t('project.new.step2.projectcategory')"
|
||||
:label="$t('project.new.step2.projectCategory')"
|
||||
item-text="title"
|
||||
item-value="apiName"
|
||||
:rules="[$util.$vc.require($t('project.new.step2.projectcategory'))]"
|
||||
:rules="[$util.$vc.require($t('project.new.step2.projectCategory'))]"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
@ -148,7 +148,7 @@
|
||||
</v-row>
|
||||
<div class="text-h6 pt-5">
|
||||
<v-icon color="info" large class="mb-1">mdi-license</v-icon>
|
||||
{{ $t('project.new.step3.licence') }}
|
||||
{{ $t('project.new.step3.license') }}
|
||||
</div>
|
||||
<v-divider class="mb-2" />
|
||||
<v-row>
|
||||
@ -159,7 +159,7 @@
|
||||
hide-details
|
||||
filled
|
||||
clearable
|
||||
:items="licences"
|
||||
:items="licenses"
|
||||
:label="$t('project.new.step3.type')"
|
||||
/>
|
||||
</v-col>
|
||||
@ -217,9 +217,37 @@
|
||||
</v-tabs>
|
||||
<v-tabs-items v-model="spigotConvertTab">
|
||||
<!-- todo spigot bbcode converter thingy -->
|
||||
<v-tab-item>1 </v-tab-item>
|
||||
<v-tab-item>
|
||||
<v-card-text>
|
||||
<v-textarea v-model="converter.bbCode" hide-details dense :rows="6" filled :label="$t('project.new.step4.convertLabels.bbCode')" />
|
||||
<div>
|
||||
<v-btn block color="primary" class="my-3" :loading="converter.loading" @click="convertBBCode">
|
||||
<v-icon left large>mdi-chevron-double-down</v-icon>
|
||||
{{ $t('project.new.step4.convert') }}
|
||||
<v-icon right large>mdi-chevron-double-down</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
<v-textarea
|
||||
v-model="converter.markdown"
|
||||
hide-details
|
||||
dense
|
||||
:rows="6"
|
||||
filled
|
||||
:label="$t('project.new.step4.convertLabels.output')"
|
||||
/>
|
||||
</v-card-text>
|
||||
</v-tab-item>
|
||||
<v-tab-item>2 </v-tab-item>
|
||||
<v-tab-item>3 </v-tab-item>
|
||||
<v-tab-item>
|
||||
<v-card-text class="text-center">
|
||||
{{ $t('project.new.step4.tutorialInstructions.line1') }}<br />
|
||||
{{ $t('project.new.step4.tutorialInstructions.line2') }}<br />
|
||||
<img src="https://i.imgur.com/8CyLMf3.png" alt="Edit Project" /><br />
|
||||
{{ $t('project.new.step4.tutorialInstructions.line3') }}<br />
|
||||
<img src="https://i.imgur.com/FLVIuQK.png" width="425" height="198" alt="Show BBCode" /><br />
|
||||
{{ $t('project.new.step4.tutorialInstructions.line4') }}<br />
|
||||
</v-card-text>
|
||||
</v-tab-item>
|
||||
</v-tabs-items>
|
||||
</StepperStepContent>
|
||||
<StepperStepContent :step="5" hide-buttons>
|
||||
@ -271,7 +299,7 @@ export default class NewProjectPage extends HangarComponent {
|
||||
projectLoading = true;
|
||||
projectError = false;
|
||||
projectOwners!: ProjectOwner[];
|
||||
licences!: string[];
|
||||
licenses!: string[];
|
||||
error = null as string | null;
|
||||
form: NewProjectForm = {
|
||||
category: ProjectCategory.ADMIN_TOOLS,
|
||||
@ -284,6 +312,12 @@ export default class NewProjectPage extends HangarComponent {
|
||||
|
||||
nameErrors: TranslateResult[] = [];
|
||||
|
||||
converter = {
|
||||
bbCode: '',
|
||||
markdown: '',
|
||||
loading: false,
|
||||
};
|
||||
|
||||
forms = {
|
||||
step2: false,
|
||||
};
|
||||
@ -305,13 +339,13 @@ export default class NewProjectPage extends HangarComponent {
|
||||
}
|
||||
|
||||
async asyncData({ $api, $util }: Context) {
|
||||
const data = await Promise.all([$api.requestInternal('data/possibleOwners'), $api.requestInternal('data/licenses', false)]).catch(
|
||||
const data = await Promise.all([$api.requestInternal('projects/possibleOwners'), $api.requestInternal('data/licenses', false)]).catch(
|
||||
$util.handlePageRequestError
|
||||
);
|
||||
if (typeof data === 'undefined') return;
|
||||
return {
|
||||
licenses: data[0],
|
||||
projectOwners: data[1],
|
||||
projectOwners: data[0],
|
||||
licenses: data[1],
|
||||
};
|
||||
}
|
||||
|
||||
@ -334,6 +368,21 @@ export default class NewProjectPage extends HangarComponent {
|
||||
});
|
||||
}
|
||||
|
||||
convertBBCode() {
|
||||
this.converter.loading = true;
|
||||
this.$api
|
||||
.requestInternal<string>('pages/convert-bbcode', false, 'post', {
|
||||
content: this.converter.bbCode,
|
||||
})
|
||||
.then((markdown) => {
|
||||
this.converter.markdown = markdown;
|
||||
})
|
||||
.catch(this.$util.handleRequestError)
|
||||
.finally(() => {
|
||||
this.converter.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
retry() {
|
||||
this.step = 1;
|
||||
this.projectLoading = true;
|
||||
|
@ -1,35 +1,16 @@
|
||||
package io.papermc.hangar.config;
|
||||
|
||||
import com.fasterxml.classmate.TypeResolver;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import io.papermc.hangar.controller.extras.pagination.Filter;
|
||||
import io.papermc.hangar.controller.extras.pagination.FilterRegistry;
|
||||
import io.papermc.hangar.controller.extras.pagination.annotations.ApplicableFilters;
|
||||
import io.papermc.hangar.controller.extras.pagination.annotations.ApplicableSorters;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.ExampleBuilder;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.builders.RequestParameterBuilder;
|
||||
import springfox.documentation.schema.Example;
|
||||
import springfox.documentation.schema.ModelRef;
|
||||
import springfox.documentation.schema.ModelSpecification;
|
||||
import springfox.documentation.schema.ScalarType;
|
||||
import springfox.documentation.service.ApiInfo;
|
||||
import springfox.documentation.service.Contact;
|
||||
import springfox.documentation.service.ParameterSpecification;
|
||||
import springfox.documentation.service.ParameterStyle;
|
||||
import springfox.documentation.service.ParameterType;
|
||||
import springfox.documentation.service.RequestParameter;
|
||||
@ -39,6 +20,13 @@ import springfox.documentation.spi.service.contexts.OperationContext;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
@Configuration
|
||||
@EnableSwagger2
|
||||
public class SwaggerConfig {
|
||||
@ -61,7 +49,7 @@ public class SwaggerConfig {
|
||||
"We're working on a session-less authentification for public endpoints. " +
|
||||
"<h3>What format does dates have?</h3>" +
|
||||
"Standard ISO types. Where possible we use the OpenAPI format modifier. You can view it's meanings [here](https://swagger.io/docs/specification/data-models/data-types/#format).")
|
||||
.license("Unlicence")
|
||||
.license("Unlicense")
|
||||
.licenseUrl("http://unlicense.org")
|
||||
.termsOfServiceUrl("")
|
||||
.version("1.0")
|
||||
|
@ -30,7 +30,7 @@ public class HangarConfig {
|
||||
private String gaCode = "";
|
||||
private List<Announcement> announcements = new ArrayList<>();
|
||||
private String urlRegex = "^(https?:\\/\\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\\/\\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})";
|
||||
private List<String> licences = new ArrayList<>();
|
||||
private List<String> licenses = new ArrayList<>();
|
||||
|
||||
@NestedConfigurationProperty
|
||||
public final FakeUserConfig fakeUser;
|
||||
@ -190,12 +190,12 @@ public class HangarConfig {
|
||||
this.urlRegex = urlRegex;
|
||||
}
|
||||
|
||||
public List<String> getLicences() {
|
||||
return licences;
|
||||
public List<String> getLicenses() {
|
||||
return licenses;
|
||||
}
|
||||
|
||||
public void setLicences(List<String> licences) {
|
||||
this.licences = licences;
|
||||
public void setLicenses(List<String> licenses) {
|
||||
this.licenses = licenses;
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
|
@ -135,9 +135,9 @@ public class BackendDataController {
|
||||
return ResponseEntity.ok(OrganizationRole.getAssignableRoles());
|
||||
}
|
||||
|
||||
@GetMapping("/licences")
|
||||
public ResponseEntity<List<String>> getLicences() {
|
||||
return ResponseEntity.ok(config.getLicences());
|
||||
@GetMapping("/licenses")
|
||||
public ResponseEntity<List<String>> getLicenses() {
|
||||
return ResponseEntity.ok(config.getLicenses());
|
||||
}
|
||||
|
||||
@GetMapping("/visibilities")
|
||||
|
@ -14,6 +14,7 @@ import io.papermc.hangar.security.annotations.visibility.VisibilityRequired.Type
|
||||
import io.papermc.hangar.service.internal.MarkdownService;
|
||||
import io.papermc.hangar.service.internal.projects.ProjectPageService;
|
||||
import io.papermc.hangar.util.StringUtils;
|
||||
import io.papermc.hangar.utils.BBCodeConverter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
@ -25,6 +26,7 @@ import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
import javax.validation.Valid;
|
||||
@ -36,11 +38,13 @@ public class ProjectPageController extends HangarComponent {
|
||||
|
||||
private final ProjectPageService projectPageService;
|
||||
private final MarkdownService markdownService;
|
||||
private final BBCodeConverter bbCodeConverter;
|
||||
|
||||
@Autowired
|
||||
public ProjectPageController(ProjectPageService projectPageService, MarkdownService markdownService) {
|
||||
public ProjectPageController(ProjectPageService projectPageService, MarkdownService markdownService, BBCodeConverter bbCodeConverter) {
|
||||
this.projectPageService = projectPageService;
|
||||
this.markdownService = markdownService;
|
||||
this.bbCodeConverter = bbCodeConverter;
|
||||
}
|
||||
|
||||
@PostMapping(path = "/render", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ -48,6 +52,13 @@ public class ProjectPageController extends HangarComponent {
|
||||
return ResponseEntity.ok(markdownService.render(content.getContent()));
|
||||
}
|
||||
|
||||
@Anyone
|
||||
@ResponseBody
|
||||
@PostMapping(path = "/convert-bbcode", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.TEXT_PLAIN_VALUE)
|
||||
public String convertBBCode(@RequestBody @Valid StringContent bbCodeContent) {
|
||||
return bbCodeConverter.convertToMarkdown(bbCodeContent.getContent());
|
||||
}
|
||||
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
@GetMapping("/checkName")
|
||||
public void checkName(@RequestParam long projectId, @RequestParam String name, @RequestParam(required = false) Long parentId) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
package io.papermc.hangar.controllerold;
|
||||
|
||||
import io.papermc.hangar.controllerold.forms.RawPage;
|
||||
import io.papermc.hangar.controllerold.util.BBCodeConverter;
|
||||
import io.papermc.hangar.utils.BBCodeConverter;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
|
@ -18,8 +18,8 @@ public class ProjectLicense {
|
||||
|
||||
@JdbiConstructor
|
||||
public ProjectLicense(@Nullable String name, @Nullable String url) {
|
||||
int index = config.getLicences().indexOf(name);
|
||||
if (name != null && index > -1 && index < config.getLicences().size() - 1) {
|
||||
int index = config.getLicenses().indexOf(name);
|
||||
if (name != null && index > -1 && index < config.getLicenses().size() - 1) {
|
||||
this.name = null;
|
||||
this.type = name;
|
||||
} else {
|
||||
|
@ -1,71 +0,0 @@
|
||||
package io.papermc.hangar.util;
|
||||
|
||||
import io.papermc.hangar.exceptions.HangarApiException;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public class AuthUtils {
|
||||
|
||||
private static final Pattern API_KEY_HEADER_PATTERN = Pattern.compile("(?<=apikey=\").*(?=\")", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
|
||||
private static final Pattern SESSION_HEADER_PATTERN = Pattern.compile("(?<=session=\").*(?=\")", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
|
||||
|
||||
private AuthUtils() { }
|
||||
|
||||
public static RuntimeException unAuth(String message) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add(HttpHeaders.WWW_AUTHENTICATE, "HangarApi");
|
||||
return new HangarApiException(HttpStatus.UNAUTHORIZED, message, headers);
|
||||
}
|
||||
|
||||
public static AuthCredentials parseAuthHeader(@Nullable HttpServletRequest request, boolean requireHeader) {
|
||||
String authHeader = request == null ? ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest().getHeader(HttpHeaders.AUTHORIZATION) : request.getHeader(HttpHeaders.AUTHORIZATION);
|
||||
boolean missingAuthHeader = authHeader == null || authHeader.isBlank() || !authHeader.startsWith("HangarApi");
|
||||
if (missingAuthHeader && requireHeader) {
|
||||
throw AuthUtils.unAuth("Invalid or no header found");
|
||||
} else if (missingAuthHeader) {
|
||||
return new AuthCredentials(null, null);
|
||||
}
|
||||
return AuthUtils.AuthCredentials.parseHeader(authHeader);
|
||||
}
|
||||
|
||||
public static class AuthCredentials {
|
||||
private final String apiKey;
|
||||
private final String session;
|
||||
|
||||
private AuthCredentials(String apiKey, String session) {
|
||||
this.apiKey = apiKey;
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
public String getApiKey() {
|
||||
return apiKey;
|
||||
}
|
||||
|
||||
public String getSession() {
|
||||
return session;
|
||||
}
|
||||
|
||||
public static AuthCredentials parseHeader(String authHeader) {
|
||||
Matcher apiKeyMatcher = API_KEY_HEADER_PATTERN.matcher(authHeader);
|
||||
Matcher sessionMatcher = SESSION_HEADER_PATTERN.matcher(authHeader);
|
||||
String apiKey = null;
|
||||
String sessionKey = null;
|
||||
if (apiKeyMatcher.find()) {
|
||||
apiKey = apiKeyMatcher.group();
|
||||
} else if (sessionMatcher.find()) {
|
||||
sessionKey = sessionMatcher.group();
|
||||
} else {
|
||||
throw AuthUtils.unAuth("Invalid Authorization header format");
|
||||
}
|
||||
return new AuthCredentials(apiKey, sessionKey);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package io.papermc.hangar.util;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Deprecated
|
||||
public class ListUtils {
|
||||
|
||||
private ListUtils() { }
|
||||
|
||||
public static <K, V> Map<K, V> zip(List<K> keys, List<V> values) {
|
||||
Map<K, V> map = new HashMap<>();
|
||||
if (keys != null && values != null) {
|
||||
if (keys.size() != values.size()) throw new ResponseStatusException(HttpStatus.BAD_REQUEST);
|
||||
for (int i = 0; i < keys.size(); i++) {
|
||||
map.put(keys.get(i), values.get(i));
|
||||
}
|
||||
}
|
||||
return map;
|
||||
|
||||
}
|
||||
}
|
@ -1,10 +1,12 @@
|
||||
package io.papermc.hangar.controllerold.util;
|
||||
package io.papermc.hangar.utils;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class BBCodeConverter {
|
||||
|
||||
private static final Map<String, TagReplacer> REPLACERS = new HashMap<>();
|
@ -50,7 +50,7 @@ hangar:
|
||||
base-url: "http://localhost:3000"
|
||||
ga-code: "UA-38006759-9"
|
||||
|
||||
licences:
|
||||
licenses:
|
||||
- "MIT"
|
||||
- "Apache 2.0"
|
||||
- "GPL"
|
||||
|
@ -1,6 +1,6 @@
|
||||
package io.papermc.hangar.util;
|
||||
|
||||
import io.papermc.hangar.controllerold.util.BBCodeConverter;
|
||||
import io.papermc.hangar.utils.BBCodeConverter;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user