1package eu.siacs.conversations.xmpp.pep;
2
3import android.util.Base64;
4
5import java.security.NoSuchAlgorithmException;
6
7import io.ipfs.cid.Cid;
8
9import eu.siacs.conversations.utils.CryptoHelper;
10import eu.siacs.conversations.xml.Element;
11import eu.siacs.conversations.xmpp.Jid;
12import im.conversations.android.xmpp.model.avatar.Metadata;
13
14public class Avatar {
15
16 public enum Origin {
17 PEP,
18 VCARD
19 }
20
21 public String type;
22 public String sha1sum;
23 public String image;
24 public int height;
25 public int width;
26 public long size;
27 public Jid owner;
28 public Origin origin = Origin.PEP; // default to maintain compat
29
30 public byte[] getImageAsBytes() {
31 return Base64.decode(image, Base64.DEFAULT);
32 }
33
34 public String getFilename() {
35 return sha1sum;
36 }
37
38 public static Avatar parseMetadata(final String primaryId, final Metadata metadata) {
39 if (primaryId == null || metadata == null) {
40 return null;
41 }
42 for (Element child : metadata.getChildren()) {
43 if (child.getName().equals("info") && primaryId.equals(child.getAttribute("id"))) {
44 Avatar avatar = new Avatar();
45 String height = child.getAttribute("height");
46 String width = child.getAttribute("width");
47 String size = child.getAttribute("bytes");
48 try {
49 if (height != null) {
50 avatar.height = Integer.parseInt(height);
51 }
52 if (width != null) {
53 avatar.width = Integer.parseInt(width);
54 }
55 if (size != null) {
56 avatar.size = Long.parseLong(size);
57 }
58 } catch (NumberFormatException e) {
59 return null;
60 }
61 avatar.type = child.getAttribute("type");
62 String hash = child.getAttribute("id");
63 if (!isValidSHA1(hash)) {
64 return null;
65 }
66 avatar.sha1sum = hash;
67 avatar.origin = Origin.PEP;
68 return avatar;
69 }
70 }
71 return null;
72 }
73
74 @Override
75 public boolean equals(Object object) {
76 if (object != null && object instanceof Avatar other) {
77 return other.getFilename().equals(this.getFilename());
78 } else {
79 return false;
80 }
81 }
82
83 public Cid cid() {
84 if (sha1sum == null) return null;
85
86 try {
87 return CryptoHelper.cid(CryptoHelper.hexToBytes(sha1sum), "sha-1");
88 } catch (final NoSuchAlgorithmException e) {
89 return null;
90 }
91 }
92
93 public static Avatar parsePresence(Element x) {
94 String hash = x == null ? null : x.findChildContent("photo");
95 if (hash == null) {
96 return null;
97 }
98 if (!isValidSHA1(hash)) {
99 return null;
100 }
101 Avatar avatar = new Avatar();
102 avatar.sha1sum = hash;
103 avatar.origin = Origin.VCARD;
104 return avatar;
105 }
106
107 private static boolean isValidSHA1(String s) {
108 return s != null && s.matches("[a-fA-F0-9]{40}");
109 }
110}