ソースを参照

Merge pull request #30 from tracim/fix/834_endpoint_enable_disable_notification

Bastien Sevajol 6 年 前
コミット
26d032cbcc
No account linked to committer's email

+ 1 - 5
backend/tracim_backend/models/context_models.py ファイルの表示

@@ -169,7 +169,7 @@ class WorkspaceAndUserPath(object):
169 169
     """
170 170
     def __init__(self, workspace_id: int, user_id: int):
171 171
         self.workspace_id = workspace_id
172
-        self.user_id = workspace_id
172
+        self.user_id = user_id
173 173
 
174 174
 
175 175
 class UserWorkspaceAndContentPath(object):
@@ -266,10 +266,8 @@ class RoleUpdate(object):
266 266
     def __init__(
267 267
         self,
268 268
         role: str,
269
-        do_notify: bool,
270 269
     ):
271 270
         self.role = role
272
-        self.do_notify = do_notify
273 271
 
274 272
 
275 273
 class WorkspaceMemberInvitation(object):
@@ -281,12 +279,10 @@ class WorkspaceMemberInvitation(object):
281 279
         user_id: int,
282 280
         user_email_or_public_name: str,
283 281
         role: str,
284
-        do_notify: str,
285 282
     ):
286 283
         self.role = role
287 284
         self.user_email_or_public_name = user_email_or_public_name
288 285
         self.user_id = user_id
289
-        self.do_notify = do_notify
290 286
 
291 287
 
292 288
 class WorkspaceUpdate(object):

+ 439 - 1
backend/tracim_backend/tests/functional/test_user.py ファイルの表示

@@ -2382,6 +2382,444 @@ class TestUserSetWorkspaceAsRead(FunctionalTest):
2382 2382
         )
2383 2383
 
2384 2384
 
2385
+class TestUserEnableWorkspaceNotification(FunctionalTest):
2386
+    """
2387
+    Tests for /api/v2/users/{user_id}/workspaces/{workspace_id}/notify
2388
+    """
2389
+    def test_api_enable_user_workspace_notification__ok__200__admin(self):
2390
+        # init DB
2391
+        dbsession = get_tm_session(self.session_factory, transaction.manager)
2392
+        admin = dbsession.query(models.User) \
2393
+            .filter(models.User.email == 'admin@admin.admin') \
2394
+            .one()
2395
+        workspace_api = WorkspaceApi(
2396
+            current_user=admin,
2397
+            session=dbsession,
2398
+            config=self.app_config
2399
+
2400
+        )
2401
+        workspace = WorkspaceApi(
2402
+            current_user=admin,
2403
+            session=dbsession,
2404
+            config=self.app_config,
2405
+        ).create_workspace(
2406
+            'test workspace',
2407
+            save_now=True
2408
+        )
2409
+        uapi = UserApi(
2410
+            current_user=admin,
2411
+            session=dbsession,
2412
+            config=self.app_config,
2413
+        )
2414
+        gapi = GroupApi(
2415
+            current_user=admin,
2416
+            session=dbsession,
2417
+            config=self.app_config,
2418
+        )
2419
+        groups = [gapi.get_one_with_name('users')]
2420
+        test_user = uapi.create_user(
2421
+            email='test@test.test',
2422
+            password='pass',
2423
+            name='bob',
2424
+            groups=groups,
2425
+            timezone='Europe/Paris',
2426
+            lang='fr',
2427
+            do_save=True,
2428
+            do_notify=False,
2429
+        )
2430
+        rapi = RoleApi(
2431
+            current_user=admin,
2432
+            session=dbsession,
2433
+            config=self.app_config,
2434
+        )
2435
+        rapi.create_one(test_user, workspace, UserRoleInWorkspace.READER, with_notif=False)  # nopep8
2436
+        transaction.commit()
2437
+        role = rapi.get_one(test_user.user_id, workspace.workspace_id)
2438
+        assert role.do_notify is False
2439
+        self.testapp.authorization = (
2440
+            'Basic',
2441
+            (
2442
+                'admin@admin.admin',
2443
+                'admin@admin.admin'
2444
+            )
2445
+        )
2446
+        self.testapp.put_json('/api/v2/users/{user_id}/workspaces/{workspace_id}/notify'.format(  # nopep8
2447
+            user_id=test_user.user_id,
2448
+            workspace_id=workspace.workspace_id
2449
+        ), status=204)
2450
+        dbsession = get_tm_session(self.session_factory, transaction.manager)
2451
+        rapi = RoleApi(
2452
+            current_user=admin,
2453
+            session=dbsession,
2454
+            config=self.app_config,
2455
+        )
2456
+        role = rapi.get_one(test_user.user_id, workspace.workspace_id)
2457
+        assert role.do_notify is True
2458
+
2459
+    def test_api_enable_user_workspace_notification__ok__200__user_itself(self):
2460
+        # init DB
2461
+        dbsession = get_tm_session(self.session_factory, transaction.manager)
2462
+        admin = dbsession.query(models.User) \
2463
+            .filter(models.User.email == 'admin@admin.admin') \
2464
+            .one()
2465
+        workspace_api = WorkspaceApi(
2466
+            current_user=admin,
2467
+            session=dbsession,
2468
+            config=self.app_config
2469
+
2470
+        )
2471
+        workspace = WorkspaceApi(
2472
+            current_user=admin,
2473
+            session=dbsession,
2474
+            config=self.app_config,
2475
+        ).create_workspace(
2476
+            'test workspace',
2477
+            save_now=True
2478
+        )
2479
+        uapi = UserApi(
2480
+            current_user=admin,
2481
+            session=dbsession,
2482
+            config=self.app_config,
2483
+        )
2484
+        gapi = GroupApi(
2485
+            current_user=admin,
2486
+            session=dbsession,
2487
+            config=self.app_config,
2488
+        )
2489
+        groups = [gapi.get_one_with_name('users')]
2490
+        test_user = uapi.create_user(
2491
+            email='test@test.test',
2492
+            password='pass',
2493
+            name='bob',
2494
+            groups=groups,
2495
+            timezone='Europe/Paris',
2496
+            lang='fr',
2497
+            do_save=True,
2498
+            do_notify=False,
2499
+        )
2500
+        rapi = RoleApi(
2501
+            current_user=admin,
2502
+            session=dbsession,
2503
+            config=self.app_config,
2504
+        )
2505
+        rapi.create_one(test_user, workspace, UserRoleInWorkspace.READER, with_notif=False)  # nopep8
2506
+        transaction.commit()
2507
+        role = rapi.get_one(test_user.user_id, workspace.workspace_id)
2508
+        assert role.do_notify is False
2509
+        self.testapp.authorization = (
2510
+            'Basic',
2511
+            (
2512
+                'test@test.test',
2513
+                'pass',
2514
+            )
2515
+        )
2516
+        self.testapp.put_json('/api/v2/users/{user_id}/workspaces/{workspace_id}/notify'.format(  # nopep8
2517
+            user_id=test_user.user_id,
2518
+            workspace_id=workspace.workspace_id
2519
+        ), status=204)
2520
+
2521
+        dbsession = get_tm_session(self.session_factory, transaction.manager)
2522
+        rapi = RoleApi(
2523
+            current_user=admin,
2524
+            session=dbsession,
2525
+            config=self.app_config,
2526
+        )
2527
+        role = rapi.get_one(test_user.user_id, workspace.workspace_id)
2528
+        assert role.do_notify is True
2529
+
2530
+    def test_api_enable_user_workspace_notification__err__403__other_user(self):
2531
+        # init DB
2532
+        dbsession = get_tm_session(self.session_factory, transaction.manager)
2533
+        admin = dbsession.query(models.User) \
2534
+            .filter(models.User.email == 'admin@admin.admin') \
2535
+            .one()
2536
+        workspace_api = WorkspaceApi(
2537
+            current_user=admin,
2538
+            session=dbsession,
2539
+            config=self.app_config
2540
+
2541
+        )
2542
+        workspace = WorkspaceApi(
2543
+            current_user=admin,
2544
+            session=dbsession,
2545
+            config=self.app_config,
2546
+        ).create_workspace(
2547
+            'test workspace',
2548
+            save_now=True
2549
+        )
2550
+        uapi = UserApi(
2551
+            current_user=admin,
2552
+            session=dbsession,
2553
+            config=self.app_config,
2554
+        )
2555
+        gapi = GroupApi(
2556
+            current_user=admin,
2557
+            session=dbsession,
2558
+            config=self.app_config,
2559
+        )
2560
+        groups = [gapi.get_one_with_name('users')]
2561
+        test_user = uapi.create_user(
2562
+            email='test@test.test',
2563
+            password='pass',
2564
+            name='bob',
2565
+            groups=groups,
2566
+            timezone='Europe/Paris',
2567
+            lang='fr',
2568
+            do_save=True,
2569
+            do_notify=False,
2570
+        )
2571
+        test_user2 = uapi.create_user(
2572
+            email='test2@test2.test2',
2573
+            password='pass',
2574
+            name='boby',
2575
+            groups=groups,
2576
+            timezone='Europe/Paris',
2577
+            lang='fr',
2578
+            do_save=True,
2579
+            do_notify=False,
2580
+        )
2581
+        rapi = RoleApi(
2582
+            current_user=admin,
2583
+            session=dbsession,
2584
+            config=self.app_config,
2585
+        )
2586
+        rapi.create_one(test_user, workspace, UserRoleInWorkspace.READER, with_notif=False)  # nopep8
2587
+        rapi.create_one(test_user2, workspace, UserRoleInWorkspace.READER, with_notif=False)  # nopep8
2588
+        transaction.commit()
2589
+        role = rapi.get_one(test_user.user_id, workspace.workspace_id)
2590
+        assert role.do_notify is False
2591
+        self.testapp.authorization = (
2592
+            'Basic',
2593
+            (
2594
+                'test2@test2.test2',
2595
+                'pass',
2596
+            )
2597
+        )
2598
+        self.testapp.put_json('/api/v2/users/{user_id}/workspaces/{workspace_id}/notify'.format(  # nopep8
2599
+            user_id=test_user.user_id,
2600
+            workspace_id=workspace.workspace_id
2601
+        ), status=403)
2602
+
2603
+
2604
+class TestUserDisableWorkspaceNotification(FunctionalTest):
2605
+    """
2606
+    Tests for /api/v2/users/{user_id}/workspaces/{workspace_id}/unnotify
2607
+    """
2608
+    def test_api_disable_user_workspace_notification__ok__200__admin(self):
2609
+        # init DB
2610
+        dbsession = get_tm_session(self.session_factory, transaction.manager)
2611
+        admin = dbsession.query(models.User) \
2612
+            .filter(models.User.email == 'admin@admin.admin') \
2613
+            .one()
2614
+        workspace_api = WorkspaceApi(
2615
+            current_user=admin,
2616
+            session=dbsession,
2617
+            config=self.app_config
2618
+
2619
+        )
2620
+        workspace = WorkspaceApi(
2621
+            current_user=admin,
2622
+            session=dbsession,
2623
+            config=self.app_config,
2624
+        ).create_workspace(
2625
+            'test workspace',
2626
+            save_now=True
2627
+        )
2628
+        uapi = UserApi(
2629
+            current_user=admin,
2630
+            session=dbsession,
2631
+            config=self.app_config,
2632
+        )
2633
+        gapi = GroupApi(
2634
+            current_user=admin,
2635
+            session=dbsession,
2636
+            config=self.app_config,
2637
+        )
2638
+        groups = [gapi.get_one_with_name('users')]
2639
+        test_user = uapi.create_user(
2640
+            email='test@test.test',
2641
+            password='pass',
2642
+            name='bob',
2643
+            groups=groups,
2644
+            timezone='Europe/Paris',
2645
+            lang='fr',
2646
+            do_save=True,
2647
+            do_notify=True,
2648
+        )
2649
+        rapi = RoleApi(
2650
+            current_user=admin,
2651
+            session=dbsession,
2652
+            config=self.app_config,
2653
+        )
2654
+        rapi.create_one(test_user, workspace, UserRoleInWorkspace.READER, with_notif=True)  # nopep8
2655
+        transaction.commit()
2656
+        role = rapi.get_one(test_user.user_id, workspace.workspace_id)
2657
+        assert role.do_notify is True
2658
+        self.testapp.authorization = (
2659
+            'Basic',
2660
+            (
2661
+                'admin@admin.admin',
2662
+                'admin@admin.admin'
2663
+            )
2664
+        )
2665
+        self.testapp.put_json('/api/v2/users/{user_id}/workspaces/{workspace_id}/unnotify'.format(  # nopep8
2666
+            user_id=test_user.user_id,
2667
+            workspace_id=workspace.workspace_id
2668
+        ), status=204)
2669
+
2670
+        dbsession = get_tm_session(self.session_factory, transaction.manager)
2671
+        rapi = RoleApi(
2672
+            current_user=admin,
2673
+            session=dbsession,
2674
+            config=self.app_config,
2675
+        )
2676
+        role = rapi.get_one(test_user.user_id, workspace.workspace_id)
2677
+        assert role.do_notify is False
2678
+
2679
+    def test_api_enable_user_workspace_notification__ok__200__user_itself(self):
2680
+        # init DB
2681
+        dbsession = get_tm_session(self.session_factory, transaction.manager)
2682
+        admin = dbsession.query(models.User) \
2683
+            .filter(models.User.email == 'admin@admin.admin') \
2684
+            .one()
2685
+        workspace_api = WorkspaceApi(
2686
+            current_user=admin,
2687
+            session=dbsession,
2688
+            config=self.app_config
2689
+
2690
+        )
2691
+        workspace = WorkspaceApi(
2692
+            current_user=admin,
2693
+            session=dbsession,
2694
+            config=self.app_config,
2695
+        ).create_workspace(
2696
+            'test workspace',
2697
+            save_now=True
2698
+        )
2699
+        uapi = UserApi(
2700
+            current_user=admin,
2701
+            session=dbsession,
2702
+            config=self.app_config,
2703
+        )
2704
+        gapi = GroupApi(
2705
+            current_user=admin,
2706
+            session=dbsession,
2707
+            config=self.app_config,
2708
+        )
2709
+        groups = [gapi.get_one_with_name('users')]
2710
+        test_user = uapi.create_user(
2711
+            email='test@test.test',
2712
+            password='pass',
2713
+            name='bob',
2714
+            groups=groups,
2715
+            timezone='Europe/Paris',
2716
+            lang='fr',
2717
+            do_save=True,
2718
+            do_notify=False,
2719
+        )
2720
+        rapi = RoleApi(
2721
+            current_user=admin,
2722
+            session=dbsession,
2723
+            config=self.app_config,
2724
+        )
2725
+        rapi.create_one(test_user, workspace, UserRoleInWorkspace.READER, with_notif=True)  # nopep8
2726
+        transaction.commit()
2727
+        role = rapi.get_one(test_user.user_id, workspace.workspace_id)
2728
+        assert role.do_notify is True
2729
+        self.testapp.authorization = (
2730
+            'Basic',
2731
+            (
2732
+                'test@test.test',
2733
+                'pass',
2734
+            )
2735
+        )
2736
+        self.testapp.put_json('/api/v2/users/{user_id}/workspaces/{workspace_id}/unnotify'.format(  # nopep8
2737
+            user_id=test_user.user_id,
2738
+            workspace_id=workspace.workspace_id
2739
+        ), status=204)
2740
+        dbsession = get_tm_session(self.session_factory, transaction.manager)
2741
+        rapi = RoleApi(
2742
+            current_user=admin,
2743
+            session=dbsession,
2744
+            config=self.app_config,
2745
+        )
2746
+        role = rapi.get_one(test_user.user_id, workspace.workspace_id)
2747
+        assert role.do_notify is False
2748
+
2749
+    def test_api_disable_user_workspace_notification__err__403__other_user(self):
2750
+        # init DB
2751
+        dbsession = get_tm_session(self.session_factory, transaction.manager)
2752
+        admin = dbsession.query(models.User) \
2753
+            .filter(models.User.email == 'admin@admin.admin') \
2754
+            .one()
2755
+        workspace_api = WorkspaceApi(
2756
+            current_user=admin,
2757
+            session=dbsession,
2758
+            config=self.app_config
2759
+
2760
+        )
2761
+        workspace = WorkspaceApi(
2762
+            current_user=admin,
2763
+            session=dbsession,
2764
+            config=self.app_config,
2765
+        ).create_workspace(
2766
+            'test workspace',
2767
+            save_now=True
2768
+        )
2769
+        uapi = UserApi(
2770
+            current_user=admin,
2771
+            session=dbsession,
2772
+            config=self.app_config,
2773
+        )
2774
+        gapi = GroupApi(
2775
+            current_user=admin,
2776
+            session=dbsession,
2777
+            config=self.app_config,
2778
+        )
2779
+        groups = [gapi.get_one_with_name('users')]
2780
+        test_user = uapi.create_user(
2781
+            email='test@test.test',
2782
+            password='pass',
2783
+            name='bob',
2784
+            groups=groups,
2785
+            timezone='Europe/Paris',
2786
+            lang='fr',
2787
+            do_save=True,
2788
+            do_notify=False,
2789
+        )
2790
+        test_user2 = uapi.create_user(
2791
+            email='test2@test2.test2',
2792
+            password='pass',
2793
+            name='boby',
2794
+            groups=groups,
2795
+            timezone='Europe/Paris',
2796
+            lang='fr',
2797
+            do_save=True,
2798
+            do_notify=False,
2799
+        )
2800
+        rapi = RoleApi(
2801
+            current_user=admin,
2802
+            session=dbsession,
2803
+            config=self.app_config,
2804
+        )
2805
+        rapi.create_one(test_user, workspace, UserRoleInWorkspace.READER, with_notif=True)  # nopep8
2806
+        rapi.create_one(test_user2, workspace, UserRoleInWorkspace.READER, with_notif=False)  # nopep8
2807
+        transaction.commit()
2808
+        role = rapi.get_one(test_user.user_id, workspace.workspace_id)
2809
+        assert role.do_notify is True
2810
+        self.testapp.authorization = (
2811
+            'Basic',
2812
+            (
2813
+                'test2@test2.test2',
2814
+                'pass',
2815
+            )
2816
+        )
2817
+        self.testapp.put_json('/api/v2/users/{user_id}/workspaces/{workspace_id}/unnotify'.format(  # nopep8
2818
+            user_id=test_user.user_id,
2819
+            workspace_id=workspace.workspace_id
2820
+        ), status=403)
2821
+
2822
+
2385 2823
 class TestUserWorkspaceEndpoint(FunctionalTest):
2386 2824
     """
