From 49fa5ee6e8271d433cd9a3b00c3533495e285c3e Mon Sep 17 00:00:00 2001
From: Cosmin Cojocar <cosmin.cojocar@gmx.ch>
Date: Mon, 12 Nov 2018 21:48:14 +0100
Subject: [PATCH] Avoid overwriting exiting redirect URI and trusted peers when
 updating the client

Also skip configure the Public field.
---
 server/api.go      | 22 +++++++++++++++++++---
 server/api_test.go | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/server/api.go b/server/api.go
index f59be4ea..20b645d1 100644
--- a/server/api.go
+++ b/server/api.go
@@ -87,12 +87,11 @@ func (d dexAPI) UpdateClient(ctx context.Context, req *api.UpdateClientReq) (*ap
 
 	err := d.s.UpdateClient(req.Id, func(old storage.Client) (storage.Client, error) {
 		if req.RedirectUris != nil && len(req.RedirectUris) > 0 {
-			old.RedirectURIs = req.RedirectUris
+			old.RedirectURIs = mergeSlice(old.RedirectURIs, req.RedirectUris)
 		}
 		if req.TrustedPeers != nil && len(req.TrustedPeers) > 0 {
-			old.TrustedPeers = req.TrustedPeers
+			old.TrustedPeers = mergeSlice(old.TrustedPeers, req.TrustedPeers)
 		}
-		old.Public = req.Public
 		if req.Name != "" {
 			old.Name = req.Name
 		}
@@ -112,6 +111,23 @@ func (d dexAPI) UpdateClient(ctx context.Context, req *api.UpdateClientReq) (*ap
 	return &api.UpdateClientResp{}, nil
 }
 
+func mergeSlice(s1 []string, s2 []string) []string {
+	isPresent := func(i string, s []string) bool {
+		for _, j := range s {
+			if j == i {
+				return true
+			}
+		}
+		return false
+	}
+	for _, i := range s2 {
+		if !isPresent(i, s1) {
+			s1 = append(s1, i)
+		}
+	}
+	return s1
+}
+
 func (d dexAPI) DeleteClient(ctx context.Context, req *api.DeleteClientReq) (*api.DeleteClientResp, error) {
 	err := d.s.DeleteClient(req.Id)
 	if err != nil {
diff --git a/server/api_test.go b/server/api_test.go
index 7e77a010..209dabd6 100644
--- a/server/api_test.go
+++ b/server/api_test.go
@@ -461,3 +461,42 @@ func find(item string, items []string) bool {
 	}
 	return false
 }
+
+func TestMergeSlice(t *testing.T) {
+	tests := map[string]struct {
+		s1   []string
+		s2   []string
+		want []string
+	}{
+		"merge slice": {
+			s1:   []string{"t1", "t2"},
+			s2:   []string{"t3"},
+			want: []string{"t1", "t2", "t3"},
+		},
+		"merge slice with duplicates": {
+			s1:   []string{"t1", "t2"},
+			s2:   []string{"t3", "t2"},
+			want: []string{"t1", "t2", "t3"},
+		},
+		"merge slice with empty slice": {
+			s1:   []string{"t1", "t2"},
+			s2:   []string{},
+			want: []string{"t1", "t2"},
+		},
+	}
+
+	for name, tc := range tests {
+		t.Run(name, func(t *testing.T) {
+			got := mergeSlice(tc.s1, tc.s2)
+			if len(got) != len(tc.want) {
+				t.Errorf("expected equal slice")
+			}
+			for _, want := range tc.want {
+				found := find(want, got)
+				if !found {
+					t.Errorf("missing element: %s", want)
+				}
+			}
+		})
+	}
+}
-- 
GitLab