1 /*
2  * Copyright (C) 2013 Emeric Poupon
3  *
4  * This file is part of LMS.
5  *
6  * LMS is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * LMS is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with LMS.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "database/User.hpp"
21 
22 #include "database/Artist.hpp"
23 #include "database/Release.hpp"
24 #include "database/Session.hpp"
25 #include "database/Track.hpp"
26 #include "database/TrackList.hpp"
27 #include "utils/Logger.hpp"
28 #include "StringViewTraits.hpp"
29 
30 namespace Database {
31 
32 
AuthToken(const std::string & value,const Wt::WDateTime & expiry,Wt::Dbo::ptr<User> user)33 AuthToken::AuthToken(const std::string& value, const Wt::WDateTime& expiry, Wt::Dbo::ptr<User> user)
34 : _value {value}
35 , _expiry {expiry}
36 , _user {user}
37 {
38 
39 }
40 
41 AuthToken::pointer
create(Session & session,const std::string & value,const Wt::WDateTime & expiry,Wt::Dbo::ptr<User> user)42 AuthToken::create(Session& session, const std::string& value, const Wt::WDateTime& expiry, Wt::Dbo::ptr<User> user)
43 {
44 	session.checkUniqueLocked();
45 
46 	auto res {session.getDboSession().add(std::make_unique<AuthToken>(value, expiry, user))};
47 
48 	session.getDboSession().flush();
49 
50 	return res;
51 }
52 
53 void
removeExpiredTokens(Session & session,const Wt::WDateTime & now)54 AuthToken::removeExpiredTokens(Session& session, const Wt::WDateTime& now)
55 {
56 	session.checkUniqueLocked();
57 
58 	session.getDboSession().execute
59 		("DELETE FROM auth_token WHERE expiry < ?").bind(now);
60 }
61 
62 AuthToken::pointer
getByValue(Session & session,const std::string & value)63 AuthToken::getByValue(Session& session, const std::string& value)
64 {
65 	session.checkSharedLocked();
66 
67 	return session.getDboSession().find<AuthToken>()
68 		.where("value = ?").bind(value);
69 }
70 
71 static const std::string queuedListName {"__queued_tracks__"};
72 
User(std::string_view loginName)73 User::User(std::string_view loginName)
74 : _loginName {loginName}
75 {
76 }
77 
78 std::vector<User::pointer>
getAll(Session & session)79 User::getAll(Session& session)
80 {
81 	session.checkSharedLocked();
82 
83 	Wt::Dbo::collection<pointer> res = session.getDboSession().find<User>();
84 	return std::vector<pointer>(res.begin(), res.end());
85 }
86 
87 User::pointer
getDemo(Session & session)88 User::getDemo(Session& session)
89 {
90 	session.checkSharedLocked();
91 
92 	pointer res = session.getDboSession().find<User>().where("type = ?").bind(Type::DEMO);
93 	return res;
94 }
95 
96 std::size_t
getCount(Session & session)97 User::getCount(Session& session)
98 {
99 	session.checkSharedLocked();
100 
101 	return session.getDboSession().query<int>("SELECT COUNT(*) FROM user");
102 }
103 
104 User::pointer
create(Session & session,std::string_view loginName)105 User::create(Session& session, std::string_view loginName)
106 {
107 	session.checkUniqueLocked();
108 
109 	User::pointer user {session.getDboSession().add(std::make_unique<User>(loginName))};
110 
111 	TrackList::create(session, queuedListName, TrackList::Type::Internal, false, user);
112 
113 	session.getDboSession().flush();
114 
115 	return user;
116 }
117 
118 User::pointer
getById(Session & session,IdType id)119 User::getById(Session& session, IdType id)
120 {
121 	return session.getDboSession().find<User>().where("id = ?").bind( id );
122 }
123 
124 User::pointer
getByLoginName(Session & session,std::string_view name)125 User::getByLoginName(Session& session, std::string_view name)
126 {
127 	return session.getDboSession().find<User>()
128 		.where("login_name = ?").bind(name);
129 }
130 
131 void
setSubsonicTranscodeBitrate(Bitrate bitrate)132 User::setSubsonicTranscodeBitrate(Bitrate bitrate)
133 {
134 	assert(audioTranscodeAllowedBitrates.find(bitrate) != audioTranscodeAllowedBitrates.cend());
135 	_subsonicTranscodeBitrate = bitrate;
136 }
137 
138 void
clearAuthTokens()139 User::clearAuthTokens()
140 {
141 	_authTokens.clear();
142 }
143 
144 Wt::Dbo::ptr<TrackList>
getQueuedTrackList(Session & session) const145 User::getQueuedTrackList(Session& session) const
146 {
147 	assert(self());
148 	session.checkSharedLocked();
149 
150 	return TrackList::get(session, queuedListName, TrackList::Type::Internal, self());
151 }
152 
153 void
starArtist(Wt::Dbo::ptr<Artist> artist)154 User::starArtist(Wt::Dbo::ptr<Artist> artist)
155 {
156 	if (_starredArtists.count(artist) == 0)
157 		_starredArtists.insert(artist);
158 }
159 
160 void
unstarArtist(Wt::Dbo::ptr<Artist> artist)161 User::unstarArtist(Wt::Dbo::ptr<Artist> artist)
162 {
163 	if (_starredArtists.count(artist) != 0)
164 		_starredArtists.erase(artist);
165 }
166 
167 bool
hasStarredArtist(Wt::Dbo::ptr<Artist> artist) const168 User::hasStarredArtist(Wt::Dbo::ptr<Artist> artist) const
169 {
170 	return _starredArtists.count(artist) != 0;
171 }
172 
173 void
starRelease(Wt::Dbo::ptr<Release> release)174 User::starRelease(Wt::Dbo::ptr<Release> release)
175 {
176 	if (_starredReleases.count(release) == 0)
177 		_starredReleases.insert(release);
178 }
179 
180 void
unstarRelease(Wt::Dbo::ptr<Release> release)181 User::unstarRelease(Wt::Dbo::ptr<Release> release)
182 {
183 	if (_starredReleases.count(release) != 0)
184 		_starredReleases.erase(release);
185 }
186 
187 bool
hasStarredRelease(Wt::Dbo::ptr<Release> release) const188 User::hasStarredRelease(Wt::Dbo::ptr<Release> release) const
189 {
190 	return _starredReleases.count(release) != 0;
191 }
192 
193 void
starTrack(Wt::Dbo::ptr<Track> track)194 User::starTrack(Wt::Dbo::ptr<Track> track)
195 {
196 	if (_starredTracks.count(track) == 0)
197 		_starredTracks.insert(track);
198 }
199 
200 void
unstarTrack(Wt::Dbo::ptr<Track> track)201 User::unstarTrack(Wt::Dbo::ptr<Track> track)
202 {
203 	if (_starredTracks.count(track) != 0)
204 		_starredTracks.erase(track);
205 }
206 
207 bool
hasStarredTrack(Wt::Dbo::ptr<Track> track) const208 User::hasStarredTrack(Wt::Dbo::ptr<Track> track) const
209 {
210 	return _starredTracks.count(track) != 0;
211 }
212 
213 } // namespace Database
214 
215 
216