2387 2825
     Tests for /api/v2/users/{user_id}/workspaces
@@ -4235,7 +4673,7 @@ class TestSetUserInfoEndpoint(FunctionalTest):
4235 4673
         params = {
4236 4674
             'public_name': 'updated',
4237 4675
             'timezone': 'Europe/London',
4238
-            'lang' : 'en',
4676
+            'lang': 'en',
4239 4677
         }
4240 4678
         self.testapp.put_json(
4241 4679
             '/api/v2/users/{}'.format(user_id),

+ 243 - 14
backend/tracim_backend/tests/functional/test_workspaces.py ファイルの表示

@@ -875,6 +875,106 @@ class TestWorkspaceEndpoint(FunctionalTest):
875 875
         assert 'details' in res.json.keys()
876 876
 
877 877
 
878
+class TestWorkspacesEndpoints(FunctionalTest):
879
+    """
880
+    Tests for /api/v2/workspaces
881
+    """
882
+    fixtures = [BaseFixture]
883
+
884
+    def test_api__get_workspaces__ok_200__nominal_case(self):
885
+        """
886
+        Check obtain all workspaces reachables for user with user auth.
887
+        """
888
+        dbsession = get_tm_session(self.session_factory, transaction.manager)
889
+        admin = dbsession.query(models.User) \
890
+            .filter(models.User.email == 'admin@admin.admin') \
891
+            .one()
892
+
893
+        workspace_api = WorkspaceApi(
894
+            session=dbsession,
895
+            current_user=admin,
896
+            config=self.app_config,
897
+        )
898
+        workspace_api.create_workspace('test', save_now=True)  # nopep8
899
+        workspace_api.create_workspace('test2', save_now=True)  # nopep8
900
+        workspace_api.create_workspace('test3', save_now=True)  # nopep8
901
+        transaction.commit()
902
+        self.testapp.authorization = (
903
+            'Basic',
904
+            (
905
+                'admin@admin.admin',
906
+                'admin@admin.admin'
907
+            )
908
+        )
909
+        res = self.testapp.get('/api/v2/workspaces', status=200)
910
+        res = res.json_body
911
+        assert len(res) == 3
912
+        workspace = res[0]
913
+        assert workspace['label'] == 'test'
914
+        assert workspace['slug'] == 'test'
915
+        workspace = res[1]
916
+        assert workspace['label'] == 'test2'
917
+        assert workspace['slug'] == 'test2'
918
+        workspace = res[2]
919
+        assert workspace['label'] == 'test3'
920
+        assert workspace['slug'] == 'test3'
921
+
922
+    def test_api__get_workspaces__err_403__unallowed_user(self):
923
+        """
924
+        Check obtain all workspaces reachables for one user
925
+        with another non-admin user auth.
926
+        """
927
+        dbsession = get_tm_session(self.session_factory, transaction.manager)
928
+        admin = dbsession.query(models.User) \
929
+            .filter(models.User.email == 'admin@admin.admin') \
930
+            .one()
931
+        uapi = UserApi(
932
+            current_user=admin,
933
+            session=dbsession,
934
+            config=self.app_config,
935
+        )
936
+        gapi = GroupApi(
937
+            current_user=admin,
938
+            session=dbsession,
939
+            config=self.app_config,
940
+        )
941
+        groups = [gapi.get_one_with_name('users')]
942
+        user = uapi.create_user('test@test.test', password='test@test.test',
943
+                                do_save=True, do_notify=False,
944
+                                groups=groups)  # nopep8
945
+        transaction.commit()
946
+        self.testapp.authorization = (
947
+            'Basic',
948
+            (
949
+                'test@test.test',
950
+                'test@test.test'
951
+            )
952
+        )
953
+        res = self.testapp.get('/api/v2/workspaces', status=403)
954
+        assert isinstance(res.json, dict)
955
+        assert 'code' in res.json.keys()
956
+        assert 'message' in res.json.keys()
957
+        assert 'details' in res.json.keys()
958
+
959
+    def test_api__get_workspaces__err_401__unregistered_user(self):
960
+        """
961
+        Check obtain all workspaces reachables for one user
962
+        without correct user auth (user unregistered).
963
+        """
964
+        self.testapp.authorization = (
965
+            'Basic',
966
+            (
967
+                'john@doe.doe',
968
+                'lapin'
969
+            )
970
+        )
971
+        res = self.testapp.get('/api/v2/workspaces', status=401)
972
+        assert isinstance(res.json, dict)
973
+        assert 'code' in res.json.keys()
974
+        assert 'message' in res.json.keys()
975
+        assert 'details' in res.json.keys()
976
+
977
+
878 978
 class TestWorkspaceMembersEndpoint(FunctionalTest):
879 979
     """
880 980
     Tests for /api/v2/workspaces/{workspace_id}/members endpoint
@@ -945,6 +1045,143 @@ class TestWorkspaceMembersEndpoint(FunctionalTest):
945 1045
         assert 'message' in res.json.keys()
946 1046
         assert 'details' in res.json.keys()
947 1047
 
1048
+    def test_api__get_workspace_member__ok_200__self(self):
1049
+        """
1050
+        Check obtain workspace members list with a reachable workspace for user
1051
+        """
1052
+        self.testapp.authorization = (
1053
+            'Basic',
1054
+            (
1055
+                'admin@admin.admin',
1056
+                'admin@admin.admin'
1057
+            )
1058
+        )
1059
+        res = self.testapp.get('/api/v2/workspaces/1/members/1', status=200).json_body   # nopep8
1060
+        user_role = res
1061
+        assert user_role['role'] == 'workspace-manager'
1062
+        assert user_role['user_id'] == 1
1063
+        assert user_role['workspace_id'] == 1
1064
+        assert user_role['workspace']['workspace_id'] == 1
1065
+        assert user_role['workspace']['label'] == 'Business'
1066
+        assert user_role['workspace']['slug'] == 'business'
1067
+        assert user_role['user']['public_name'] == 'Global manager'
1068
+        assert user_role['user']['user_id'] == 1
1069
+        assert user_role['is_active'] is True
1070
+        assert user_role['do_notify'] is True
1071
+        # TODO - G.M - 24-05-2018 - [Avatar] Replace
1072
+        # by correct value when avatar feature will be enabled
1073
+        assert user_role['user']['avatar_url'] is None
1074
+
1075
+    def test_api__get_workspace_member__ok_200__other_user(self):
1076
+        """
1077
+        Check obtain workspace members list with a reachable workspace for user
1078
+        """
1079
+        dbsession = get_tm_session(self.session_factory, transaction.manager)
1080
+        admin = dbsession.query(models.User) \
1081
+            .filter(models.User.email == 'admin@admin.admin') \
1082
+            .one()
1083
+        uapi = UserApi(
1084
+            current_user=admin,
1085
+            session=dbsession,
1086
+            config=self.app_config,
1087
+        )
1088
+        gapi = GroupApi(
1089
+            current_user=admin,
1090
+            session=dbsession,
1091
+            config=self.app_config,
1092
+        )
1093
+        groups = [gapi.get_one_with_name('managers')]
1094
+        user = uapi.create_user('test@test.test', password='test@test.test', do_save=True, do_notify=False, groups=groups)  # nopep8
1095
+        workspace_api = WorkspaceApi(
1096
+            current_user=admin,
1097
+            session=dbsession,
1098
+            config=self.app_config,
1099
+        )
1100
+        workspace = workspace_api.create_workspace('test_2', save_now=True)  # nopep8
1101
+        rapi = RoleApi(
1102
+            current_user=admin,
1103
+            session=dbsession,
1104
+            config=self.app_config,
1105
+        )
1106
+        rapi.create_one(user, workspace, UserRoleInWorkspace.READER, False)  # nopep8
1107
+        transaction.commit()
1108
+        user_id = user.user_id
1109
+        workspace_id = workspace.workspace_id
1110
+        admin_id = admin.user_id
1111
+        self.testapp.authorization = (
1112
+            'Basic',
1113
+            (
1114
+                'admin@admin.admin',
1115
+                'admin@admin.admin'
1116
+            )
1117
+        )
1118
+        print(str(user_id) + '##' + str(workspace_id))
1119
+        res = self.testapp.get('/api/v2/workspaces/{}/members/{}'.format(
1120
+            workspace_id,
1121
+            user_id
1122
+        ), status=200).json_body
1123
+        user_role = res
1124
+        assert user_role['role'] == 'reader'
1125
+        assert user_role['user_id'] == user_id
1126
+        assert user_role['workspace_id'] == workspace_id
1127
+        assert user_role['is_active'] is True
1128
+        assert user_role['do_notify'] is False
1129
+
1130
+        self.testapp.authorization = (
1131
+            'Basic',
1132
+            (
1133
+                'test@test.test',
1134
+                'test@test.test'
1135
+            )
1136
+        )
1137
+        res = self.testapp.get('/api/v2/workspaces/{}/members/{}'.format(
1138
+            workspace_id,
1139
+            admin_id
1140
+        ), status=200).json_body
1141
+        user_role = res
1142
+        assert user_role['role'] == 'workspace-manager'
1143
+        assert user_role['user_id'] == admin_id
1144
+        assert user_role['workspace_id'] == workspace_id
1145
+        assert user_role['is_active'] is True
1146
+        assert user_role['do_notify'] is True
1147
+
1148
+
1149
+    def test_api__get_workspace_member__err_400__unallowed_user(self):
1150
+        """
1151
+        Check obtain workspace members info with an unreachable workspace for
1152
+        user
1153
+        """
1154
+        self.testapp.authorization = (
1155
+            'Basic',
1156
+            (
1157
+                'lawrence-not-real-email@fsf.local',
1158
+                'foobarbaz'
1159
+            )
1160
+        )
1161
+        res = self.testapp.get('/api/v2/workspaces/3/members/1', status=400)
1162
+        assert isinstance(res.json, dict)
1163
+        assert 'code' in res.json.keys()
1164
+        assert 'message' in res.json.keys()
1165
+        assert 'details' in res.json.keys()
1166
+
1167
+    def test_api__get_workspace_member__err_401__unregistered_user(self):
1168
+        """
1169
+        Check obtain workspace member info with an unregistered user
1170
+        """
1171
+        self.testapp.authorization = (
1172
+            'Basic',
1173
+            (
1174
+                'john@doe.doe',
1175
+                'lapin'
1176
+            )
1177
+        )
1178
+        res = self.testapp.get('/api/v2/workspaces/1/members/1', status=401)
1179
+        assert isinstance(res.json, dict)
1180
+        assert 'code' in res.json.keys()
1181
+        assert 'message' in res.json.keys()
1182
+        assert 'details' in res.json.keys()
1183
+
1184
+
948 1185
     def test_api__get_workspace_members__err_400__workspace_does_not_exist(self):  # nopep8
949 1186
         """
950 1187
         Check obtain workspace members list with an existing user but
@@ -980,7 +1217,6 @@ class TestWorkspaceMembersEndpoint(FunctionalTest):
980 1217
             'user_id': 2,
981 1218
             'user_email_or_public_name': None,
982 1219
             'role': 'content-manager',
983
-            'do_notify': False,
984 1220
         }
