Add Codestyle definition, editorconfig
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Armin Friedl 2020-06-21 20:21:08 +02:00
parent 23af542178
commit 75b65f3f77
Signed by: armin
GPG key ID: 48C726EEE7FBCBC8
34 changed files with 1300 additions and 1235 deletions

9
.editorconfig Normal file
View file

@ -0,0 +1,9 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true

380
fling-java-codestyle.xml Normal file
View file

@ -0,0 +1,380 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="19">
<profile kind="CodeFormatterProfile" name="GoogleStyle" version="19">
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_with_spaces" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_record_components" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_logical_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="100"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_additive_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_shift_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_loops" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_relational_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="3"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.text_block_indentation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_shift_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_code_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_not_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_relational_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_tag_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_constructor" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_string_concatenation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_logical_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_additive_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_string_concatenation" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="100"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
</profile>
</profiles>

View file

@ -2,14 +2,11 @@ package net.friedl.fling;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

View file

@ -1,9 +1,7 @@
package net.friedl.fling.controller; package net.friedl.fling.controller;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource; import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
@ -19,7 +17,6 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import net.friedl.fling.model.dto.ArtifactDto; import net.friedl.fling.model.dto.ArtifactDto;
import net.friedl.fling.persistence.archive.ArchiveException; import net.friedl.fling.persistence.archive.ArchiveException;
import net.friedl.fling.service.ArtifactService; import net.friedl.fling.service.ArtifactService;
@ -46,7 +43,8 @@ public class ArtifactController {
} }
@PostMapping("/artifacts/{flingId}") @PostMapping("/artifacts/{flingId}")
public ArtifactDto postArtifact(@PathVariable Long flingId, HttpServletRequest request) throws Exception { public ArtifactDto postArtifact(@PathVariable Long flingId, HttpServletRequest request)
throws Exception {
return artifactService.storeArtifact(flingId, request.getInputStream()); return artifactService.storeArtifact(flingId, request.getInputStream());
} }
@ -66,14 +64,16 @@ public class ArtifactController {
} }
@GetMapping(path = "/artifacts/{artifactId}/{downloadId}/download") @GetMapping(path = "/artifacts/{artifactId}/{downloadId}/download")
public ResponseEntity<Resource> downloadArtifact(@PathVariable Long artifactId, @PathVariable String downloadId) public ResponseEntity<Resource> downloadArtifact(@PathVariable Long artifactId,
@PathVariable String downloadId)
throws ArchiveException { throws ArchiveException {
var artifact = artifactService.findArtifact(artifactId).orElseThrow(); var artifact = artifactService.findArtifact(artifactId).orElseThrow();
var stream = new InputStreamResource(artifactService.downloadArtifact(downloadId)); var stream = new InputStreamResource(artifactService.downloadArtifact(downloadId));
return ResponseEntity.ok() return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=\"" + artifact.getName() + "\"") .header(HttpHeaders.CONTENT_DISPOSITION,
"attachment;filename=\"" + artifact.getName() + "\"")
.contentLength(artifact.getSize()) .contentLength(artifact.getSize())
.contentType(MediaType.APPLICATION_OCTET_STREAM) .contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(stream); .body(stream);

View file

@ -2,7 +2,6 @@ package net.friedl.fling.controller;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource; import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
@ -18,7 +17,6 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import net.friedl.fling.model.dto.FlingDto; import net.friedl.fling.model.dto.FlingDto;
import net.friedl.fling.persistence.archive.ArchiveException; import net.friedl.fling.persistence.archive.ArchiveException;
import net.friedl.fling.service.FlingService; import net.friedl.fling.service.FlingService;
@ -75,13 +73,15 @@ public class FlingController {
} }
@GetMapping(path = "/fling/{flingId}/download/{downloadId}") @GetMapping(path = "/fling/{flingId}/download/{downloadId}")
public ResponseEntity<Resource> downloadFling(@PathVariable Long flingId, @PathVariable String downloadId) throws ArchiveException, IOException { public ResponseEntity<Resource> downloadFling(@PathVariable Long flingId,
@PathVariable String downloadId) throws ArchiveException, IOException {
var fling = flingService.findFlingById(flingId).orElseThrow(); var fling = flingService.findFlingById(flingId).orElseThrow();
var flingPackage = flingService.downloadFling(downloadId); var flingPackage = flingService.downloadFling(downloadId);
var stream = new InputStreamResource(flingPackage.getFirst()); var stream = new InputStreamResource(flingPackage.getFirst());
return ResponseEntity.ok() return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=\"" + fling.getName() + ".zip" + "\"") .header(HttpHeaders.CONTENT_DISPOSITION,
"attachment;filename=\"" + fling.getName() + ".zip" + "\"")
.contentLength(flingPackage.getSecond()) .contentLength(flingPackage.getSecond())
.contentType(MediaType.APPLICATION_OCTET_STREAM) .contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(stream); .body(stream);

View file

@ -1,9 +1,6 @@
package net.friedl.fling.model.dto; package net.friedl.fling.model.dto;
import java.time.Instant; import java.time.Instant;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data; import lombok.Data;
@Data @Data

View file

@ -3,10 +3,8 @@ package net.friedl.fling.model.dto;
import java.time.Instant; import java.time.Instant;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data; import lombok.Data;
@Data @Data
@ -59,21 +57,23 @@ public class FlingDto {
@JsonProperty("expiration") @JsonProperty("expiration")
private void unpackExpiration(Map<String, Object> expiration) { private void unpackExpiration(Map<String, Object> expiration) {
String type = (String) expiration.getOrDefault("type", null); String type = (String) expiration.getOrDefault("type", null);
if(type == null) return; if (type == null)
return;
switch(type) { switch (type) {
case "time": case "time":
this.expirationClicks = null; this.expirationClicks = null;
// json can only handle int, long must be given as string // json can only handle int, long must be given as string
// TODO: this back and forth conversion is a bit hack-ish // TODO: this back and forth conversion is a bit hack-ish
this.expirationTime = Instant.ofEpochMilli(Long.valueOf(expiration.get("value").toString())); this.expirationTime =
Instant.ofEpochMilli(Long.valueOf(expiration.get("value").toString()));
break; break;
case "clicks": case "clicks":
this.expirationTime = null; this.expirationTime = null;
this.expirationClicks = Integer.valueOf(expiration.get("value").toString()); this.expirationClicks = Integer.valueOf(expiration.get("value").toString());
break; break;
default: default:
throw new IllegalArgumentException("Unexpected value '"+type+"'"); throw new IllegalArgumentException("Unexpected value '" + type + "'");
} }
} }
@ -81,12 +81,12 @@ public class FlingDto {
private Map<String, Object> packExpiration() { private Map<String, Object> packExpiration() {
Map<String, Object> expiration = new HashMap<>(); Map<String, Object> expiration = new HashMap<>();
if(this.expirationClicks != null) { if (this.expirationClicks != null) {
expiration.put("type", "clicks"); expiration.put("type", "clicks");
expiration.put("value", this.expirationClicks); expiration.put("value", this.expirationClicks);
} }
if(this.expirationTime != null) { if (this.expirationTime != null) {
expiration.put("type", "time"); expiration.put("type", "time");
expiration.put("value", this.expirationTime.toEpochMilli()); expiration.put("value", this.expirationTime.toEpochMilli());
} }

View file

@ -4,9 +4,7 @@ import java.lang.reflect.Field;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.friedl.fling.model.dto.ArtifactDto; import net.friedl.fling.model.dto.ArtifactDto;
import net.friedl.fling.persistence.entities.ArtifactEntity; import net.friedl.fling.persistence.entities.ArtifactEntity;
@ -32,16 +30,16 @@ public abstract class ArtifactMapper {
field.setAccessible(true); field.setAccessible(true);
try { try {
if (patch.containsKey(fieldName)) { if (patch.containsKey(fieldName)) {
if(field.getType().equals(Long.class)) { if (field.getType().equals(Long.class)) {
field.set(mergedArtifactDto, ((Number) patch.get(fieldName)).longValue()); field.set(mergedArtifactDto, ((Number) patch.get(fieldName)).longValue());
} }
field.set(mergedArtifactDto, patch.get(fieldName)); field.set(mergedArtifactDto, patch.get(fieldName));
} else { } else {
field.set(mergedArtifactDto, field.get(originalArtifactDto)); field.set(mergedArtifactDto, field.get(originalArtifactDto));
} }
} } catch (IllegalArgumentException | IllegalAccessException e) {
catch (IllegalArgumentException | IllegalAccessException e) { log.error("Could not merge {} [value={}] with {}", fieldName, patch.get(fieldName),
log.error("Could not merge {} [value={}] with {}", fieldName, patch.get(fieldName), originalArtifactDto, originalArtifactDto,
e); e);
} }
} }

View file

@ -2,9 +2,7 @@ package net.friedl.fling.model.mapper;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import net.friedl.fling.model.dto.FlingDto; import net.friedl.fling.model.dto.FlingDto;
import net.friedl.fling.persistence.entities.FlingEntity; import net.friedl.fling.persistence.entities.FlingEntity;

View file

@ -19,16 +19,14 @@ public interface Archive {
* *
* @param is The artifact represented as {@link InputStream} * @param is The artifact represented as {@link InputStream}
* @return A unique archive id for the artifact * @return A unique archive id for the artifact
* @throws IOException If anything goes wrong while storing the artifact in * @throws IOException If anything goes wrong while storing the artifact in the archive
* the archive
*/ */
String store(InputStream is) throws ArchiveException; String store(InputStream is) throws ArchiveException;
default String store(File file) throws ArchiveException { default String store(File file) throws ArchiveException {
try { try {
return store(new FileInputStream(file)); return store(new FileInputStream(file));
} } catch (IOException ex) {
catch (IOException ex) {
throw new ArchiveException(ex); throw new ArchiveException(ex);
} }
} }

View file

@ -4,21 +4,19 @@ public class ArchiveException extends Exception {
private static final long serialVersionUID = 6216735865308056261L; private static final long serialVersionUID = 6216735865308056261L;
/** /**
* Constructs a new exception with {@code null} as its detail message. The * Constructs a new exception with {@code null} as its detail message. The cause is not
* cause is not initialized, and may subsequently be initialized by a call * initialized, and may subsequently be initialized by a call to {@link #initCause}.
* to {@link #initCause}.
*/ */
public ArchiveException() { public ArchiveException() {
super(); super();
} }
/** /**
* Constructs a new exception with the specified detail message. The cause * Constructs a new exception with the specified detail message. The cause is not initialized, and
* is not initialized, and may subsequently be initialized by a call to * may subsequently be initialized by a call to {@link #initCause}.
* {@link #initCause}.
* *
* @param message the detail message. The detail message is saved for later * @param message the detail message. The detail message is saved for later retrieval by the
* retrieval by the {@link #getMessage()} method. * {@link #getMessage()} method.
*/ */
public ArchiveException(String message) { public ArchiveException(String message) {
super(message); super(message);
@ -27,14 +25,14 @@ public class ArchiveException extends Exception {
/** /**
* Constructs a new exception with the specified detail message and cause. * Constructs a new exception with the specified detail message and cause.
* <p> * <p>
* Note that the detail message associated with {@code cause} is <i>not</i> * Note that the detail message associated with {@code cause} is <i>not</i> automatically
* automatically incorporated in this exception's detail message. * incorporated in this exception's detail message.
* *
* @param message the detail message (which is saved for later retrieval by * @param message the detail message (which is saved for later retrieval by the
* the {@link #getMessage()} method). * {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method).
* {@link #getCause()} method). (A {@code null} value is permitted, * (A {@code null} value is permitted, and indicates that the cause is nonexistent or
* and indicates that the cause is nonexistent or unknown.) * unknown.)
* @since 1.4 * @since 1.4
*/ */
public ArchiveException(String message, Throwable cause) { public ArchiveException(String message, Throwable cause) {
@ -42,16 +40,15 @@ public class ArchiveException extends Exception {
} }
/** /**
* Constructs a new exception with the specified cause and a detail message * Constructs a new exception with the specified cause and a detail message of
* of {@code (cause==null ? null : cause.toString())} (which typically * {@code (cause==null ? null : cause.toString())} (which typically contains the class and detail
* contains the class and detail message of {@code cause}). This constructor * message of {@code cause}). This constructor is useful for exceptions that are little more than
* is useful for exceptions that are little more than wrappers for other * wrappers for other throwables (for example,
* throwables (for example,
* {@link java.security.PrivilegedActionArchiveException}). * {@link java.security.PrivilegedActionArchiveException}).
* *
* @param cause the cause (which is saved for later retrieval by the * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method).
* {@link #getCause()} method). (A {@code null} value is permitted, * (A {@code null} value is permitted, and indicates that the cause is nonexistent or
* and indicates that the cause is nonexistent or unknown.) * unknown.)
* @since 1.4 * @since 1.4
*/ */
public ArchiveException(Throwable cause) { public ArchiveException(Throwable cause) {
@ -59,20 +56,18 @@ public class ArchiveException extends Exception {
} }
/** /**
* Constructs a new exception with the specified detail message, cause, * Constructs a new exception with the specified detail message, cause, suppression enabled or
* suppression enabled or disabled, and writable stack trace enabled or * disabled, and writable stack trace enabled or disabled.
* disabled.
* *
* @param message the detail message. * @param message the detail message.
* @param cause the cause. (A {@code null} value is permitted, and indicates * @param cause the cause. (A {@code null} value is permitted, and indicates that the cause is
* that the cause is nonexistent or unknown.) * nonexistent or unknown.)
* @param enableSuppression whether or not suppression is enabled or * @param enableSuppression whether or not suppression is enabled or disabled
* disabled * @param writableStackTrace whether or not the stack trace should be writable
* @param writableStackTrace whether or not the stack trace should be
* writable
* @since 1.7 * @since 1.7
*/ */
protected ArchiveException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { protected ArchiveException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace); super(message, cause, enableSuppression, writableStackTrace);
} }
} }

View file

@ -10,10 +10,8 @@ import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.StandardOpenOption; import java.nio.file.StandardOpenOption;
import java.security.MessageDigest; import java.security.MessageDigest;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import net.friedl.fling.persistence.archive.Archive; import net.friedl.fling.persistence.archive.Archive;
import net.friedl.fling.persistence.archive.ArchiveException; import net.friedl.fling.persistence.archive.ArchiveException;
@ -24,7 +22,8 @@ public class FileSystemArchive implements Archive {
private FileSystemArchiveConfiguration configuration; private FileSystemArchiveConfiguration configuration;
@Autowired @Autowired
public FileSystemArchive(MessageDigest fileStoreDigest, FileSystemArchiveConfiguration configuration) { public FileSystemArchive(MessageDigest fileStoreDigest,
FileSystemArchiveConfiguration configuration) {
this.fileStoreDigest = fileStoreDigest; this.fileStoreDigest = fileStoreDigest;
this.configuration = configuration; this.configuration = configuration;
} }
@ -49,7 +48,8 @@ public class FileSystemArchive implements Archive {
String fileStoreId = hexEncode(fileStoreDigest.digest(fileBytes)); String fileStoreId = hexEncode(fileStoreDigest.digest(fileBytes));
FileChannel fc = FileChannel.open(Paths.get(configuration.getDirectory(), fileStoreId), FileChannel fc = FileChannel.open(Paths.get(configuration.getDirectory(), fileStoreId),
StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE, StandardOpenOption.CREATE); StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE,
StandardOpenOption.CREATE);
fc.write(ByteBuffer.wrap(fileBytes)); fc.write(ByteBuffer.wrap(fileBytes));

View file

@ -5,14 +5,11 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -21,7 +18,8 @@ import lombok.extern.slf4j.Slf4j;
@Configuration @Configuration
@ConfigurationProperties("fling.archive.fileystem") @ConfigurationProperties("fling.archive.fileystem")
@ConditionalOnBean(FileSystemArchive.class) @ConditionalOnBean(FileSystemArchive.class)
@Getter @Setter @Getter
@Setter
public class FileSystemArchiveConfiguration { public class FileSystemArchiveConfiguration {
private String directory; private String directory;

View file

@ -1,7 +1,6 @@
package net.friedl.fling.persistence.entities; package net.friedl.fling.persistence.entities;
import java.time.Instant; import java.time.Instant;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.GeneratedValue; import javax.persistence.GeneratedValue;
@ -9,13 +8,13 @@ import javax.persistence.Id;
import javax.persistence.ManyToOne; import javax.persistence.ManyToOne;
import javax.persistence.PrePersist; import javax.persistence.PrePersist;
import javax.persistence.Table; import javax.persistence.Table;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@Entity @Entity
@Table(name = "Artifact") @Table(name = "Artifact")
@Getter @Setter @Getter
@Setter
public class ArtifactEntity { public class ArtifactEntity {
@Id @Id
@GeneratedValue @GeneratedValue
@ -41,6 +40,7 @@ public class ArtifactEntity {
private void prePersist() { private void prePersist() {
this.uploadTime = Instant.now(); this.uploadTime = Instant.now();
if(this.version == null) this.version = -1; if (this.version == null)
this.version = -1;
} }
} }

View file

@ -2,7 +2,6 @@ package net.friedl.fling.persistence.entities;
import java.time.Instant; import java.time.Instant;
import java.util.Set; import java.util.Set;
import javax.persistence.CascadeType; import javax.persistence.CascadeType;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
@ -12,7 +11,6 @@ import javax.persistence.OneToMany;
import javax.persistence.PostPersist; import javax.persistence.PostPersist;
import javax.persistence.PrePersist; import javax.persistence.PrePersist;
import javax.persistence.Table; import javax.persistence.Table;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@ -64,9 +62,9 @@ public class FlingEntity {
@PostPersist @PostPersist
private void postPersist() { private void postPersist() {
System.out.println("ID: "+this.id); System.out.println("ID: " + this.id);
System.out.println("Share Url: "+this.shareUrl); System.out.println("Share Url: " + this.shareUrl);
this.shareUrl = this.id+this.shareUrl; this.shareUrl = this.id + this.shareUrl;
} }
} }

View file

@ -2,13 +2,13 @@ package net.friedl.fling.persistence.repositories;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import net.friedl.fling.persistence.entities.ArtifactEntity; import net.friedl.fling.persistence.entities.ArtifactEntity;
public interface ArtifactRepository extends JpaRepository<ArtifactEntity, Long> { public interface ArtifactRepository extends JpaRepository<ArtifactEntity, Long> {
Optional<ArtifactEntity> findByDoi(String doi); Optional<ArtifactEntity> findByDoi(String doi);
List<ArtifactEntity> deleteByDoi(String doi); List<ArtifactEntity> deleteByDoi(String doi);
List<ArtifactEntity> findAllByFlingId(Long flingId); List<ArtifactEntity> findAllByFlingId(Long flingId);
} }

View file

@ -1,10 +1,8 @@
package net.friedl.fling.persistence.repositories; package net.friedl.fling.persistence.repositories;
import java.util.Optional; import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import net.friedl.fling.persistence.entities.FlingEntity; import net.friedl.fling.persistence.entities.FlingEntity;
public interface FlingRepository extends JpaRepository<FlingEntity, Long> { public interface FlingRepository extends JpaRepository<FlingEntity, Long> {

View file

@ -1,13 +1,10 @@
package net.friedl.fling.security; package net.friedl.fling.security;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.friedl.fling.security.authentication.FlingToken; import net.friedl.fling.security.authentication.FlingToken;
import net.friedl.fling.security.authentication.dto.UserAuthDto; import net.friedl.fling.security.authentication.dto.UserAuthDto;
@ -27,10 +24,12 @@ public class AuthorizationService {
} }
public boolean allowUpload(Long flingId, AbstractAuthenticationToken token) { public boolean allowUpload(Long flingId, AbstractAuthenticationToken token) {
if (!(token instanceof FlingToken)) return false; if (!(token instanceof FlingToken))
return false;
FlingToken flingToken = (FlingToken) token; FlingToken flingToken = (FlingToken) token;
if (flingToken.getGrantedFlingAuthority().getAuthority().equals(FlingAuthority.FLING_OWNER.name())) { if (flingToken.getGrantedFlingAuthority().getAuthority()
.equals(FlingAuthority.FLING_OWNER.name())) {
return true; return true;
} }
@ -49,10 +48,12 @@ public class AuthorizationService {
} }
public boolean allowFlingAccess(Long flingId, AbstractAuthenticationToken token) { public boolean allowFlingAccess(Long flingId, AbstractAuthenticationToken token) {
if (!(token instanceof FlingToken)) return false; if (!(token instanceof FlingToken))
return false;
FlingToken flingToken = (FlingToken) token; FlingToken flingToken = (FlingToken) token;
if (flingToken.getGrantedFlingAuthority().getAuthority().equals(FlingAuthority.FLING_OWNER.name())) { if (flingToken.getGrantedFlingAuthority().getAuthority()
.equals(FlingAuthority.FLING_OWNER.name())) {
return true; return true;
} }
@ -60,10 +61,12 @@ public class AuthorizationService {
} }
public boolean allowFlingAccess(AbstractAuthenticationToken token, HttpServletRequest request) { public boolean allowFlingAccess(AbstractAuthenticationToken token, HttpServletRequest request) {
if (!(token instanceof FlingToken)) return false; if (!(token instanceof FlingToken))
return false;
FlingToken flingToken = (FlingToken) token; FlingToken flingToken = (FlingToken) token;
if (flingToken.getGrantedFlingAuthority().getAuthority().equals(FlingAuthority.FLING_OWNER.name())) { if (flingToken.getGrantedFlingAuthority().getAuthority()
.equals(FlingAuthority.FLING_OWNER.name())) {
return true; return true;
} }

View file

@ -1,6 +1,5 @@
package net.friedl.fling.security; package net.friedl.fling.security;
public enum FlingAuthority { public enum FlingAuthority {
FLING_OWNER, FLING_OWNER, FLING_USER
FLING_USER
} }

View file

@ -3,11 +3,9 @@ package net.friedl.fling.security;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.Key; import java.security.Key;
import java.util.List; import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import io.jsonwebtoken.JwtParser; import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts; import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys; import io.jsonwebtoken.security.Keys;

View file

@ -1,11 +1,9 @@
package net.friedl.fling.security; package net.friedl.fling.security;
import static org.springframework.security.config.Customizer.withDefaults; import static org.springframework.security.config.Customizer.withDefaults;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -20,7 +18,6 @@ import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource; import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -136,7 +133,8 @@ public class FlingWebSecurityConfigurer extends WebSecurityConfigurerAdapter {
// setAllowedHeaders is important! Without it, OPTIONS preflight request // setAllowedHeaders is important! Without it, OPTIONS preflight request
// will fail with 403 Invalid CORS request // will fail with 403 Invalid CORS request
configuration.setAllowedHeaders(List.of("Authorization", "Cache-Control", "Content-Type", "Origin")); configuration
.setAllowedHeaders(List.of("Authorization", "Cache-Control", "Content-Type", "Origin"));
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration); source.registerCorsConfiguration("/**", configuration);

View file

@ -5,7 +5,6 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import net.friedl.fling.security.authentication.dto.OwnerAuthDto; import net.friedl.fling.security.authentication.dto.OwnerAuthDto;
import net.friedl.fling.security.authentication.dto.UserAuthDto; import net.friedl.fling.security.authentication.dto.UserAuthDto;

View file

@ -3,13 +3,11 @@ package net.friedl.fling.security.authentication;
import java.security.Key; import java.security.Key;
import java.time.Instant; import java.time.Instant;
import java.util.Date; import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder; import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.JwtParser; import io.jsonwebtoken.JwtParser;

View file

@ -1,7 +1,6 @@
package net.friedl.fling.security.authentication; package net.friedl.fling.security.authentication;
import java.util.List; import java.util.List;
import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.authentication.AbstractAuthenticationToken;
public class FlingToken extends AbstractAuthenticationToken { public class FlingToken extends AbstractAuthenticationToken {

View file

@ -1,7 +1,6 @@
package net.friedl.fling.security.authentication; package net.friedl.fling.security.authentication;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import net.friedl.fling.security.FlingAuthority; import net.friedl.fling.security.FlingAuthority;
/** /**

View file

@ -1,19 +1,16 @@
package net.friedl.fling.security.authentication; package net.friedl.fling.security.authentication;
import java.io.IOException; import java.io.IOException;
import javax.servlet.FilterChain; import javax.servlet.FilterChain;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.filter.OncePerRequestFilter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
@ -30,12 +27,13 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
} }
@Override @Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException { throws ServletException, IOException {
String header = request.getHeader(HEADER_STRING); String header = request.getHeader(HEADER_STRING);
if(header == null || !header.startsWith(TOKEN_PREFIX)) { if (header == null || !header.startsWith(TOKEN_PREFIX)) {
log.warn("Could not find bearer token. No JWT authentication."); log.warn("Could not find bearer token. No JWT authentication.");
filterChain.doFilter(request, response); filterChain.doFilter(request, response);
return; return;
@ -45,7 +43,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
SecurityContext securityContext = SecurityContextHolder.getContext(); SecurityContext securityContext = SecurityContextHolder.getContext();
if(securityContext.getAuthentication() == null) { if (securityContext.getAuthentication() == null) {
Authentication authentication = authenticationService.parseAuthentication(authToken); Authentication authentication = authenticationService.parseAuthentication(authToken);
securityContext.setAuthentication(authentication); securityContext.setAuthentication(authentication);
} }

View file

@ -4,14 +4,11 @@ import java.io.InputStream;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import javax.transaction.Transactional; import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.json.JsonParser; import org.springframework.boot.json.JsonParser;
import org.springframework.boot.json.JsonParserFactory; import org.springframework.boot.json.JsonParserFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import net.friedl.fling.model.dto.ArtifactDto; import net.friedl.fling.model.dto.ArtifactDto;
import net.friedl.fling.model.mapper.ArtifactMapper; import net.friedl.fling.model.mapper.ArtifactMapper;
import net.friedl.fling.persistence.archive.Archive; import net.friedl.fling.persistence.archive.Archive;

View file

@ -16,16 +16,13 @@ import java.util.function.Supplier;
import java.util.zip.Deflater; import java.util.zip.Deflater;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream; import java.util.zip.ZipOutputStream;
import javax.transaction.Transactional; import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.util.Pair; import org.springframework.data.util.Pair;
import org.springframework.security.crypto.codec.Hex; import org.springframework.security.crypto.codec.Hex;
import org.springframework.security.crypto.keygen.KeyGenerators; import org.springframework.security.crypto.keygen.KeyGenerators;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.friedl.fling.model.dto.FlingDto; import net.friedl.fling.model.dto.FlingDto;
import net.friedl.fling.model.mapper.FlingMapper; import net.friedl.fling.model.mapper.FlingMapper;
@ -46,7 +43,8 @@ public class FlingService {
private MessageDigest keyHashDigest; private MessageDigest keyHashDigest;
@Autowired @Autowired
public FlingService(FlingRepository flingRepository, FlingMapper flingMapper, Archive archive, MessageDigest keyHashDigest) { public FlingService(FlingRepository flingRepository, FlingMapper flingMapper, Archive archive,
MessageDigest keyHashDigest) {
this.flingRepository = flingRepository; this.flingRepository = flingRepository;
this.flingMapper = flingMapper; this.flingMapper = flingMapper;
this.archive = archive; this.archive = archive;
@ -100,7 +98,8 @@ public class FlingService {
public boolean hasAuthCode(Long flingId, String authCode) { public boolean hasAuthCode(Long flingId, String authCode) {
var fling = flingRepository.getOne(flingId); var fling = flingRepository.getOne(flingId);
if(!StringUtils.hasText(fling.getAuthCode())) return true; if (!StringUtils.hasText(fling.getAuthCode()))
return true;
return fling.getAuthCode().equals(hashKey(authCode)); return fling.getAuthCode().equals(hashKey(authCode));
} }
@ -126,23 +125,23 @@ public class FlingService {
return fling.getArtifacts().stream() return fling.getArtifacts().stream()
.map(ae -> ae.getSize()) .map(ae -> ae.getSize())
.reduce(0L, (acc, as) -> acc+as); .reduce(0L, (acc, as) -> acc + as);
} }
public String packageFling(Long flingId) throws IOException, ArchiveException { public String packageFling(Long flingId) throws IOException, ArchiveException {
var fling = flingRepository.getOne(flingId); var fling = flingRepository.getOne(flingId);
var tempFile = Files.createTempFile(Long.toString(flingId), ".zip"); var tempFile = Files.createTempFile(Long.toString(flingId), ".zip");
try(var zipStream = new ZipOutputStream(new FileOutputStream(tempFile.toFile()))){ try (var zipStream = new ZipOutputStream(new FileOutputStream(tempFile.toFile()))) {
zipStream.setLevel(Deflater.BEST_SPEED); zipStream.setLevel(Deflater.BEST_SPEED);
for(ArtifactEntity artifactEntity: fling.getArtifacts()) { for (ArtifactEntity artifactEntity : fling.getArtifacts()) {
ZipEntry ze = new ZipEntry(artifactEntity.getName()); ZipEntry ze = new ZipEntry(artifactEntity.getName());
zipStream.putNextEntry(ze); zipStream.putNextEntry(ze);
var artifactStream = archive.get(artifactEntity.getDoi()); var artifactStream = archive.get(artifactEntity.getDoi());
try(var archiveEntryStream = new BufferedInputStream(artifactStream)) { try (var archiveEntryStream = new BufferedInputStream(artifactStream)) {
int b; int b;
while( (b = archiveEntryStream.read()) != -1 ) { while ((b = archiveEntryStream.read()) != -1) {
zipStream.write(b); zipStream.write(b);
} }
} finally { } finally {
@ -179,14 +178,16 @@ public class FlingService {
} }
public String hashKey(String key) { public String hashKey(String key) {
if(!StringUtils.hasText(key)) return null; if (!StringUtils.hasText(key))
return null;
return new String(Hex.encode(keyHashDigest.digest(key.getBytes()))); return new String(Hex.encode(keyHashDigest.digest(key.getBytes())));
} }
private <T> void mergeNonEmpty(Supplier<T> sup, Consumer<T> con) { private <T> void mergeNonEmpty(Supplier<T> sup, Consumer<T> con) {
T r = sup.get(); T r = sup.get();
if(r != null) con.accept(r); if (r != null)
con.accept(r);
} }
private <T> void mergeWithEmpty(Supplier<T> sup, Consumer<T> con) { private <T> void mergeWithEmpty(Supplier<T> sup, Consumer<T> con) {

View file

@ -1,287 +0,0 @@
---
openapi: 3.0.2
info:
title: Fling
version: 1.0.0
description: A project based API for publishing and sharing digital artifacts
contact:
name: Armin Friedl
email: dev@friedl.net
paths:
/fling:
summary: A fling share
description: |-
A grouping of shared objects. Settings for sharing and expiration are
associated with a fling.
get:
responses:
"200":
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Fling'
description: List of metadata for all flings
summary: Get a list of metadata for all flings
post:
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Fling'
required: true
responses:
"200":
description: Fling created successfuly
summary: Create a new fling
/fling/{flingId}:
get:
responses:
"200":
content:
application/json:
schema:
$ref: '#/components/schemas/Fling'
description: A fling object containing all metadata of the fling
summary: Get metadata for a fling
description: Expiration, sharing and general information of a fling.
delete:
responses:
"200":
description: Fling deleted successfully
patch:
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Fling'
required: true
parameters:
- name: id
description: The unique fling id
schema:
format: int64
type: integer
in: query
required: true
responses:
"200":
description: Fling was successfully updated
parameters:
- name: flingId
description: Unique id of the fling
schema:
format: int64
type: integer
in: path
required: true
/f:
summary: Endpoint for accessing flings by external users
/f/{shareId}:
get:
responses:
"302":
content:
text/html:
schema:
type: string
description: |-
If the fling is marked as direct download, the user will be directly redirected
to /f/{sharId}/download which starts the fling download.
"200":
content:
application/json: {}
description: sdf
parameters:
- name: shareId
description: |-
A share id with which a fling can be uniquely identified. The share id might be
the fling id also used in /fling endpoints, another artificially generated id or
a customURL given by the fling creator
schema:
type: string
in: path
required: true
/fling/{flingId}/artifact:
summary: Upload an object to the fling identified by id
get:
responses:
"200":
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Artifact'
description: A list of metadata of all objects within this fling
summary: Retrieve a list of metadata all objects within this fling
post:
requestBody:
description: "Content type is any media type from \nhttps://www.iana.org/assignments/media-types/media-types.xhtml.\n\
The content can by arbitrary payload and will be stored as-is."
content:
application/octet-stream:
schema:
format: binary
type: string
required: true
parameters:
- name: name
description: The name of the object
schema:
type: string
in: query
required: true
- name: path
description: |-
A path under which the object should be stored. Nested paths must be delimited
by forward slash '/'. The path might or might not start with a '/', it will always
be interpreted as absolute starting from the fling root.
schema:
type: string
in: query
responses:
"200":
content:
application/json:
schema:
$ref: '#/components/schemas/Artifact'
description: Return the metadata of a fling object after successful request
parameters:
- name: flingId
description: Unique id for the fling
schema:
format: int64
type: integer
in: path
required: true
/fling/{flingId}/artifact/{objectId}:
summary: Endpoint for interacting with individual objects within a fling
get:
responses:
"200":
content:
application/json:
schema:
$ref: '#/components/schemas/Artifact'
description: Return the metadata of a fling object after successful request
summary: Retrive the metadata of an object within a fling
put:
requestBody:
description: "Content type is any media type from \nhttps://www.iana.org/assignments/media-types/media-types.xhtml.\n\
The content can by arbitrary payload and will be stored as-is."
content:
application/octet-stream:
schema:
format: binary
type: string
required: true
responses:
"200":
content:
application/json:
schema:
$ref: '#/components/schemas/Artifact'
description: Return the metadata of a fling object after successful request
summary: Create a new version of the object
parameters:
- name: flingId
description: The unique id of the fling
schema:
format: int64
type: integer
in: path
required: true
- name: objectId
description: |-
The unique id of the object within its fling. The id is not necessarily globally
unique across all flings.
schema:
format: int64
type: integer
in: path
required: true
components:
schemas:
Fling:
description: |-
Fling containing all metadata of a fling, including general information,
sharing settings and expiration settings.
required:
- name
type: object
properties:
name:
description: Human readable name of the fling
type: string
id:
format: int64
description: Unique id of the fling
type: integer
expiration:
description: Expiration settings
type: object
properties:
expirationType:
description: Expiration type
enum:
- Time
- Clicks
type: string
value:
description: Parsable string representation for the expiration type
type: string
sharing:
description: Settings for sharing
type: object
properties:
directDownload:
description: Accessing the share will immediately prompt a download
type: boolean
upload:
description: Allow external users to upload to the share
type: boolean
customURL:
description: |-
Makes the fling available under a custom URL. The URL is only
allowed to have one path element. The allowed characters are
[A-Za-z0-9-._~], that is, the unreserved URL characters of
https://www.ietf.org/rfc/rfc3986 excluding the forward
slash. The customURL must be unique across all flings
of a Fling application deployment.
type: string
Artifact:
description: An object in a fling share
required:
- name
- doi
type: object
properties:
name:
description: The name of the object
type: string
id:
format: int64
description: The unique id of the object within its fling
type: integer
path:
description: |-
The path of the object within its fling. Nested paths are separated by a forward
slash '/'. A path may or may not start with '/'. A path will always be interpreted
as absolute with the fling of the object as root.
type: string
doi:
description: "A unique and stable id for the fling object. This id is unique\
\ across all flings\nand versions of an object within a Fling deployment.\
\ A doi is never assigned twice\nby a Fling deployment, even if the object\
\ it referred to (or a version thereof) \nwas delted. A doi might not\
\ resolve to an object if the object was deleted."
type: string
version:
description: The version of the object
type: integer
fling:
format: int64
description: The id of the fling this object belongs to
type: integer

View file

@ -5,9 +5,7 @@ import static org.hamcrest.Matchers.hasSize;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import java.util.List; import java.util.List;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
@ -16,7 +14,6 @@ import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.FilterType; import org.springframework.context.annotation.FilterType;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import net.friedl.fling.model.dto.ArtifactDto; import net.friedl.fling.model.dto.ArtifactDto;
import net.friedl.fling.service.ArtifactService; import net.friedl.fling.service.ArtifactService;