21
21
22
22
namespace OCA \User_SAML ;
23
23
24
+ use OC \Files \Filesystem ;
25
+ use OC \User \Backend ;
24
26
use OCP \Authentication \IApacheBackend ;
25
27
use OCP \DB \QueryBuilder \IQueryBuilder ;
26
28
use OCP \EventDispatcher \IEventDispatcher ;
27
29
use OCP \Files \NotPermittedException ;
30
+ use OCP \IAvatarManager ;
28
31
use OCP \IConfig ;
29
32
use OCP \IDBConnection ;
30
33
use OCP \IGroupManager ;
@@ -61,6 +64,8 @@ class UserBackend implements IApacheBackend, UserInterface, IUserBackend {
61
64
private $ userData ;
62
65
/** @var IEventDispatcher */
63
66
private $ eventDispatcher ;
67
+ /** @var IAvatarManager */
68
+ private $ avatarManager ;
64
69
65
70
public function __construct (
66
71
IConfig $ config ,
@@ -72,8 +77,9 @@ public function __construct(
72
77
SAMLSettings $ settings ,
73
78
ILogger $ logger ,
74
79
UserData $ userData ,
75
- IEventDispatcher $ eventDispatcher
76
- ) {
80
+ IEventDispatcher $ eventDispatcher ,
81
+ IAvatarManager $ avatarManager
82
+ ) {
77
83
$ this ->config = $ config ;
78
84
$ this ->urlGenerator = $ urlGenerator ;
79
85
$ this ->session = $ session ;
@@ -84,6 +90,25 @@ public function __construct(
84
90
$ this ->logger = $ logger ;
85
91
$ this ->userData = $ userData ;
86
92
$ this ->eventDispatcher = $ eventDispatcher ;
93
+ $ this ->avatarManager = $ avatarManager ;
94
+ }
95
+
96
+ /**
97
+ * checks whether the user is allowed to change his avatar in Nextcloud
98
+ *
99
+ * @param string $uid the Nextcloud user name
100
+ * @return boolean either the user can or cannot
101
+ * @throws \Exception
102
+ */
103
+ public function canChangeAvatar ($ uid ) {
104
+ if (!$ this ->implementsActions (Backend::PROVIDE_AVATAR )) {
105
+ return true ;
106
+ }
107
+ try {
108
+ return empty (trim ($ this ->getAttributeKeys ('saml-attribute-mapping-avatar_mapping ' )[0 ]));
109
+ } catch (\InvalidArgumentException $ e ) {
110
+ return true ;
111
+ }
87
112
}
88
113
89
114
/**
@@ -185,6 +210,7 @@ public function implementsActions($actions) {
185
210
$ availableActions |= \OC \User \Backend::GET_DISPLAYNAME ;
186
211
$ availableActions |= \OC \User \Backend::GET_HOME ;
187
212
$ availableActions |= \OC \User \Backend::COUNT_USERS ;
213
+ $ availableActions |= \OC \User \Backend::PROVIDE_AVATAR ;
188
214
return (bool )($ availableActions & $ actions );
189
215
}
190
216
@@ -648,6 +674,14 @@ public function updateAttributes($uid,
648
674
$ newGroups = null ;
649
675
}
650
676
677
+ try {
678
+ $ newAvatar = $ this ->getAttributeValue ('saml-attribute-mapping-avatar_mapping ' , $ attributes );
679
+ $ this ->logger ->debug ('Avatar attribute content: {avatar} ' , ['app ' => 'user_saml ' , 'avatar ' => $ newAvatar ]);
680
+ } catch (\InvalidArgumentException $ e ) {
681
+ $ this ->logger ->debug ('Failed to fetch avatar attribute: {exception} ' , ['app ' => 'user_saml ' , 'exception ' => $ e ->getMessage ()]);
682
+ $ newAvatar = null ;
683
+ }
684
+
651
685
if ($ user !== null ) {
652
686
$ currentEmail = (string )(method_exists ($ user , 'getSystemEMailAddress ' ) ? $ user ->getSystemEMailAddress () : $ user ->getEMailAddress ());
653
687
if ($ newEmail !== null
@@ -683,7 +717,54 @@ public function updateAttributes($uid,
683
717
$ groupManager ->get ($ group )->removeUser ($ user );
684
718
}
685
719
}
720
+
721
+ if ($ newAvatar !== null ) {
722
+ $ image = new \OCP \Image ();
723
+ $ fileData = file_get_contents ($ newAvatar );
724
+ $ image ->loadFromData ($ fileData );
725
+
726
+ $ checksum = md5 ($ image ->data ());
727
+ if ($ checksum !== $ this ->config ->getUserValue ($ uid , 'user_saml ' , 'lastAvatarChecksum ' )) {
728
+ // use the checksum before modifications
729
+ if ($ this ->setAvatarFromSamlProvider ($ uid , $ image )) {
730
+ // save checksum only after successful setting
731
+ $ this ->config ->setUserValue ($ uid , 'user_saml ' , 'lastAvatarChecksum ' , $ checksum );
732
+ }
733
+ }
734
+ }
735
+ }
736
+ }
737
+
738
+ private function setAvatarFromSamlProvider ($ uid , $ image ) {
739
+ if (!$ image ->valid ()) {
740
+ $ this ->logger ->debug ('avatar image data from LDAP invalid for ' . $ uid );
741
+ return false ;
742
+ }
743
+
744
+
745
+ //make sure it is a square and not bigger than 128x128
746
+ $ size = min ([$ image ->width (), $ image ->height (), 128 ]);
747
+ if (!$ image ->centerCrop ($ size )) {
748
+ $ this ->logger ->debug ('croping image for avatar failed for ' . $ uid );
749
+ return false ;
750
+ }
751
+
752
+ if (!Filesystem::$ loaded ) {
753
+ \OC_Util::setupFS ($ uid );
754
+ }
755
+
756
+ try {
757
+ $ avatar = $ this ->avatarManager ->getAvatar ($ uid );
758
+ $ avatar ->set ($ image );
759
+ return true ;
760
+ } catch (\Exception $ e ) {
761
+ $ this ->logger ->logException ($ e , [
762
+ 'message ' => 'Could not set avatar for ' . $ uid ,
763
+ 'level ' => ILogger::INFO ,
764
+ 'app ' => 'user_saml ' ,
765
+ ]);
686
766
}
767
+ return false ;
687
768
}
688
769
689
770
0 commit comments