985 1221
         res = self.testapp.post_json(
986 1222
             '/api/v2/workspaces/1/members',
@@ -1023,7 +1259,6 @@ class TestWorkspaceMembersEndpoint(FunctionalTest):
1023 1259
             'user_id': None,
1024 1260
             'user_email_or_public_name': 'lawrence-not-real-email@fsf.local',
1025 1261
             'role': 'content-manager',
1026
-            'do_notify': 'True',
1027 1262
         }
1028 1263
         res = self.testapp.post_json(
1029 1264
             '/api/v2/workspaces/1/members',
@@ -1036,7 +1271,7 @@ class TestWorkspaceMembersEndpoint(FunctionalTest):
1036 1271
         assert user_role_found['workspace_id'] == 1
1037 1272
         assert user_role_found['newly_created'] is False
1038 1273
         assert user_role_found['email_sent'] is False
1039
-        assert user_role_found['do_notify'] is True
1274
+        assert user_role_found['do_notify'] is False
1040 1275
 
1041 1276
         res = self.testapp.get('/api/v2/workspaces/1/members', status=200).json_body   # nopep8
1042 1277
         assert len(res) == 2
@@ -1066,7 +1301,6 @@ class TestWorkspaceMembersEndpoint(FunctionalTest):
1066 1301
             'user_id': None,
1067 1302
             'user_email_or_public_name': 'Lawrence L.',
1068 1303
             'role': 'content-manager',
1069
-            'do_notify': True,
1070 1304
         }
1071 1305
         res = self.testapp.post_json(
1072 1306
             '/api/v2/workspaces/1/members',
@@ -1079,7 +1313,7 @@ class TestWorkspaceMembersEndpoint(FunctionalTest):
1079 1313
         assert user_role_found['workspace_id'] == 1
1080 1314
         assert user_role_found['newly_created'] is False
1081 1315
         assert user_role_found['email_sent'] is False
1082
-        assert user_role_found['do_notify'] is True
1316
+        assert user_role_found['do_notify'] is False
1083 1317
 
1084 1318
         res = self.testapp.get('/api/v2/workspaces/1/members', status=200).json_body   # nopep8
1085 1319
         assert len(res) == 2
@@ -1109,7 +1343,6 @@ class TestWorkspaceMembersEndpoint(FunctionalTest):
1109 1343
             'user_id': None,
1110 1344
             'user_email_or_public_name': None,
1111 1345
             'role': 'content-manager',
1112
-            'do_notify': True,
1113 1346
         }
1114 1347
         res = self.testapp.post_json(
1115 1348
             '/api/v2/workspaces/1/members',
@@ -1134,7 +1367,6 @@ class TestWorkspaceMembersEndpoint(FunctionalTest):
1134 1367
             'user_id': 47,
1135 1368
             'user_email_or_public_name': None,
1136 1369
             'role': 'content-manager',
1137
-            'do_notify': True,
1138 1370
         }
