[Draft] Implement Early deletion by Submitter #37 #38
7 changed files with 151 additions and 10 deletions
fix various things
- migration where not being applied as the old structure was successfully parsed as the new structure - incorrect field order for toml serialization - docker stuff
commit
a316cc83b4
|
|
@ -1,9 +1,15 @@
|
||||||
FROM archlinux:base-devel AS source
|
FROM archlinux:base-devel AS source
|
||||||
|
|
||||||
|
ARG UID=1999
|
||||||
|
ARG GID=1999
|
||||||
|
|
||||||
EXPOSE 8080/tcp
|
EXPOSE 8080/tcp
|
||||||
VOLUME [ "/var/lib/jobboerse/job_offers" ]
|
VOLUME [ "/var/lib/jobboerse/job_offers" ]
|
||||||
|
|
||||||
RUN useradd -mU dev
|
RUN echo $UID $GID
|
||||||
|
RUN groupadd -g $GID dev
|
||||||
|
RUN useradd -u $UID -g dev -m dev
|
||||||
|
|
||||||
RUN echo -e "\ndev ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers
|
RUN echo -e "\ndev ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers
|
||||||
|
|
||||||
RUN pacman -Syu --noconfirm
|
RUN pacman -Syu --noconfirm
|
||||||
|
|
@ -12,11 +18,14 @@ COPY . /src_dir
|
||||||
|
|
||||||
RUN chown -R dev:dev /src_dir
|
RUN chown -R dev:dev /src_dir
|
||||||
|
|
||||||
|
COPY ./packages/jobboerse/config/login.toml /usr/lib/jobboerse/config/
|
||||||
|
|
||||||
USER dev
|
USER dev
|
||||||
|
|
||||||
WORKDIR /src_dir/dist/arch/devel
|
WORKDIR /src_dir/dist/arch/devel
|
||||||
|
|
||||||
RUN sudo -u dev -- makepkg -siC --noconfirm
|
RUN id
|
||||||
|
RUN makepkg -siC --noconfirm
|
||||||
|
|
||||||
WORKDIR /usr/lib/jobboerse/
|
WORKDIR /usr/lib/jobboerse/
|
||||||
|
|
||||||
|
|
|
||||||
50
packages/jobboerse/config/dist-test-config.toml
Normal file
50
packages/jobboerse/config/dist-test-config.toml
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
# the base URL Path under which the jobboerse will be accessible (defaults to the root path)
|
||||||
|
# url_base_path = "jobbörse"
|
||||||
|
|
||||||
|
# the path under which the server will store the job offers (default "./job_offers")
|
||||||
|
data_storage_path = "/var/lib/jobboerse/job_offers"
|
||||||
|
|
||||||
|
# when specefied a banner will be placed at the top of the web-page with the content of this field
|
||||||
|
# banner = ""
|
||||||
|
|
||||||
|
# Configuration of the login provider which shall handle the processing of login information submitter through the login dialouge
|
||||||
|
[login_provider]
|
||||||
|
# the type of the configured login provider
|
||||||
|
# for production builds possible options are: Disabled, Simple or Ldap
|
||||||
|
|
||||||
|
type = 'Simple' # deny all login attempts without further configuration options
|
||||||
|
file_path = '/etc/jobboerse/login.toml'
|
||||||
|
|
||||||
|
# type = 'Simple' # lookup username password pairs in a file
|
||||||
|
# file_path = 'config/login.toml' # toml file containing a `users` table with usernames as the keys and clear-text passwords as values
|
||||||
|
|
||||||
|
# type = 'Ldap' # use an ldap server for authentication
|
||||||
|
# server_address = 'ldap://ldap.example.com' # ldap server URL
|
||||||
|
# ldap_user_dn = 'uid=%{username},ou=People,dc=example,dc=com' # user DN template , %{username} will be replaced by the provided username
|
||||||
|
# ldap_user_filter = '(&(objectClass=posixAccount)(uid=%{username}))' # search filter template, %{username} will be replaced by the provided username
|
||||||
|
# starttls = true # use starttls when applicable for the server_address URL (defaults to true)
|
||||||
|
|
||||||
|
# for development builds the value `Development` is also available
|
||||||
|
# type = 'Development' # accepts all username password combinations without further configuration options USE WITH CARE!!!
|
||||||
|
|
||||||
|
# The configuration for sending cofirmation emails
|
||||||
|
# when not specefied no confirmation emails will be send and submitters won't be able to confirm their submissions
|
||||||
|
# [email]
|
||||||
|
# # content of the FROM header for send emails
|
||||||
|
# from = "jobs@example.com"
|
||||||
|
# # content of the SUBJECT header for the confirmation emails
|
||||||
|
# subject = "[Jobbörse] Please, confirm your job-offer submission."
|
||||||
|
|
||||||
|
# you can add additional footer links by adding [[footer_links]] entries
|
||||||
|
# [[footer_links]]
|
||||||
|
# title = "Example"
|
||||||
|
# url = "https://example.com"
|
||||||
|
|
||||||
|
# the default footer links Impressum, Homepage and Source Repository can be overriten by adding a matching [[footer_links]] entry
|
||||||
|
# [[footer_links]]
|
||||||
|
# title = "Homepage"
|
||||||
|
# url = "https://example.com/home"
|
||||||
|
|
||||||
|
# default footer links can also be removed by adding a matching section here without an URL
|
||||||
|
# [[footer_links]]
|
||||||
|
# title = "Source Repository"
|
||||||
|
|
@ -108,7 +108,7 @@ pub(crate) struct Link {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Hash)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Hash)]
|
||||||
#[serde(tag = "type")]
|
#[serde(tag = "type", deny_unknown_fields)]
|
||||||
pub enum ConfirmationStatus {
|
pub enum ConfirmationStatus {
|
||||||
AwaitingConfirmation,
|
AwaitingConfirmation,
|
||||||
Confirmed,
|
Confirmed,
|
||||||
|
|
@ -133,10 +133,10 @@ pub enum ReviewStatus {
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Hash)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Hash)]
|
||||||
pub struct JobOfferStatus {
|
pub struct JobOfferStatus {
|
||||||
review_status: ReviewStatus,
|
|
||||||
confirmation_status: ConfirmationStatus,
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
submitter_token: Option<String>,
|
submitter_token: Option<String>,
|
||||||
|
review_status: ReviewStatus,
|
||||||
|
confirmation_status: ConfirmationStatus,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<V1JobOfferStatus> for JobOfferStatus {
|
impl From<V1JobOfferStatus> for JobOfferStatus {
|
||||||
|
|
@ -570,6 +570,50 @@ impl JobOffer<PathBuf> {
|
||||||
url.set_fragment(Some(&format!("joboffer-{}", id)));
|
url.set_fragment(Some(&format!("joboffer-{}", id)));
|
||||||
Ok(url)
|
Ok(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) fn new_for_test() -> Self {
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
Self {
|
||||||
|
title: "Test".to_string(),
|
||||||
|
offering_party: "Test".to_string(),
|
||||||
|
public_contact_info: false,
|
||||||
|
date_of_submission: better_toml_datetime::Datetime {
|
||||||
|
date: Some(better_toml_datetime::Date(toml::value::Date {
|
||||||
|
year: 2022,
|
||||||
|
month: 10,
|
||||||
|
day: 31,
|
||||||
|
})),
|
||||||
|
time: Some(better_toml_datetime::Time(toml::value::Time {
|
||||||
|
hour: 12,
|
||||||
|
minute: 11,
|
||||||
|
second: 10,
|
||||||
|
nanosecond: 9,
|
||||||
|
})),
|
||||||
|
offset: Some(better_toml_datetime::Offset::Z),
|
||||||
|
},
|
||||||
|
date_of_expiry: Some(Date(toml::value::Date {
|
||||||
|
year: 2022,
|
||||||
|
month: 10,
|
||||||
|
day: 31,
|
||||||
|
})),
|
||||||
|
permanent: false,
|
||||||
|
contact_info: Address::from_str("test@example.com")
|
||||||
|
.expect("the hardcoded value should be fine"),
|
||||||
|
status: JobOfferStatus {
|
||||||
|
submitter_token: Some("Token".to_string()),
|
||||||
|
review_status: ReviewStatus::AwaitingReview,
|
||||||
|
confirmation_status: ConfirmationStatus::AwaitingConfirmation,
|
||||||
|
},
|
||||||
|
attachments: vec![Attachment {
|
||||||
|
title: "Attachment".to_string(),
|
||||||
|
file_name: "filename.txt".to_string(),
|
||||||
|
attachment_location: PathBuf::from("some_path.attachment"),
|
||||||
|
}],
|
||||||
|
links: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct JobOffers {
|
pub struct JobOffers {
|
||||||
|
|
@ -887,3 +931,15 @@ impl Deref for MutBorrowedJobOffer<'_, '_, '_> {
|
||||||
self.data.deref()
|
self.data.deref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use super::JobOffer;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn joboffers_can_be_serialized() -> Result<(), toml::ser::Error> {
|
||||||
|
toml::ser::to_string_pretty(&JobOffer::<PathBuf>::new_for_test()).map(|_| ())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,10 @@ pub(crate) fn internal_server_error_handler<B>(
|
||||||
} else if let Some(err) = err.as_error::<PresentationError>() {
|
} else if let Some(err) = err.as_error::<PresentationError>() {
|
||||||
error!("Internal Server Error due to PresentationError: {}", err)
|
error!("Internal Server Error due to PresentationError: {}", err)
|
||||||
} else if let Some(err) = err.as_error::<SubmissionResponseError>() {
|
} else if let Some(err) = err.as_error::<SubmissionResponseError>() {
|
||||||
error!("Internal Server Error due to SubmissionError: {}", err)
|
error!(
|
||||||
|
"Internal Server Error due to SubmissionResponseError: {}",
|
||||||
|
err
|
||||||
|
)
|
||||||
} else if let Some(err) = err.as_error::<EditResponseError>() {
|
} else if let Some(err) = err.as_error::<EditResponseError>() {
|
||||||
error!("Internal Server Error due to EditResponseError: {}", err)
|
error!("Internal Server Error due to EditResponseError: {}", err)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -284,3 +284,4 @@ pub(crate) enum FormProcessingError {
|
||||||
#[error("invalid hash")]
|
#[error("invalid hash")]
|
||||||
InvalidHash,
|
InvalidHash,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,4 +4,6 @@ USER=${SUDO_USER:-$(whoami)}
|
||||||
|
|
||||||
echo "Generating for ${USER}"
|
echo "Generating for ${USER}"
|
||||||
|
|
||||||
docker build --rm --build-arg UID="$(id -u "${USER}")" --build-arg GID="$(id -g "${USER}")" --build-arg BUILD_FLAGS="--features=dev_mode" --tag jobboerse:dev .
|
# needs root as otherwise we can't run it with root later (images will be in the users images but runing from root images)
|
||||||
|
# see run_dev_conatiner.sh for why that needs root
|
||||||
|
sudo docker build --rm --build-arg UID="$(id -u "${USER}")" --build-arg GID="$(id -g "${USER}")" --build-arg BUILD_FLAGS="--features=dev_mode" --tag jobboerse:dev .
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,28 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
USER=${SUDO_USER:-$(whoami)}
|
||||||
|
|
||||||
docker build -t jobboerse:pkgbuild -f ./Dockerfile-pkgbuild .
|
echo "Generating for ${USER}"
|
||||||
docker run --rm \
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "Building docker image"
|
||||||
|
# needs root as otherwise we can't run it with root later (images will be in the users images but runing from root images)
|
||||||
|
# see run_dev_conatiner.sh for why that needs root
|
||||||
|
sudo docker build \
|
||||||
|
--rm \
|
||||||
|
--build-arg UID="$(id -u "${USER}")" \
|
||||||
|
--build-arg GID="$(id -g "${USER}")" \
|
||||||
|
-t jobboerse:pkgbuild \
|
||||||
|
-f ./Dockerfile-pkgbuild \
|
||||||
|
.
|
||||||
|
|
||||||
|
echo "Starting empheral container"
|
||||||
|
# root is necessary for the volums to be mounted correctly
|
||||||
|
# otherwise they will be owned by root instead of the correct user
|
||||||
|
sudo docker run \
|
||||||
|
--rm \
|
||||||
-p 8080:8080 \
|
-p 8080:8080 \
|
||||||
-v "$(pwd)"/job_offers:/var/lib/jobboerse/job_offers \
|
-v "$(pwd)"/job_offers:/var/lib/jobboerse/job_offers \
|
||||||
-v "$(pwd)"/packages/jobboerse/config:/config \
|
-v "$(pwd)"/packages/jobboerse/config/dist-test-config.toml:/etc/jobboerse/config.toml \
|
||||||
|
-v "$(pwd)"/packages/jobboerse/config/login.toml:/etc/jobboerse/login.toml \
|
||||||
jobboerse:pkgbuild
|
jobboerse:pkgbuild
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue