mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2025-12-30 17:00:57 -06:00
graph: Add config knob to set a minimal grace period for schoolTermination
When setting a terminationDate on a School, it's possible to configure a grace period now so that only terminationDate that are at least a certain time in the future can be set. We also now forbid to set a terminationDate in the past.
This commit is contained in:
committed by
Ralf Haferkamp
parent
0bc36f1cf5
commit
51bc49d5b5
@@ -94,6 +94,8 @@ type LDAPEducationConfig struct {
|
||||
SchoolNameAttribute string `yaml:"school_name_attribute" env:"GRAPH_LDAP_SCHOOL_NAME_ATTRIBUTE" desc:"LDAP Attribute to use for the name of a school."`
|
||||
SchoolNumberAttribute string `yaml:"school_number_attribute" env:"GRAPH_LDAP_SCHOOL_NUMBER_ATTRIBUTE" desc:"LDAP Attribute to use for the number of a school."`
|
||||
SchoolIDAttribute string `yaml:"school_id_attribute" env:"GRAPH_LDAP_SCHOOL_ID_ATTRIBUTE" desc:"LDAP Attribute to use as the unique id for schools. This should be a stable globally unique ID like a UUID."`
|
||||
|
||||
SchoolTerminationGraceDays int `yaml:"school_termination_min_grace_days" env:"GRAPH_LDAP_SCHOOL_TERMINATION_MIN_GRACE_DAYS" desc:"When setting a 'terminationDate' for a school, require the date to be at least this number of days in the future."`
|
||||
}
|
||||
|
||||
type Identity struct {
|
||||
|
||||
@@ -80,6 +80,16 @@ func (g Graph) PostEducationSchool(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// validate terminationDate attribute, needs to be "far enough" in the future, terminationDate can be nil (means
|
||||
// termination date is to be deleted
|
||||
if terminationDate, ok := school.GetTerminationDateOk(); ok && terminationDate != nil {
|
||||
err = g.validateTerminationDate(*terminationDate)
|
||||
if err != nil {
|
||||
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if school, err = g.identityEducationBackend.CreateEducationSchool(r.Context(), *school); err != nil {
|
||||
logger.Debug().Err(err).Interface("school", school).Msg("could not create school: backend error")
|
||||
errorcode.RenderError(w, r, err)
|
||||
@@ -126,6 +136,16 @@ func (g Graph) PatchEducationSchool(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// validate terminationDate attribute, needs to be "far enough" in the future, terminationDate can be nil (means
|
||||
// termination date is to be deleted
|
||||
if terminationDate, ok := school.GetTerminationDateOk(); ok && terminationDate != nil {
|
||||
err = g.validateTerminationDate(*terminationDate)
|
||||
if err != nil {
|
||||
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if school, err = g.identityEducationBackend.UpdateEducationSchool(r.Context(), schoolID, *school); err != nil {
|
||||
logger.Debug().Err(err).Interface("school", school).Msg("could not update school: backend error")
|
||||
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
|
||||
@@ -566,6 +586,19 @@ func (g Graph) DeleteEducationSchoolClass(w http.ResponseWriter, r *http.Request
|
||||
render.NoContent(w, r)
|
||||
}
|
||||
|
||||
func (g Graph) validateTerminationDate(terminationDate time.Time) error {
|
||||
if terminationDate.Before(time.Now()) {
|
||||
return fmt.Errorf("can not set a termination date in the past")
|
||||
}
|
||||
graceDays := g.config.Identity.LDAP.EducationConfig.SchoolTerminationGraceDays
|
||||
if graceDays != 0 {
|
||||
if terminationDate.Before(time.Now().Add(time.Duration(graceDays) * 24 * time.Hour)) {
|
||||
return fmt.Errorf("termination needs to be at least %d day(s) in the future", graceDays)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func sortEducationSchools(req *godata.GoDataRequest, schools []*libregraph.EducationSchool) ([]*libregraph.EducationSchool, error) {
|
||||
if req.Query.OrderBy == nil || len(req.Query.OrderBy.OrderByItems) != 1 {
|
||||
return schools, nil
|
||||
|
||||
@@ -74,6 +74,7 @@ var _ = Describe("Schools", func() {
|
||||
|
||||
cfg = defaults.FullDefaultConfig()
|
||||
cfg.Identity.LDAP.CACert = "" // skip the startup checks, we don't use LDAP at all in this tests
|
||||
cfg.Identity.LDAP.EducationConfig.SchoolTerminationGraceDays = 30
|
||||
cfg.TokenManager.JWTSecret = "loremipsum"
|
||||
cfg.Commons = &shared.Commons{}
|
||||
cfg.GRPCClientTLS = &shared.GRPCClientTLS{}
|
||||
@@ -294,8 +295,17 @@ var _ = Describe("Schools", func() {
|
||||
schoolUpdate.SetDisplayName("New School Name")
|
||||
schoolUpdateJson, _ := json.Marshal(schoolUpdate)
|
||||
|
||||
schoolUpdatePast := libregraph.NewEducationSchool()
|
||||
schoolUpdatePast.SetTerminationDate(time.Now().Add(-time.Hour * 1))
|
||||
schoolUpdatePastJson, _ := json.Marshal(schoolUpdatePast)
|
||||
|
||||
schoolUpdateBeforeGrace := libregraph.NewEducationSchool()
|
||||
schoolUpdateBeforeGrace.SetTerminationDate(time.Now().Add(24 * 10 * time.Hour))
|
||||
schoolUpdateBeforeGraceJson, _ := json.Marshal(schoolUpdateBeforeGrace)
|
||||
|
||||
schoolUpdatePastGrace := libregraph.NewEducationSchool()
|
||||
schoolUpdatePastGrace.SetTerminationDate(time.Now().Add(24 * 31 * time.Hour))
|
||||
schoolUpdatePastGraceJson, _ := json.Marshal(schoolUpdatePastGrace)
|
||||
|
||||
BeforeEach(func() {
|
||||
identityEducationBackend.On("UpdateEducationSchool", mock.Anything, mock.Anything, mock.Anything).Return(schoolUpdate, nil)
|
||||
@@ -315,6 +325,9 @@ var _ = Describe("Schools", func() {
|
||||
Entry("handles missing or empty school id", "", bytes.NewBufferString(""), http.StatusBadRequest),
|
||||
Entry("handles malformed school id", "school%id", bytes.NewBuffer(schoolUpdateJson), http.StatusBadRequest),
|
||||
Entry("updates the school", "school-id", bytes.NewBuffer(schoolUpdateJson), http.StatusOK),
|
||||
Entry("fails to set a termination date in the past", "school-id", bytes.NewBuffer(schoolUpdatePastJson), http.StatusBadRequest),
|
||||
Entry("fails to set a termination date before grace period", "school-id", bytes.NewBuffer(schoolUpdateBeforeGraceJson), http.StatusBadRequest),
|
||||
Entry("succeeds to set a termination date past the grace period", "school-id", bytes.NewBuffer(schoolUpdatePastGraceJson), http.StatusOK),
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user