1139 1371
         res = self.testapp.post_json(
1140 1372
             '/api/v2/workspaces/1/members',
@@ -1159,7 +1391,6 @@ class TestWorkspaceMembersEndpoint(FunctionalTest):
1159 1391
             'user_id': None,
1160 1392
             'user_email_or_public_name': 'nothing@nothing.nothing',
1161 1393
             'role': 'content-manager',
1162
-            'do_notify': True,
1163 1394
         }
1164 1395
         res = self.testapp.post_json(
1165 1396
             '/api/v2/workspaces/1/members',
@@ -1173,7 +1404,7 @@ class TestWorkspaceMembersEndpoint(FunctionalTest):
1173 1404
         assert user_role_found['workspace_id'] == 1
1174 1405
         assert user_role_found['newly_created'] is True
1175 1406
         assert user_role_found['email_sent'] is False
1176
-        assert user_role_found['do_notify'] is True
1407
+        assert user_role_found['do_notify'] is False
1177 1408
 
1178 1409
         res = self.testapp.get('/api/v2/workspaces/1/members',
1179 1410
                                status=200).json_body  # nopep8
@@ -1205,10 +1436,10 @@ class TestWorkspaceMembersEndpoint(FunctionalTest):
1205 1436
         assert user_role['role'] == 'workspace-manager'
1206 1437
         assert user_role['user_id'] == 1
1207 1438
         assert user_role['workspace_id'] == 1
1439
+        assert user_role['do_notify'] is True
1208 1440
         # update workspace role
1209 1441
         params = {
1210 1442
             'role': 'content-manager',
1211
-            'do_notify': False,
1212 1443
         }
1213 1444
         res = self.testapp.put_json(
1214 1445
             '/api/v2/workspaces/1/members/1',
@@ -1224,7 +1455,7 @@ class TestWorkspaceMembersEndpoint(FunctionalTest):
1224 1455
         assert len(res) == 1
1225 1456
         user_role = res[0]
1226 1457
         assert user_role['role'] == 'content-manager'
1227
-        assert user_role['do_notify'] is False
1458
+        assert user_role['do_notify'] is True
1228 1459
         assert user_role['user_id'] == 1
1229 1460
         assert user_role['workspace_id'] == 1
1230 1461
 
@@ -1367,7 +1598,6 @@ class TestUserInvitationWithMailActivatedSync(FunctionalTest):
1367 1598
             'user_id': None,
1368 1599
             'user_email_or_public_name': 'bob@bob.bob',
1369 1600
             'role': 'content-manager',
1370
-            'do_notify': True,
1371 1601
         }
1372 1602
         res = self.testapp.post_json(
1373 1603
             '/api/v2/workspaces/1/members',
@@ -1381,7 +1611,7 @@ class TestUserInvitationWithMailActivatedSync(FunctionalTest):
1381 1611
         assert user_role_found['workspace_id'] == 1
1382 1612
         assert user_role_found['newly_created'] is True
1383 1613
         assert user_role_found['email_sent'] is True
1384
-        assert user_role_found['do_notify'] is True
1614
+        assert user_role_found['do_notify'] is False
1385 1615
 
1386 1616
         # check mail received
1387 1617
         response = requests.get('http://127.0.0.1:8025/api/v1/messages')
@@ -1418,7 +1648,6 @@ class TestUserInvitationWithMailActivatedASync(FunctionalTest):
1418 1648
             'user_id': None,
1419 1649
             'user_email_or_public_name': 'bob@bob.bob',
1420 1650
             'role': 'content-manager',
1421
-            'do_notify': True,
1422 1651
         }
1423 1652
         res = self.testapp.post_json(
1424 1653
             '/api/v2/workspaces/1/members',

+ 0 - 6
backend/tracim_backend/views/core_api/schemas.py ファイルの表示

@@ -466,12 +466,6 @@ class RoleUpdateSchema(marshmallow.Schema):
466 466
         example='contributor',
467 467
         validate=OneOf(UserRoleInWorkspace.get_all_role_slug())
468 468
     )
469
-    do_notify = marshmallow.fields.Bool(
470
-        description='has user enabled notification for this workspace',
471
-        example=True,
472
-        default=None,
473
-        allow_none=True,
474
-    )
475 469
 
476 470
     @post_load
477 471
     def make_role(self, data):

+ 63 - 0
backend/tracim_backend/views/core_api/user_controller.py ファイルの表示

@@ -1,4 +1,5 @@
1 1
 from pyramid.config import Configurator
2
+from tracim_backend.lib.core.userworkspace import RoleApi
2 3
 from tracim_backend.lib.utils.utils import password_generator
3 4
 
4 5
 try:  # Python 3.5+
@@ -458,6 +459,60 @@ class UserController(Controller):
458 459
         api.mark_read__workspace(request.current_workspace)
459 460
         return
460 461
 
462
+    @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
463
+    @require_same_user_or_profile(Group.TIM_ADMIN)
464
+    @hapic.input_path(UserWorkspaceIdPathSchema())
465
+    @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT)  # nopep8
466
+    def enable_workspace_notification(self, context, request: TracimRequest, hapic_data=None):  # nopep8
467
+        """
468
+        enable workspace notification
469
+        """
470
+        app_config = request.registry.settings['CFG']
471
+        api = ContentApi(
472
+            current_user=request.candidate_user,  # User
473
+            session=request.dbsession,
474
+            config=app_config,
475
+        )
476
+        wapi = WorkspaceApi(
477
+            current_user=request.candidate_user,  # User
478
+            session=request.dbsession,
479
+            config=app_config,
480
+        )
481
+        workspace = wapi.get_one(hapic_data.path.workspace_id)
482
+        wapi.enable_notifications(request.candidate_user, workspace)
483
+        rapi = RoleApi(
484
+            current_user=request.candidate_user,  # User
485
+            session=request.dbsession,
486
+            config=app_config,
487
+        )
488
+        role = rapi.get_one(request.candidate_user.user_id, workspace.workspace_id)
489
+        wapi.save(workspace)
490
+        return
491
+
492
+    @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
493
+    @require_same_user_or_profile(Group.TIM_ADMIN)
494
+    @hapic.input_path(UserWorkspaceIdPathSchema())
495
+    @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT)  # nopep8
496
+    def disable_workspace_notification(self, context, request: TracimRequest, hapic_data=None):  # nopep8
497
+        """
498
+        disable workspace notification
499
+        """
500
+        app_config = request.registry.settings['CFG']
501
+        api = ContentApi(
502
+            current_user=request.candidate_user,  # User
503
+            session=request.dbsession,
504
+            config=app_config,
505
+        )
506
+        wapi = WorkspaceApi(
507
+            current_user=request.candidate_user,  # User
508
+            session=request.dbsession,
509
+            config=app_config,
510
+        )
511
+        workspace = wapi.get_one(hapic_data.path.workspace_id)
512
+        wapi.disable_notifications(request.candidate_user, workspace)
513
+        wapi.save(workspace)
514
+        return
515
+
461 516
     def bind(self, configurator: Configurator) -> None:
