PageRenderTime 79ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/api/account/delete.go

http://github.com/pomack/dsocial.go
Go | 423 lines | 258 code | 57 blank | 108 comment | 84 complexity | f8b364b238ad8774a2b9514f0896d960 MD5 | raw file
  1. package account
  2. import (
  3. "github.com/pomack/dsocial.go/api/apiutil"
  4. acct "github.com/pomack/dsocial.go/backend/accounts"
  5. auth "github.com/pomack/dsocial.go/backend/authentication"
  6. dm "github.com/pomack/dsocial.go/models/dsocial"
  7. "github.com/pomack/jsonhelper.go/jsonhelper"
  8. wm "github.com/pomack/webmachine.go/webmachine"
  9. "io"
  10. "net/http"
  11. "strings"
  12. "time"
  13. )
  14. type DeleteAccountRequestHandler struct {
  15. wm.DefaultRequestHandler
  16. ds acct.DataStore
  17. authDS auth.DataStore
  18. }
  19. type DeleteAccountContext interface {
  20. Type() string
  21. SetType(theType string)
  22. User() *dm.User
  23. SetUser(user *dm.User)
  24. Consumer() *dm.Consumer
  25. SetConsumer(consumer *dm.Consumer)
  26. ExternalUser() *dm.ExternalUser
  27. SetExternalUser(externalUser *dm.ExternalUser)
  28. LastModified() time.Time
  29. ETag() string
  30. ToObject() interface{}
  31. RequestingUser() *dm.User
  32. SetRequestingUser(user *dm.User)
  33. RequestingConsumer() *dm.Consumer
  34. SetRequestingConsumer(consumer *dm.Consumer)
  35. MarkAsDeleted()
  36. Deleted() bool
  37. }
  38. type deleteAccountContext struct {
  39. theType string
  40. user *dm.User
  41. consumer *dm.Consumer
  42. externalUser *dm.ExternalUser
  43. requestingUser *dm.User
  44. requestingConsumer *dm.Consumer
  45. wasDeleted bool
  46. }
  47. func NewDeleteAccountContext() DeleteAccountContext {
  48. return new(deleteAccountContext)
  49. }
  50. func (p *deleteAccountContext) Type() string {
  51. return p.theType
  52. }
  53. func (p *deleteAccountContext) SetType(theType string) {
  54. p.theType = theType
  55. }
  56. func (p *deleteAccountContext) User() *dm.User {
  57. return p.user
  58. }
  59. func (p *deleteAccountContext) SetUser(user *dm.User) {
  60. p.user = user
  61. }
  62. func (p *deleteAccountContext) Consumer() *dm.Consumer {
  63. return p.consumer
  64. }
  65. func (p *deleteAccountContext) SetConsumer(consumer *dm.Consumer) {
  66. p.consumer = consumer
  67. }
  68. func (p *deleteAccountContext) ExternalUser() *dm.ExternalUser {
  69. return p.externalUser
  70. }
  71. func (p *deleteAccountContext) SetExternalUser(externalUser *dm.ExternalUser) {
  72. p.externalUser = externalUser
  73. }
  74. func (p *deleteAccountContext) LastModified() time.Time {
  75. var lastModified time.Time
  76. if p.user != nil && p.user.ModifiedAt != 0 {
  77. lastModified = time.Unix(p.user.ModifiedAt, 0).UTC()
  78. } else if p.consumer != nil && p.consumer.ModifiedAt != 0 {
  79. lastModified = time.Unix(p.consumer.ModifiedAt, 0).UTC()
  80. } else if p.externalUser != nil && p.externalUser.ModifiedAt != 0 {
  81. lastModified = time.Unix(p.externalUser.ModifiedAt, 0).UTC()
  82. }
  83. return lastModified
  84. }
  85. func (p *deleteAccountContext) ToObject() interface{} {
  86. var user interface{}
  87. if p.user != nil {
  88. user = p.user
  89. } else if p.consumer != nil {
  90. user = p.consumer
  91. } else if p.externalUser != nil {
  92. user = p.externalUser
  93. }
  94. return user
  95. }
  96. func (p *deleteAccountContext) ETag() string {
  97. var etag string
  98. if p.user != nil {
  99. etag = p.user.Etag
  100. } else if p.consumer != nil {
  101. etag = p.consumer.Etag
  102. } else if p.externalUser != nil {
  103. etag = p.externalUser.Etag
  104. }
  105. return etag
  106. }
  107. func (p *deleteAccountContext) RequestingUser() *dm.User {
  108. return p.requestingUser
  109. }
  110. func (p *deleteAccountContext) SetRequestingUser(user *dm.User) {
  111. p.requestingUser = user
  112. }
  113. func (p *deleteAccountContext) RequestingConsumer() *dm.Consumer {
  114. return p.requestingConsumer
  115. }
  116. func (p *deleteAccountContext) SetRequestingConsumer(consumer *dm.Consumer) {
  117. p.requestingConsumer = consumer
  118. }
  119. func (p *deleteAccountContext) MarkAsDeleted() {
  120. p.wasDeleted = true
  121. }
  122. func (p *deleteAccountContext) Deleted() bool {
  123. return p.wasDeleted
  124. }
  125. func NewDeleteAccountRequestHandler(ds acct.DataStore, authDS auth.DataStore) *DeleteAccountRequestHandler {
  126. return &DeleteAccountRequestHandler{ds: ds, authDS: authDS}
  127. }
  128. func (p *DeleteAccountRequestHandler) GenerateContext(req wm.Request, cxt wm.Context) DeleteAccountContext {
  129. if dac, ok := cxt.(DeleteAccountContext); ok {
  130. return dac
  131. }
  132. return NewDeleteAccountContext()
  133. }
  134. func (p *DeleteAccountRequestHandler) HandlerFor(req wm.Request, writer wm.ResponseWriter) wm.RequestHandler {
  135. // /api/v1/json/account/(user|consumer|external_user)/delete/(id)
  136. path := req.URLParts()
  137. pathLen := len(path)
  138. if path[pathLen-1] == "" {
  139. // ignore trailing slash
  140. pathLen = pathLen - 1
  141. }
  142. if pathLen >= 8 {
  143. if path[0] == "" && path[1] == "api" && path[2] == "v1" && path[3] == "json" && path[4] == "account" && path[6] == "delete" {
  144. switch path[5] {
  145. case "user", "consumer", "external_user":
  146. return p
  147. }
  148. }
  149. }
  150. return nil
  151. }
  152. func (p *DeleteAccountRequestHandler) StartRequest(req wm.Request, cxt wm.Context) (wm.Request, wm.Context) {
  153. dac := p.GenerateContext(req, cxt)
  154. path := req.URLParts()
  155. pathLen := len(path)
  156. if pathLen >= 8 {
  157. dac.SetType(path[5])
  158. var id string
  159. if path[pathLen-1] == "" {
  160. id = strings.Join(path[7:pathLen-1], "/")
  161. } else {
  162. id = strings.Join(path[7:], "/")
  163. }
  164. switch dac.Type() {
  165. case "user":
  166. user, _ := p.ds.RetrieveUserAccountById(id)
  167. dac.SetUser(user)
  168. case "consumer":
  169. consumer, _ := p.ds.RetrieveConsumerAccountById(id)
  170. dac.SetConsumer(consumer)
  171. case "external_user":
  172. externalUser, _ := p.ds.RetrieveExternalUserAccountById(id)
  173. dac.SetExternalUser(externalUser)
  174. }
  175. }
  176. return req, dac
  177. }
  178. /*
  179. func (p *CreateAccountRequestHandler) ServiceAvailable(req wm.Request, cxt wm.Context) (bool, wm.Request, wm.Context, int, os.Error) {
  180. return true, req, cxt, 0, nil
  181. }
  182. */
  183. func (p *DeleteAccountRequestHandler) ResourceExists(req wm.Request, cxt wm.Context) (bool, wm.Request, wm.Context, int, error) {
  184. dac := cxt.(DeleteAccountContext)
  185. return dac.ToObject() != nil, req, cxt, 0, nil
  186. }
  187. func (p *DeleteAccountRequestHandler) AllowedMethods(req wm.Request, cxt wm.Context) ([]string, wm.Request, wm.Context, int, error) {
  188. return []string{wm.POST, wm.DELETE}, req, cxt, 0, nil
  189. }
  190. func (p *DeleteAccountRequestHandler) IsAuthorized(req wm.Request, cxt wm.Context) (bool, string, wm.Request, wm.Context, int, error) {
  191. dac := cxt.(DeleteAccountContext)
  192. hasSignature, userId, consumerId, err := apiutil.CheckSignature(p.authDS, req.UnderlyingRequest())
  193. if !hasSignature || err != nil {
  194. return hasSignature, "dsocial", req, cxt, http.StatusUnauthorized, err
  195. }
  196. if userId != "" {
  197. user, _ := p.ds.RetrieveUserAccountById(userId)
  198. dac.SetRequestingUser(user)
  199. }
  200. if consumerId != "" {
  201. consumer, _ := p.ds.RetrieveConsumerAccountById(consumerId)
  202. dac.SetRequestingConsumer(consumer)
  203. }
  204. return true, "", req, cxt, 0, nil
  205. }
  206. func (p *DeleteAccountRequestHandler) Forbidden(req wm.Request, cxt wm.Context) (bool, wm.Request, wm.Context, int, error) {
  207. dac := cxt.(DeleteAccountContext)
  208. if dac.RequestingUser() != nil && dac.RequestingUser().Accessible() && (dac.RequestingUser().Role == dm.ROLE_ADMIN || (dac.User() != nil && dac.RequestingUser().Id == dac.User().Id)) {
  209. return false, req, cxt, 0, nil
  210. }
  211. // Cannot find user or consumer with specified id
  212. return true, req, cxt, 0, nil
  213. }
  214. /*
  215. func (p *DeleteAccountRequestHandler) AllowMissingPost(req wm.Request, cxt wm.Context) (bool, wm.Request, wm.Context, int, os.Error) {
  216. return false, req, cxt, 0, nil
  217. }
  218. */
  219. /*
  220. func (p *DeleteAccountRequestHandler) MalformedRequest(req wm.Request, cxt wm.Context) (bool, wm.Request, wm.Context, int, os.Error) {
  221. return false, req, cxt, 0, nil
  222. }
  223. */
  224. /*
  225. func (p *DeleteAccountRequestHandler) URITooLong(req wm.Request, cxt wm.Context) (bool, wm.Request, wm.Context, int, os.Error) {
  226. return false, req, cxt, 0, nil
  227. }
  228. */
  229. func (p *DeleteAccountRequestHandler) DeleteResource(req wm.Request, cxt wm.Context) (bool, wm.Request, wm.Context, int, error) {
  230. dac := cxt.(DeleteAccountContext)
  231. var err error
  232. if dac.User() != nil {
  233. _, err = p.ds.DeleteUserAccount(dac.User())
  234. } else if dac.Consumer() != nil {
  235. _, err = p.ds.DeleteConsumerAccount(dac.Consumer())
  236. } else if dac.ExternalUser() != nil {
  237. _, err = p.ds.DeleteExternalUserAccount(dac.ExternalUser())
  238. }
  239. dac.MarkAsDeleted()
  240. if err != nil {
  241. return false, req, cxt, http.StatusInternalServerError, err
  242. }
  243. return true, req, cxt, 0, nil
  244. }
  245. /*
  246. func (p *DeleteAccountRequestHandler) DeleteCompleted(req wm.Request, cxt wm.Context) (bool, wm.Request, wm.Context, int, os.Error) {
  247. return true, req, cxt, 0, nil
  248. }
  249. */
  250. /*
  251. func (p *DeleteAccountRequestHandler) PostIsCreate(req wm.Request, cxt wm.Context) (bool, wm.Request, wm.Context, int, os.Error) {
  252. return false, req, cxt, 0, nil
  253. }
  254. */
  255. /*
  256. func (p *DeleteAccountRequestHandler) CreatePath(req wm.Request, cxt wm.Context) (string, wm.Request, wm.Context, int, os.Error) {
  257. return "", req, cxt, 0, nil
  258. }
  259. */
  260. func (p *DeleteAccountRequestHandler) ProcessPost(req wm.Request, cxt wm.Context) (wm.Request, wm.Context, int, http.Header, io.WriterTo, error) {
  261. _, req, cxt, httpCode, httpError := p.DeleteResource(req, cxt)
  262. return req, cxt, httpCode, nil, nil, httpError
  263. }
  264. func (p *DeleteAccountRequestHandler) ContentTypesProvided(req wm.Request, cxt wm.Context) ([]wm.MediaTypeHandler, wm.Request, wm.Context, int, error) {
  265. cac := cxt.(DeleteAccountContext)
  266. obj := cac.ToObject()
  267. lastModified := cac.LastModified()
  268. etag := cac.ETag()
  269. var jsonObj jsonhelper.JSONObject
  270. if obj != nil {
  271. theobj, _ := jsonhelper.MarshalWithOptions(obj, dm.UTC_DATETIME_FORMAT)
  272. jsonObj, _ = theobj.(jsonhelper.JSONObject)
  273. }
  274. return []wm.MediaTypeHandler{apiutil.NewJSONMediaTypeHandler(jsonObj, lastModified, etag)}, req, cac, 0, nil
  275. }
  276. func (p *DeleteAccountRequestHandler) ContentTypesAccepted(req wm.Request, cxt wm.Context) ([]wm.MediaTypeInputHandler, wm.Request, wm.Context, int, error) {
  277. arr := []wm.MediaTypeInputHandler{apiutil.NewJSONMediaTypeInputHandler("", "", p, req.Body())}
  278. return arr, req, cxt, 0, nil
  279. }
  280. /*
  281. func (p *DeleteAccountRequestHandler) IsLanguageAvailable(languages []string, req wm.Request, cxt wm.Context) (bool, wm.Request, wm.Context, int, os.Error) {
  282. }
  283. */
  284. /*
  285. func (p *DeleteAccountRequestHandler) CharsetsProvided(charsets []string, req wm.Request, cxt wm.Context) ([]CharsetHandler, wm.Request, wm.Context, int, os.Error) {
  286. }
  287. */
  288. /*
  289. func (p *DeleteAccountRequestHandler) EncodingsProvided(encodings []string, req wm.Request, cxt wm.Context) ([]EncodingHandler, wm.Request, wm.Context, int, os.Error) {
  290. }
  291. */
  292. /*
  293. func (p *DeleteAccountRequestHandler) Variances(req wm.Request, cxt wm.Context) ([]string, wm.Request, wm.Context, int, os.Error) {
  294. }
  295. */
  296. /*
  297. func (p *DeleteAccountRequestHandler) IsConflict(req wm.Request, cxt wm.Context) (bool, wm.Request, wm.Context, int, os.Error) {
  298. return false, req, cxt, 0, nil
  299. }
  300. */
  301. /*
  302. func (p *DeleteAccountRequestHandler) MultipleChoices(req wm.Request, cxt wm.Context) (bool, http.Header, wm.Request, wm.Context, int, os.Error) {
  303. return false, nil, req, cxt, 0, nil
  304. }
  305. */
  306. /*
  307. func (p *DeleteAccountRequestHandler) PreviouslyExisted(req wm.Request, cxt wm.Context) (bool, wm.Request, wm.Context, int, os.Error) {
  308. }
  309. */
  310. /*
  311. func (p *DeleteAccountRequestHandler) MovedPermanently(req wm.Request, cxt wm.Context) (string, wm.Request, wm.Context, int, os.Error) {
  312. }
  313. */
  314. /*
  315. func (p *DeleteAccountRequestHandler) MovedTemporarily(req wm.Request, cxt wm.Context) (string, wm.Request, wm.Context, int, os.Error) {
  316. }
  317. */
  318. /*
  319. func (p *DeleteAccountRequestHandler) LastModified(req wm.Request, cxt wm.Context) (*time.Time, wm.Request, wm.Context, int, os.Error) {
  320. return nil, req, cxt, 0, nil
  321. }
  322. */
  323. /*
  324. func (p *DeleteAccountRequestHandler) Expires(req wm.Request, cxt wm.Context) (*time.Time, wm.Request, wm.Context, int, os.Error) {
  325. }
  326. */
  327. /*
  328. func (p *DeleteAccountRequestHandler) GenerateETag(req wm.Request, cxt wm.Context) (string, wm.Request, wm.Context, int, os.Error) {
  329. }
  330. */
  331. /*
  332. func (p *DeleteAccountRequestHandler) FinishRequest(req wm.Request, cxt wm.Context) (bool, wm.Request, wm.Context, int, os.Error) {
  333. return true, req, cxt, 0, nil
  334. }
  335. */
  336. /*
  337. func (p *DeleteAccountRequestHandler) ResponseIsRedirect(req wm.Request, cxt wm.Context) (bool, wm.Request, wm.Context, int, os.Error) {
  338. return false, req, cxt, 0, nil
  339. }
  340. */
  341. func (p *DeleteAccountRequestHandler) HasRespBody(req wm.Request, cxt wm.Context) bool {
  342. return true
  343. }
  344. func (p *DeleteAccountRequestHandler) HandleJSONObjectInputHandler(req wm.Request, cxt wm.Context, inputObj jsonhelper.JSONObject) (int, http.Header, io.WriterTo) {
  345. dac := cxt.(DeleteAccountContext)
  346. obj := dac.ToObject()
  347. var err error
  348. if !dac.Deleted() {
  349. _, req, cxt, _, err = p.DeleteResource(req, cxt)
  350. }
  351. if err != nil {
  352. return apiutil.OutputErrorMessage(err.Error(), nil, http.StatusInternalServerError, nil)
  353. }
  354. theobj, _ := jsonhelper.MarshalWithOptions(obj, dm.UTC_DATETIME_FORMAT)
  355. jsonObj, _ := theobj.(jsonhelper.JSONObject)
  356. return apiutil.OutputJSONObject(jsonObj, time.Time{}, "", 0, nil)
  357. }