462 517
         """
463 518
         Create all routes and views using pyramid configurator
@@ -532,3 +587,11 @@ class UserController(Controller):
532 587
         # set workspace as read
533 588
         configurator.add_route('read_workspace', '/users/{user_id}/workspaces/{workspace_id}/read', request_method='PUT')  # nopep8
534 589
         configurator.add_view(self.set_workspace_as_read, route_name='read_workspace')  # nopep8
590
+
591
+        # enable workspace notification
592
+        configurator.add_route('enable_workspace_notification', '/users/{user_id}/workspaces/{workspace_id}/notify', request_method='PUT')  # nopep8
593
+        configurator.add_view(self.enable_workspace_notification, route_name='enable_workspace_notification')  # nopep8
594
+
595
+        # enable workspace notification
596
+        configurator.add_route('disable_workspace_notification', '/users/{user_id}/workspaces/{workspace_id}/unnotify', request_method='PUT')  # nopep8
597
+        configurator.add_view(self.disable_workspace_notification, route_name='disable_workspace_notification')  # nopep8

+ 55 - 3
backend/tracim_backend/views/core_api/workspace_controller.py ファイルの表示

@@ -18,6 +18,7 @@ from tracim_backend.lib.core.workspace import WorkspaceApi
18 18
 from tracim_backend.lib.core.content import ContentApi
19 19
 from tracim_backend.lib.core.userworkspace import RoleApi
20 20
 from tracim_backend.lib.utils.authorization import require_workspace_role
21
+from tracim_backend.lib.utils.authorization import require_same_user_or_profile
21 22
 from tracim_backend.lib.utils.authorization import require_profile_or_other_profile_with_workspace_role
22 23
 from tracim_backend.lib.utils.authorization import require_profile
23 24
 from tracim_backend.models import Group
@@ -77,6 +78,26 @@ class WorkspaceController(Controller):
77 78
         return wapi.get_workspace_with_context(request.current_workspace)
78 79
 
79 80
     @hapic.with_api_doc(tags=[SWAGGER_TAG_WORKSPACE_ENDPOINTS])
81
+    @require_profile(Group.TIM_ADMIN)
82
+    @hapic.output_body(WorkspaceSchema(many=True), )
83
+    def workspaces(self, context, request: TracimRequest, hapic_data=None):
84
+        """
85
+        Get list of all workspaces
86
+        """
87
+        app_config = request.registry.settings['CFG']
88
+        wapi = WorkspaceApi(
89
+            current_user=request.current_user,  # User
90
+            session=request.dbsession,
91
+            config=app_config,
92
+        )
93
+
94
+        workspaces = wapi.get_all()
95
+        return [
96
+            wapi.get_workspace_with_context(workspace)
97
+            for workspace in workspaces
98
+        ]
99
+
100
+    @hapic.with_api_doc(tags=[SWAGGER_TAG_WORKSPACE_ENDPOINTS])
80 101
     @hapic.handle_exception(EmptyLabelNotAllowed, HTTPStatus.BAD_REQUEST)
81 102
     @require_workspace_role(UserRoleInWorkspace.WORKSPACE_MANAGER)
82 103
     @hapic.input_path(WorkspaceIdPathSchema())
@@ -194,6 +215,32 @@ class WorkspaceController(Controller):
194 215
         ]
195 216
 
196 217
     @hapic.with_api_doc(tags=[SWAGGER_TAG_WORKSPACE_ENDPOINTS])
218
+    @require_workspace_role(UserRoleInWorkspace.READER)
219
+    @hapic.input_path(WorkspaceAndUserIdPathSchema())
220
+    @hapic.output_body(WorkspaceMemberSchema())
221
+    def workspaces_member_role(
222
+            self,
223
+            context,
224
+            request: TracimRequest,
225
+            hapic_data=None
226
+    ) -> UserRoleWorkspaceInContext:
227
+        """
228
+        Get role of user in workspace
229
+        """
230
+        app_config = request.registry.settings['CFG']
231
+        rapi = RoleApi(
232
+            current_user=request.current_user,
233
+            session=request.dbsession,
234
+            config=app_config,
235
+        )
236
+
237
+        role = rapi.get_one(
238
+            user_id=hapic_data.path.user_id,
239
+            workspace_id=hapic_data.path.workspace_id,
240
+        )
241
+        return rapi.get_user_role_workspace_with_context(role)
242
+
243
+    @hapic.with_api_doc(tags=[SWAGGER_TAG_WORKSPACE_ENDPOINTS])
197 244
     @require_workspace_role(UserRoleInWorkspace.WORKSPACE_MANAGER)
198 245
     @hapic.input_path(WorkspaceAndUserIdPathSchema())
199 246
     @hapic.input_body(RoleUpdateSchema())
@@ -221,8 +268,7 @@ class WorkspaceController(Controller):
221 268
         workspace_role = WorkspaceRoles.get_role_from_slug(hapic_data.body.role)
222 269
         role = rapi.update_role(
223 270
             role,
224
-            role_level=workspace_role.level,
225
-            with_notif=hapic_data.body.do_notify
271
+            role_level=workspace_role.level
226 272
         )
227 273
         return rapi.get_user_role_workspace_with_context(role)
228 274
 
@@ -303,7 +349,7 @@ class WorkspaceController(Controller):
303 349
             user=user,
304 350
             workspace=request.current_workspace,
305 351
             role_level=WorkspaceRoles.get_role_from_slug(hapic_data.body.role).level,  # nopep8
306
-            with_notif=hapic_data.body.do_notify or False,  # nopep8, default value as false
352
+            with_notif=False,
307 353
             flush=True,
308 354
         )
309 355
         return rapi.get_user_role_workspace_with_context(
@@ -639,6 +685,9 @@ class WorkspaceController(Controller):
639 685
         pyramid configurator for this controller
640 686
         """
641 687
 
688
+        # Workspaces
689
+        configurator.add_route('workspaces', '/workspaces', request_method='GET')  # nopep8
690
+        configurator.add_view(self.workspaces, route_name='workspaces')
642 691
         # Workspace
643 692
         configurator.add_route('workspace', '/workspaces/{workspace_id}', request_method='GET')  # nopep8
644 693
         configurator.add_view(self.workspace, route_name='workspace')
@@ -656,6 +705,9 @@ class WorkspaceController(Controller):
656 705
         # Workspace Members (Roles)
657 706
         configurator.add_route('workspace_members', '/workspaces/{workspace_id}/members', request_method='GET')  # nopep8
658 707
         configurator.add_view(self.workspaces_members, route_name='workspace_members')  # nopep8
708
+        # Workspace Members (Role) Individual
709
+        configurator.add_route('workspace_member_role', '/workspaces/{workspace_id}/members/{user_id}', request_method='GET')  # nopep8
710
+        configurator.add_view(self.workspaces_member_role, route_name='workspace_member_role')  # nopep8
659 711
         # Update Workspace Members roles
660 712
         configurator.add_route('update_workspace_member', '/workspaces/{workspace_id}/members/{user_id}', request_method='PUT')  # nopep8
661 713
         configurator.add_view(self.update_workspaces_members_role, route_name='update_workspace_member')  # nopep8